Refactored common used operations into TLS crypto helper
[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 * All handshake data concatentated
54 */
55 chunk_t handshake;
56
57 /**
58 * Connection state TLS PRF
59 */
60 tls_prf_t *prf;
61
62 /**
63 * Signer instance for inbound traffic
64 */
65 signer_t *signer_in;
66
67 /**
68 * Signer instance for outbound traffic
69 */
70 signer_t *signer_out;
71
72 /**
73 * Crypter instance for inbound traffic
74 */
75 crypter_t *crypter_in;
76
77 /**
78 * Crypter instance for outbound traffic
79 */
80 crypter_t *crypter_out;
81
82 /**
83 * IV for input decryption, if < TLSv1.2
84 */
85 chunk_t iv_in;
86
87 /**
88 * IV for output decryption, if < TLSv1.2
89 */
90 chunk_t iv_out;
91
92 /**
93 * EAP-TLS MSK
94 */
95 chunk_t msk;
96 };
97
98 typedef struct {
99 tls_cipher_suite_t suite;
100 hash_algorithm_t hash;
101 pseudo_random_function_t prf;
102 integrity_algorithm_t mac;
103 encryption_algorithm_t encr;
104 size_t encr_size;
105 } suite_algs_t;
106
107 /**
108 * Mapping suites to a set of algorithms
109 */
110 static suite_algs_t suite_algs[] = {
111 { TLS_RSA_WITH_NULL_MD5,
112 HASH_MD5,
113 PRF_HMAC_MD5,
114 AUTH_HMAC_MD5_128,
115 ENCR_NULL, 0
116 },
117 { TLS_RSA_WITH_NULL_SHA,
118 HASH_SHA1,
119 PRF_HMAC_SHA1,
120 AUTH_HMAC_SHA1_160,
121 ENCR_NULL, 0
122 },
123 { TLS_RSA_WITH_NULL_SHA256,
124 HASH_SHA256,
125 PRF_HMAC_SHA2_256,
126 AUTH_HMAC_SHA2_256_256,
127 ENCR_NULL, 0
128 },
129 { TLS_RSA_WITH_AES_128_CBC_SHA,
130 HASH_SHA1,
131 PRF_HMAC_SHA1,
132 AUTH_HMAC_SHA1_160,
133 ENCR_AES_CBC, 16
134 },
135 { TLS_RSA_WITH_AES_256_CBC_SHA,
136 HASH_SHA1,
137 PRF_HMAC_SHA1,
138 AUTH_HMAC_SHA1_160,
139 ENCR_AES_CBC, 32
140 },
141 { TLS_RSA_WITH_3DES_EDE_CBC_SHA,
142 HASH_SHA1,
143 PRF_HMAC_SHA1,
144 AUTH_HMAC_SHA1_160,
145 ENCR_3DES, 0
146 },
147 { TLS_RSA_WITH_AES_128_CBC_SHA256,
148 HASH_SHA256,
149 PRF_HMAC_SHA2_256,
150 AUTH_HMAC_SHA2_256_256,
151 ENCR_AES_CBC, 16
152 },
153 };
154
155 /**
156 * Look up algoritms by a suite
157 */
158 static suite_algs_t *find_suite(tls_cipher_suite_t suite)
159 {
160 int i;
161
162 for (i = 0; i < countof(suite_algs); i++)
163 {
164 if (suite_algs[i].suite == suite)
165 {
166 return &suite_algs[i];
167 }
168 }
169 return NULL;
170 }
171
172 /**
173 * Initialize the cipher suite list
174 */
175 static void build_cipher_suite_list(private_tls_crypto_t *this)
176 {
177 encryption_algorithm_t encr;
178 integrity_algorithm_t mac;
179 enumerator_t *encrs, *macs;
180 tls_cipher_suite_t supported[64], unique[64];
181 int count = 0, i, j;
182
183 /* we assume that we support RSA, but no DHE yet */
184 macs = lib->crypto->create_signer_enumerator(lib->crypto);
185 while (macs->enumerate(macs, &mac))
186 {
187 switch (mac)
188 {
189 case AUTH_HMAC_SHA1_160:
190 supported[count++] = TLS_RSA_WITH_NULL_SHA;
191 break;
192 case AUTH_HMAC_SHA2_256_256:
193 supported[count++] = TLS_RSA_WITH_NULL_SHA256;
194 break;
195 case AUTH_HMAC_MD5_128:
196 supported[count++] = TLS_RSA_WITH_NULL_MD5;
197 break;
198 default:
199 break;
200 }
201 encrs = lib->crypto->create_crypter_enumerator(lib->crypto);
202 while (encrs->enumerate(encrs, &encr))
203 {
204 switch (encr)
205 {
206 case ENCR_AES_CBC:
207 switch (mac)
208 {
209 case AUTH_HMAC_SHA1_160:
210 supported[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
211 supported[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
212 break;
213 case AUTH_HMAC_SHA2_256_256:
214 supported[count++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
215 supported[count++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
216 break;
217 default:
218 break;
219 }
220 break;
221 case ENCR_3DES:
222 switch (mac)
223 {
224 case AUTH_HMAC_SHA1_160:
225 supported[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
226 break;
227 default:
228 break;
229 }
230 break;
231 default:
232 break;
233 }
234 }
235 encrs->destroy(encrs);
236 }
237 macs->destroy(macs);
238
239 /* remove duplicates */
240 this->suite_count = 0;
241 for (i = 0; i < count; i++)
242 {
243 bool match = FALSE;
244
245 for (j = 0; j < this->suite_count; j++)
246 {
247 if (supported[i] == unique[j])
248 {
249 match = TRUE;
250 break;
251 }
252 }
253 if (!match)
254 {
255 unique[this->suite_count++] = supported[i];
256 }
257 }
258 free(this->suites);
259 this->suites = malloc(sizeof(tls_cipher_suite_t) * this->suite_count);
260 memcpy(this->suites, unique, sizeof(tls_cipher_suite_t) * this->suite_count);
261 }
262
263 METHOD(tls_crypto_t, get_cipher_suites, int,
264 private_tls_crypto_t *this, tls_cipher_suite_t **suites)
265 {
266 *suites = this->suites;
267 return this->suite_count;
268 }
269
270 /**
271 * Create crypto primitives
272 */
273 static bool create_ciphers(private_tls_crypto_t *this, tls_cipher_suite_t suite)
274 {
275 suite_algs_t *algs;
276
277 algs = find_suite(suite);
278 if (!algs)
279 {
280 DBG1(DBG_IKE, "selected TLS suite not supported");
281 return FALSE;
282 }
283
284 DESTROY_IF(this->prf);
285 if (this->tls->get_version(this->tls) < TLS_1_2)
286 {
287 this->prf = tls_prf_create_10();
288 }
289 else
290 {
291 this->prf = tls_prf_create_12(algs->prf);
292 }
293 if (!this->prf)
294 {
295 DBG1(DBG_IKE, "selected TLS PRF not supported");
296 return FALSE;
297 }
298
299 DESTROY_IF(this->signer_in);
300 DESTROY_IF(this->signer_out);
301 this->signer_in = lib->crypto->create_signer(lib->crypto, algs->mac);
302 this->signer_out = lib->crypto->create_signer(lib->crypto, algs->mac);
303 if (!this->signer_in || !this->signer_out)
304 {
305 DBG1(DBG_IKE, "selected TLS MAC %N not supported",
306 integrity_algorithm_names, algs->mac);
307 return FALSE;
308 }
309
310 DESTROY_IF(this->crypter_in);
311 DESTROY_IF(this->crypter_out);
312 if (algs->encr == ENCR_NULL)
313 {
314 this->crypter_in = this->crypter_out = NULL;
315 }
316 else
317 {
318 this->crypter_in = lib->crypto->create_crypter(lib->crypto,
319 algs->encr, algs->encr_size);
320 this->crypter_out = lib->crypto->create_crypter(lib->crypto,
321 algs->encr, algs->encr_size);
322 if (!this->crypter_in || !this->crypter_out)
323 {
324 DBG1(DBG_IKE, "selected TLS crypter %N not supported",
325 encryption_algorithm_names, algs->encr);
326 return FALSE;
327 }
328 }
329 return TRUE;
330 }
331
332 METHOD(tls_crypto_t, select_cipher_suite, tls_cipher_suite_t,
333 private_tls_crypto_t *this, tls_cipher_suite_t *suites, int count)
334 {
335 int i, j;
336
337 for (i = 0; i < this->suite_count; i++)
338 {
339 for (j = 0; j < count; j++)
340 {
341 if (this->suites[i] == suites[j])
342 {
343 if (create_ciphers(this, this->suites[i]))
344 {
345 this->suite = this->suites[i];
346 return this->suite;
347 }
348 }
349 }
350 }
351 return 0;
352 }
353
354 METHOD(tls_crypto_t, append_handshake, void,
355 private_tls_crypto_t *this, tls_handshake_type_t type, chunk_t data)
356 {
357 u_int32_t header;
358
359 /* reconstruct handshake header */
360 header = htonl(data.len | (type << 24));
361 this->handshake = chunk_cat("mcc", this->handshake,
362 chunk_from_thing(header), data);
363 }
364
365 /**
366 * Create a hash of the stored handshake data
367 */
368 static bool hash_handshake(private_tls_crypto_t *this, chunk_t *hash)
369 {
370 if (this->tls->get_version(this->tls) >= TLS_1_2)
371 {
372 hasher_t *hasher;
373 suite_algs_t *alg;
374
375 alg = find_suite(this->suite);
376 if (!alg)
377 {
378 return FALSE;
379 }
380 hasher = lib->crypto->create_hasher(lib->crypto, alg->hash);
381 if (!hasher)
382 {
383 DBG1(DBG_IKE, "%N not supported", hash_algorithm_names, alg->hash);
384 return FALSE;
385 }
386 hasher->allocate_hash(hasher, this->handshake, hash);
387 hasher->destroy(hasher);
388 }
389 else
390 {
391 hasher_t *md5, *sha1;
392 char buf[HASH_SIZE_MD5 + HASH_SIZE_SHA1];
393
394 md5 = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
395 if (!md5)
396 {
397 DBG1(DBG_IKE, "%N not supported", hash_algorithm_names, HASH_MD5);
398 return FALSE;
399 }
400 md5->get_hash(md5, this->handshake, buf);
401 md5->destroy(md5);
402 sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
403 if (!sha1)
404 {
405 DBG1(DBG_IKE, "%N not supported", hash_algorithm_names, HASH_SHA1);
406 return FALSE;
407 }
408 sha1->get_hash(sha1, this->handshake, buf + HASH_SIZE_MD5);
409 sha1->destroy(sha1);
410
411 *hash = chunk_clone(chunk_from_thing(buf));
412 }
413 return TRUE;
414 }
415
416 METHOD(tls_crypto_t, sign_handshake, bool,
417 private_tls_crypto_t *this, private_key_t *key, chunk_t *sig)
418 {
419 if (this->tls->get_version(this->tls) >= TLS_1_2)
420 {
421 u_int16_t length;
422 u_int8_t hash_alg;
423 u_int8_t sig_alg;
424
425 if (!key->sign(key, SIGN_RSA_EMSA_PKCS1_SHA1, this->handshake, sig))
426 {
427 return FALSE;
428 }
429 /* TODO: signature scheme to hashsign algorithm mapping */
430 hash_alg = 2; /* sha1 */
431 sig_alg = 1; /* RSA */
432 length = htons(sig->len);
433 *sig = chunk_cat("cccm", chunk_from_thing(hash_alg),
434 chunk_from_thing(sig_alg), chunk_from_thing(length), *sig);
435 }
436 else
437 {
438 u_int16_t length;
439 chunk_t hash;
440
441 if (!hash_handshake(this, &hash))
442 {
443 return FALSE;
444 }
445 if (!key->sign(key, SIGN_RSA_EMSA_PKCS1_NULL, hash, sig))
446 {
447 free(hash.ptr);
448 return FALSE;
449 }
450 free(hash.ptr);
451 length = htons(sig->len);
452 *sig = chunk_cat("cm", chunk_from_thing(length), *sig);
453 }
454 return TRUE;
455 }
456
457 METHOD(tls_crypto_t, calculate_finished, bool,
458 private_tls_crypto_t *this, char *label, char out[12])
459 {
460 chunk_t seed;
461
462 if (!this->prf)
463 {
464 return FALSE;
465 }
466 if (!hash_handshake(this, &seed))
467 {
468 return FALSE;
469 }
470 this->prf->get_bytes(this->prf, label, seed, 12, out);
471 free(seed.ptr);
472 return TRUE;
473 }
474
475 METHOD(tls_crypto_t, derive_secrets, void,
476 private_tls_crypto_t *this, chunk_t premaster,
477 chunk_t client_random, chunk_t server_random)
478 {
479 char master[48];
480 chunk_t seed, block, client_write, server_write;
481 int mks, eks = 0, ivs = 0;
482
483 /* derive master secret */
484 seed = chunk_cata("cc", client_random, server_random);
485 this->prf->set_key(this->prf, premaster);
486 this->prf->get_bytes(this->prf, "master secret", seed,
487 sizeof(master), master);
488
489 this->prf->set_key(this->prf, chunk_from_thing(master));
490 memset(master, 0, sizeof(master));
491
492 /* derive key block for key expansion */
493 mks = this->signer_out->get_key_size(this->signer_out);
494 if (this->crypter_out)
495 {
496 eks = this->crypter_out->get_key_size(this->crypter_out);
497 if (this->tls->get_version(this->tls) < TLS_1_1)
498 {
499 ivs = this->crypter_out->get_block_size(this->crypter_out);
500 }
501 }
502 seed = chunk_cata("cc", server_random, client_random);
503 block = chunk_alloca((mks + eks + ivs) * 2);
504 this->prf->get_bytes(this->prf, "key expansion", seed, block.len, block.ptr);
505
506 /* signer keys */
507 client_write = chunk_create(block.ptr, mks);
508 block = chunk_skip(block, mks);
509 server_write = chunk_create(block.ptr, mks);
510 block = chunk_skip(block, mks);
511 if (this->tls->is_server(this->tls))
512 {
513 this->signer_in->set_key(this->signer_in, client_write);
514 this->signer_out->set_key(this->signer_out, server_write);
515 }
516 else
517 {
518 this->signer_out->set_key(this->signer_out, client_write);
519 this->signer_in->set_key(this->signer_in, server_write);
520 }
521
522 /* crypter keys, and IVs if < TLSv1.2 */
523 if (this->crypter_out && this->crypter_in)
524 {
525 client_write = chunk_create(block.ptr, eks);
526 block = chunk_skip(block, eks);
527 server_write = chunk_create(block.ptr, eks);
528 block = chunk_skip(block, eks);
529
530 if (this->tls->is_server(this->tls))
531 {
532 this->crypter_in->set_key(this->crypter_in, client_write);
533 this->crypter_out->set_key(this->crypter_out, server_write);
534 }
535 else
536 {
537 this->crypter_out->set_key(this->crypter_out, client_write);
538 this->crypter_in->set_key(this->crypter_in, server_write);
539 }
540 if (ivs)
541 {
542 client_write = chunk_create(block.ptr, ivs);
543 block = chunk_skip(block, ivs);
544 server_write = chunk_create(block.ptr, ivs);
545 block = chunk_skip(block, ivs);
546
547 if (this->tls->is_server(this->tls))
548 {
549 this->iv_in = chunk_clone(client_write);
550 this->iv_out = chunk_clone(server_write);
551 }
552 else
553 {
554 this->iv_out = chunk_clone(client_write);
555 this->iv_in = chunk_clone(server_write);
556 }
557 }
558 }
559 }
560
561 METHOD(tls_crypto_t, change_cipher, void,
562 private_tls_crypto_t *this, bool inbound)
563 {
564 if (inbound)
565 {
566 this->tls->change_cipher(this->tls, TRUE, this->signer_in,
567 this->crypter_in, this->iv_in);
568 }
569 else
570 {
571 this->tls->change_cipher(this->tls, FALSE, this->signer_out,
572 this->crypter_out, this->iv_out);
573 }
574 }
575
576 METHOD(tls_crypto_t, derive_eap_msk, void,
577 private_tls_crypto_t *this, chunk_t client_random, chunk_t server_random)
578 {
579 chunk_t seed;
580
581 seed = chunk_cata("cc", client_random, server_random);
582 free(this->msk.ptr);
583 this->msk = chunk_alloc(64);
584 this->prf->get_bytes(this->prf, "client EAP encryption", seed,
585 this->msk.len, this->msk.ptr);
586 }
587
588 METHOD(tls_crypto_t, get_eap_msk, chunk_t,
589 private_tls_crypto_t *this)
590 {
591 return this->msk;
592 }
593
594 METHOD(tls_crypto_t, destroy, void,
595 private_tls_crypto_t *this)
596 {
597 DESTROY_IF(this->signer_in);
598 DESTROY_IF(this->signer_out);
599 DESTROY_IF(this->crypter_in);
600 DESTROY_IF(this->crypter_out);
601 free(this->iv_in.ptr);
602 free(this->iv_out.ptr);
603 free(this->handshake.ptr);
604 free(this->msk.ptr);
605 DESTROY_IF(this->prf);
606 free(this->suites);
607 free(this);
608 }
609
610 /**
611 * See header
612 */
613 tls_crypto_t *tls_crypto_create(tls_t *tls)
614 {
615 private_tls_crypto_t *this;
616
617 INIT(this,
618 .public = {
619 .get_cipher_suites = _get_cipher_suites,
620 .select_cipher_suite = _select_cipher_suite,
621 .append_handshake = _append_handshake,
622 .sign_handshake = _sign_handshake,
623 .calculate_finished = _calculate_finished,
624 .derive_secrets = _derive_secrets,
625 .change_cipher = _change_cipher,
626 .derive_eap_msk = _derive_eap_msk,
627 .get_eap_msk = _get_eap_msk,
628 .destroy = _destroy,
629 },
630 .tls = tls,
631 );
632
633 build_cipher_suite_list(this);
634
635 return &this->public;
636 }