Derive MSK for EAP-TLS authentication
[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 * EAP-TLS MSK
89 */
90 chunk_t msk;
91 };
92
93 typedef struct {
94 tls_cipher_suite_t suite;
95 hash_algorithm_t hash;
96 pseudo_random_function_t prf;
97 integrity_algorithm_t mac;
98 encryption_algorithm_t encr;
99 size_t encr_size;
100 } suite_algs_t;
101
102 /**
103 * Mapping suites to a set of algorithms
104 */
105 static suite_algs_t suite_algs[] = {
106 { TLS_RSA_WITH_NULL_MD5,
107 HASH_MD5,
108 PRF_HMAC_MD5,
109 AUTH_HMAC_MD5_128,
110 ENCR_NULL, 0
111 },
112 { TLS_RSA_WITH_NULL_SHA,
113 HASH_SHA1,
114 PRF_HMAC_SHA1,
115 AUTH_HMAC_SHA1_160,
116 ENCR_NULL, 0
117 },
118 { TLS_RSA_WITH_NULL_SHA256,
119 HASH_SHA256,
120 PRF_HMAC_SHA2_256,
121 AUTH_HMAC_SHA2_256_256,
122 ENCR_NULL, 0
123 },
124 { TLS_RSA_WITH_AES_128_CBC_SHA,
125 HASH_SHA1,
126 PRF_HMAC_SHA1,
127 AUTH_HMAC_SHA1_160,
128 ENCR_AES_CBC, 16
129 },
130 { TLS_RSA_WITH_AES_256_CBC_SHA,
131 HASH_SHA1,
132 PRF_HMAC_SHA1,
133 AUTH_HMAC_SHA1_160,
134 ENCR_AES_CBC, 32
135 },
136 { TLS_RSA_WITH_3DES_EDE_CBC_SHA,
137 HASH_SHA1,
138 PRF_HMAC_SHA1,
139 AUTH_HMAC_SHA1_160,
140 ENCR_3DES, 0
141 },
142 { TLS_RSA_WITH_AES_128_CBC_SHA256,
143 HASH_SHA256,
144 PRF_HMAC_SHA2_256,
145 AUTH_HMAC_SHA2_256_256,
146 ENCR_AES_CBC, 16
147 },
148 };
149
150 /**
151 * Look up algoritms by a suite
152 */
153 static suite_algs_t *find_suite(tls_cipher_suite_t suite)
154 {
155 int i;
156
157 for (i = 0; i < countof(suite_algs); i++)
158 {
159 if (suite_algs[i].suite == suite)
160 {
161 return &suite_algs[i];
162 }
163 }
164 return NULL;
165 }
166
167 /**
168 * Initialize the cipher suite list
169 */
170 static void build_cipher_suite_list(private_tls_crypto_t *this)
171 {
172 encryption_algorithm_t encr;
173 integrity_algorithm_t mac;
174 enumerator_t *encrs, *macs;
175 tls_cipher_suite_t supported[64], unique[64];
176 int count = 0, i, j;
177
178 /* we assume that we support RSA, but no DHE yet */
179 macs = lib->crypto->create_signer_enumerator(lib->crypto);
180 while (macs->enumerate(macs, &mac))
181 {
182 switch (mac)
183 {
184 case AUTH_HMAC_SHA1_160:
185 supported[count++] = TLS_RSA_WITH_NULL_SHA;
186 break;
187 case AUTH_HMAC_SHA2_256_256:
188 supported[count++] = TLS_RSA_WITH_NULL_SHA256;
189 break;
190 case AUTH_HMAC_MD5_128:
191 supported[count++] = TLS_RSA_WITH_NULL_MD5;
192 break;
193 default:
194 break;
195 }
196 encrs = lib->crypto->create_crypter_enumerator(lib->crypto);
197 while (encrs->enumerate(encrs, &encr))
198 {
199 switch (encr)
200 {
201 case ENCR_AES_CBC:
202 switch (mac)
203 {
204 case AUTH_HMAC_SHA1_160:
205 supported[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
206 supported[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
207 break;
208 case AUTH_HMAC_SHA2_256_256:
209 supported[count++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
210 supported[count++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
211 break;
212 default:
213 break;
214 }
215 break;
216 case ENCR_3DES:
217 switch (mac)
218 {
219 case AUTH_HMAC_SHA1_160:
220 supported[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
221 break;
222 default:
223 break;
224 }
225 break;
226 default:
227 break;
228 }
229 }
230 encrs->destroy(encrs);
231 }
232 macs->destroy(macs);
233
234 /* remove duplicates */
235 this->suite_count = 0;
236 for (i = 0; i < count; i++)
237 {
238 bool match = FALSE;
239
240 for (j = 0; j < this->suite_count; j++)
241 {
242 if (supported[i] == unique[j])
243 {
244 match = TRUE;
245 break;
246 }
247 }
248 if (!match)
249 {
250 unique[this->suite_count++] = supported[i];
251 }
252 }
253 free(this->suites);
254 this->suites = malloc(sizeof(tls_cipher_suite_t) * this->suite_count);
255 memcpy(this->suites, unique, sizeof(tls_cipher_suite_t) * this->suite_count);
256 }
257
258 METHOD(tls_crypto_t, get_cipher_suites, int,
259 private_tls_crypto_t *this, tls_cipher_suite_t **suites)
260 {
261 *suites = this->suites;
262 return this->suite_count;
263 }
264
265 /**
266 * Create crypto primitives
267 */
268 static bool create_ciphers(private_tls_crypto_t *this, tls_cipher_suite_t suite)
269 {
270 suite_algs_t *algs;
271
272 algs = find_suite(suite);
273 if (!algs)
274 {
275 DBG1(DBG_IKE, "selected TLS suite not supported");
276 return FALSE;
277 }
278
279 DESTROY_IF(this->prf);
280 if (this->tls->get_version(this->tls) < TLS_1_2)
281 {
282 this->prf = tls_prf_create_10();
283 }
284 else
285 {
286 this->prf = tls_prf_create_12(algs->prf);
287 }
288 if (!this->prf)
289 {
290 DBG1(DBG_IKE, "selected TLS PRF not supported");
291 return FALSE;
292 }
293
294 DESTROY_IF(this->signer_in);
295 DESTROY_IF(this->signer_out);
296 this->signer_in = lib->crypto->create_signer(lib->crypto, algs->mac);
297 this->signer_out = lib->crypto->create_signer(lib->crypto, algs->mac);
298 if (!this->signer_in || !this->signer_out)
299 {
300 DBG1(DBG_IKE, "selected TLS MAC %N not supported",
301 integrity_algorithm_names, algs->mac);
302 return FALSE;
303 }
304
305 DESTROY_IF(this->crypter_in);
306 DESTROY_IF(this->crypter_out);
307 if (algs->encr == ENCR_NULL)
308 {
309 this->crypter_in = this->crypter_out = NULL;
310 }
311 else
312 {
313 this->crypter_in = lib->crypto->create_crypter(lib->crypto,
314 algs->encr, algs->encr_size);
315 this->crypter_out = lib->crypto->create_crypter(lib->crypto,
316 algs->encr, algs->encr_size);
317 if (!this->crypter_in || !this->crypter_out)
318 {
319 DBG1(DBG_IKE, "selected TLS crypter %N not supported",
320 encryption_algorithm_names, algs->encr);
321 return FALSE;
322 }
323 }
324 return TRUE;
325 }
326
327 METHOD(tls_crypto_t, select_cipher_suite, tls_cipher_suite_t,
328 private_tls_crypto_t *this, tls_cipher_suite_t *suites, int count)
329 {
330 int i, j;
331
332 for (i = 0; i < this->suite_count; i++)
333 {
334 for (j = 0; j < count; j++)
335 {
336 if (this->suites[i] == suites[j])
337 {
338 if (create_ciphers(this, this->suites[i]))
339 {
340 this->suite = this->suites[i];
341 return this->suite;
342 }
343 }
344 }
345 }
346 return 0;
347 }
348
349 METHOD(tls_crypto_t, derive_master_secret, void,
350 private_tls_crypto_t *this, chunk_t premaster,
351 chunk_t client_random, chunk_t server_random)
352 {
353 char master[48];
354 chunk_t seed, block, client_write, server_write;
355 int mks, eks = 0, ivs = 0;
356
357 /* derive master secret */
358 seed = chunk_cata("cc", client_random, server_random);
359 this->prf->set_key(this->prf, premaster);
360 this->prf->get_bytes(this->prf, "master secret", seed,
361 sizeof(master), master);
362
363 this->prf->set_key(this->prf, chunk_from_thing(master));
364 memset(master, 0, sizeof(master));
365
366 /* MSK for EAP-TLS */
367 this->msk = chunk_alloc(64);
368 this->prf->get_bytes(this->prf, "client EAP encryption", seed,
369 this->msk.len, this->msk.ptr);
370
371 /* derive key block for key expansion */
372 mks = this->signer_out->get_key_size(this->signer_out);
373 if (this->crypter_out)
374 {
375 eks = this->crypter_out->get_key_size(this->crypter_out);
376 if (this->tls->get_version(this->tls) < TLS_1_1)
377 {
378 ivs = this->crypter_out->get_block_size(this->crypter_out);
379 }
380 }
381 seed = chunk_cata("cc", server_random, client_random);
382 block = chunk_alloca((mks + eks + ivs) * 2);
383 this->prf->get_bytes(this->prf, "key expansion", seed, block.len, block.ptr);
384
385 /* signer keys */
386 client_write = chunk_create(block.ptr, mks);
387 block = chunk_skip(block, mks);
388 server_write = chunk_create(block.ptr, mks);
389 block = chunk_skip(block, mks);
390 if (this->tls->is_server(this->tls))
391 {
392 this->signer_in->set_key(this->signer_in, client_write);
393 this->signer_out->set_key(this->signer_out, server_write);
394 }
395 else
396 {
397 this->signer_out->set_key(this->signer_out, client_write);
398 this->signer_in->set_key(this->signer_in, server_write);
399 }
400
401 /* crypter keys, and IVs if < TLSv1.2 */
402 if (this->crypter_out && this->crypter_in)
403 {
404 client_write = chunk_create(block.ptr, eks);
405 block = chunk_skip(block, eks);
406 server_write = chunk_create(block.ptr, eks);
407 block = chunk_skip(block, eks);
408
409 if (this->tls->is_server(this->tls))
410 {
411 this->crypter_in->set_key(this->crypter_in, client_write);
412 this->crypter_out->set_key(this->crypter_out, server_write);
413 }
414 else
415 {
416 this->crypter_out->set_key(this->crypter_out, client_write);
417 this->crypter_in->set_key(this->crypter_in, server_write);
418 }
419 if (ivs)
420 {
421 client_write = chunk_create(block.ptr, ivs);
422 block = chunk_skip(block, ivs);
423 server_write = chunk_create(block.ptr, ivs);
424 block = chunk_skip(block, ivs);
425
426 if (this->tls->is_server(this->tls))
427 {
428 this->iv_in = chunk_clone(client_write);
429 this->iv_out = chunk_clone(server_write);
430 }
431 else
432 {
433 this->iv_out = chunk_clone(client_write);
434 this->iv_in = chunk_clone(server_write);
435 }
436 }
437 }
438 }
439
440 METHOD(tls_crypto_t, change_cipher, void,
441 private_tls_crypto_t *this, bool inbound)
442 {
443 if (inbound)
444 {
445 this->tls->change_cipher(this->tls, TRUE, this->signer_in,
446 this->crypter_in, this->iv_in);
447 }
448 else
449 {
450 this->tls->change_cipher(this->tls, FALSE, this->signer_out,
451 this->crypter_out, this->iv_out);
452 }
453 }
454
455 METHOD(tls_crypto_t, get_prf, tls_prf_t*,
456 private_tls_crypto_t *this)
457 {
458 return this->prf;
459 }
460
461 METHOD(tls_crypto_t, get_eap_msk, chunk_t,
462 private_tls_crypto_t *this)
463 {
464 return this->msk;
465 }
466
467 METHOD(tls_crypto_t, destroy, void,
468 private_tls_crypto_t *this)
469 {
470 DESTROY_IF(this->signer_in);
471 DESTROY_IF(this->signer_out);
472 DESTROY_IF(this->crypter_in);
473 DESTROY_IF(this->crypter_out);
474 free(this->iv_in.ptr);
475 free(this->iv_out.ptr);
476 free(this->msk.ptr);
477 DESTROY_IF(this->prf);
478 free(this->suites);
479 free(this);
480 }
481
482 /**
483 * See header
484 */
485 tls_crypto_t *tls_crypto_create(tls_t *tls)
486 {
487 private_tls_crypto_t *this;
488
489 INIT(this,
490 .public = {
491 .get_cipher_suites = _get_cipher_suites,
492 .select_cipher_suite = _select_cipher_suite,
493 .derive_master_secret = _derive_master_secret,
494 .change_cipher = _change_cipher,
495 .get_prf = _get_prf,
496 .get_eap_msk = _get_eap_msk,
497 .destroy = _destroy,
498 },
499 .tls = tls,
500 );
501
502 build_cipher_suite_list(this);
503
504 return &this->public;
505 }