891f6a21e004ba78321b02374efdfd509f806700
[strongswan.git] / src / libcharon / sa / keymat_v1.c
1 /*
2 * Copyright (C) 2011 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
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 "keymat_v1.h"
17
18 #include <daemon.h>
19 #include <utils/linked_list.h>
20
21 typedef struct private_keymat_v1_t private_keymat_v1_t;
22
23 /**
24 * Max. number of IVs to track.
25 */
26 #define MAX_IV 3
27
28 /**
29 * Data stored for IVs
30 */
31 typedef struct {
32 /** message ID */
33 u_int32_t mid;
34 /** current IV */
35 chunk_t iv;
36 /** last block of encrypted message */
37 chunk_t last_block;
38 } iv_data_t;
39
40 /**
41 * Private data of an keymat_t object.
42 */
43 struct private_keymat_v1_t {
44
45 /**
46 * Public keymat_v1_t interface.
47 */
48 keymat_v1_t public;
49
50 /**
51 * IKE_SA Role, initiator or responder
52 */
53 bool initiator;
54
55 /**
56 * General purpose PRF
57 */
58 prf_t *prf;
59
60 /**
61 * Negotiated PRF algorithm
62 */
63 pseudo_random_function_t prf_alg;
64
65 /**
66 * Crypter wrapped in an aead_t interface
67 */
68 aead_t *aead;
69
70 /**
71 * Hasher used for IV generation
72 */
73 hasher_t *hasher;
74
75 /**
76 * Key used for authentication during main mode
77 */
78 chunk_t skeyid;
79
80 /**
81 * Key to derive key material from for non-ISAKMP SAs, rekeying
82 */
83 chunk_t skeyid_d;
84
85 /**
86 * Key used for authentication after main mode
87 */
88 chunk_t skeyid_a;
89
90 /**
91 * Phase 1 IV
92 */
93 iv_data_t phase1_iv;
94
95 /**
96 * Keep track of IVs for exchanges after phase 1. We store only a limited
97 * number of IVs in an MRU sort of way. Stores iv_data_t objects.
98 */
99 linked_list_t *ivs;
100 };
101
102
103 /**
104 * Destroy an iv_data_t object.
105 */
106 static void iv_data_destroy(iv_data_t *this)
107 {
108 chunk_free(&this->last_block);
109 chunk_free(&this->iv);
110 free(this);
111 }
112
113 /**
114 * Constants used in key derivation.
115 */
116 static const chunk_t octet_0 = chunk_from_chars(0x00);
117 static const chunk_t octet_1 = chunk_from_chars(0x01);
118 static const chunk_t octet_2 = chunk_from_chars(0x02);
119
120 /**
121 * Simple aead_t implementation without support for authentication.
122 */
123 typedef struct {
124 /** implements aead_t interface */
125 aead_t aead;
126 /** crypter to be used */
127 crypter_t *crypter;
128 } private_aead_t;
129
130
131 METHOD(aead_t, encrypt, void,
132 private_aead_t *this, chunk_t plain, chunk_t assoc, chunk_t iv,
133 chunk_t *encrypted)
134 {
135 this->crypter->encrypt(this->crypter, plain, iv, encrypted);
136 }
137
138 METHOD(aead_t, decrypt, bool,
139 private_aead_t *this, chunk_t encrypted, chunk_t assoc, chunk_t iv,
140 chunk_t *plain)
141 {
142 this->crypter->decrypt(this->crypter, encrypted, iv, plain);
143 return TRUE;
144 }
145
146 METHOD(aead_t, get_block_size, size_t,
147 private_aead_t *this)
148 {
149 return this->crypter->get_block_size(this->crypter);
150 }
151
152 METHOD(aead_t, get_icv_size, size_t,
153 private_aead_t *this)
154 {
155 return 0;
156 }
157
158 METHOD(aead_t, get_iv_size, size_t,
159 private_aead_t *this)
160 {
161 /* in order to create the messages properly we return 0 here */
162 return 0;
163 }
164
165 METHOD(aead_t, get_key_size, size_t,
166 private_aead_t *this)
167 {
168 return this->crypter->get_key_size(this->crypter);
169 }
170
171 METHOD(aead_t, set_key, void,
172 private_aead_t *this, chunk_t key)
173 {
174 this->crypter->set_key(this->crypter, key);
175 }
176
177 METHOD(aead_t, aead_destroy, void,
178 private_aead_t *this)
179 {
180 this->crypter->destroy(this->crypter);
181 free(this);
182 }
183
184 /**
185 * Expand SKEYID_e according to Appendix B in RFC 2409.
186 * TODO-IKEv1: verify keys (e.g. for weak keys, see Appendix B)
187 */
188 static chunk_t expand_skeyid_e(chunk_t skeyid_e, size_t key_size, prf_t *prf)
189 {
190 size_t block_size;
191 chunk_t seed, ka;
192 int i;
193
194 if (skeyid_e.len >= key_size)
195 { /* no expansion required, reduce to key_size */
196 skeyid_e.len = key_size;
197 return skeyid_e;
198 }
199 block_size = prf->get_block_size(prf);
200 ka = chunk_alloc((key_size / block_size + 1) * block_size);
201 ka.len = key_size;
202
203 /* Ka = K1 | K2 | ..., K1 = prf(SKEYID_e, 0), K2 = prf(SKEYID_e, K1) ... */
204 prf->set_key(prf, skeyid_e);
205 seed = octet_0;
206 for (i = 0; i < key_size; i += block_size)
207 {
208 prf->get_bytes(prf, seed, ka.ptr + i);
209 seed = chunk_create(ka.ptr + i, block_size);
210 }
211 chunk_clear(&skeyid_e);
212 return ka;
213 }
214
215 /**
216 * Create a simple implementation of the aead_t interface which only encrypts
217 * or decrypts data.
218 */
219 static aead_t *create_aead(proposal_t *proposal, prf_t *prf, chunk_t skeyid_e)
220 {
221 private_aead_t *this;
222 u_int16_t alg, key_size;
223 crypter_t *crypter;
224 chunk_t ka;
225
226 if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &alg,
227 &key_size))
228 {
229 DBG1(DBG_IKE, "no %N selected",
230 transform_type_names, ENCRYPTION_ALGORITHM);
231 return NULL;
232 }
233 crypter = lib->crypto->create_crypter(lib->crypto, alg, key_size / 8);
234 if (!crypter)
235 {
236 DBG1(DBG_IKE, "%N %N (key size %d) not supported!",
237 transform_type_names, ENCRYPTION_ALGORITHM,
238 encryption_algorithm_names, alg, key_size);
239 return NULL;
240 }
241 key_size = crypter->get_key_size(crypter);
242 ka = expand_skeyid_e(skeyid_e, crypter->get_key_size(crypter), prf);
243 DBG4(DBG_IKE, "encryption key Ka %B", &ka);
244 crypter->set_key(crypter, ka);
245 chunk_clear(&ka);
246
247 INIT(this,
248 .aead = {
249 .encrypt = _encrypt,
250 .decrypt = _decrypt,
251 .get_block_size = _get_block_size,
252 .get_icv_size = _get_icv_size,
253 .get_iv_size = _get_iv_size,
254 .get_key_size = _get_key_size,
255 .set_key = _set_key,
256 .destroy = _aead_destroy,
257 },
258 .crypter = crypter,
259 );
260 return &this->aead;
261 }
262
263 /**
264 * Converts integrity algorithm to PRF algorithm
265 */
266 static u_int16_t auth_to_prf(u_int16_t alg)
267 {
268 switch (alg)
269 {
270 case AUTH_HMAC_SHA1_96:
271 return PRF_HMAC_SHA1;
272 case AUTH_HMAC_SHA2_256_128:
273 return PRF_HMAC_SHA2_256;
274 case AUTH_HMAC_SHA2_384_192:
275 return PRF_HMAC_SHA2_384;
276 case AUTH_HMAC_SHA2_512_256:
277 return PRF_HMAC_SHA2_512;
278 case AUTH_HMAC_MD5_96:
279 return PRF_HMAC_MD5;
280 case AUTH_AES_XCBC_96:
281 return PRF_AES128_XCBC;
282 default:
283 return PRF_UNDEFINED;
284 }
285 }
286
287 /**
288 * Converts integrity algorithm to hash algorithm
289 */
290 static u_int16_t auth_to_hash(u_int16_t alg)
291 {
292 switch (alg)
293 {
294 case AUTH_HMAC_SHA1_96:
295 return HASH_SHA1;
296 case AUTH_HMAC_SHA2_256_128:
297 return HASH_SHA256;
298 case AUTH_HMAC_SHA2_384_192:
299 return HASH_SHA384;
300 case AUTH_HMAC_SHA2_512_256:
301 return HASH_SHA512;
302 case AUTH_HMAC_MD5_96:
303 return HASH_MD5;
304 default:
305 return HASH_UNKNOWN;
306 }
307 }
308
309 /**
310 * Adjust the key length for PRF algorithms that expect a fixed key length.
311 */
312 static void adjust_keylen(u_int16_t alg, chunk_t *key)
313 {
314 switch (alg)
315 {
316 case PRF_AES128_XCBC:
317 /* while rfc4434 defines variable keys for AES-XCBC, rfc3664 does
318 * not and therefore fixed key semantics apply to XCBC for key
319 * derivation. */
320 key->len = min(key->len, 16);
321 break;
322 default:
323 /* all other algorithms use variable key length */
324 break;
325 }
326 }
327
328 METHOD(keymat_v1_t, derive_ike_keys, bool,
329 private_keymat_v1_t *this, proposal_t *proposal, diffie_hellman_t *dh,
330 chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id,
331 auth_class_t auth, shared_key_t *shared_key)
332 {
333 chunk_t g_xy, g_xi, g_xr, dh_me, spi_i, spi_r, nonces, data, skeyid_e;
334 u_int16_t alg;
335
336 spi_i = chunk_alloca(sizeof(u_int64_t));
337 spi_r = chunk_alloca(sizeof(u_int64_t));
338
339 if (!proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &alg, NULL))
340 { /* no PRF negotiated, use HMAC version of integrity algorithm instead */
341 if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &alg, NULL)
342 || (alg = auth_to_prf(alg)) == PRF_UNDEFINED)
343 {
344 DBG1(DBG_IKE, "no %N selected",
345 transform_type_names, PSEUDO_RANDOM_FUNCTION);
346 return FALSE;
347 }
348 }
349 this->prf_alg = alg;
350 this->prf = lib->crypto->create_prf(lib->crypto, alg);
351 if (!this->prf)
352 {
353 DBG1(DBG_IKE, "%N %N not supported!",
354 transform_type_names, PSEUDO_RANDOM_FUNCTION,
355 pseudo_random_function_names, alg);
356 return FALSE;
357 }
358 if (this->prf->get_block_size(this->prf) <
359 this->prf->get_key_size(this->prf))
360 { /* TODO-IKEv1: support PRF output expansion (RFC 2409, Appendix B) */
361 DBG1(DBG_IKE, "expansion of %N %N output not supported!",
362 transform_type_names, PSEUDO_RANDOM_FUNCTION,
363 pseudo_random_function_names, alg);
364 return FALSE;
365 }
366
367 if (dh->get_shared_secret(dh, &g_xy) != SUCCESS)
368 {
369 return FALSE;
370 }
371 DBG4(DBG_IKE, "shared Diffie Hellman secret %B", &g_xy);
372
373 *((u_int64_t*)spi_i.ptr) = id->get_initiator_spi(id);
374 *((u_int64_t*)spi_r.ptr) = id->get_responder_spi(id);
375 nonces = chunk_cata("cc", nonce_i, nonce_r);
376
377 switch (auth)
378 {
379 case AUTH_CLASS_PSK:
380 { /* SKEYID = prf(pre-shared-key, Ni_b | Nr_b) */
381 chunk_t psk;
382 if (!shared_key)
383 {
384 chunk_clear(&g_xy);
385 return FALSE;
386 }
387 psk = shared_key->get_key(shared_key);
388 adjust_keylen(alg, &psk);
389 this->prf->set_key(this->prf, psk);
390 this->prf->allocate_bytes(this->prf, nonces, &this->skeyid);
391 break;
392 }
393 case AUTH_CLASS_PUBKEY:
394 {
395 /* signatures : SKEYID = prf(Ni_b | Nr_b, g^xy)
396 * pubkey encr: SKEYID = prf(hash(Ni_b | Nr_b), CKY-I | CKY-R) */
397 /* TODO-IKEv1: implement key derivation for other schemes,
398 * fall for now */
399 }
400 default:
401 /* authentication class not supported */
402 chunk_clear(&g_xy);
403 return FALSE;
404 }
405 adjust_keylen(alg, &this->skeyid);
406 DBG4(DBG_IKE, "SKEYID %B", &this->skeyid);
407
408 /* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */
409 data = chunk_cat("cccc", g_xy, spi_i, spi_r, octet_0);
410 this->prf->set_key(this->prf, this->skeyid);
411 this->prf->allocate_bytes(this->prf, data, &this->skeyid_d);
412 chunk_clear(&data);
413 DBG4(DBG_IKE, "SKEYID_d %B", &this->skeyid_d);
414
415 /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */
416 data = chunk_cat("ccccc", this->skeyid_d, g_xy, spi_i, spi_r, octet_1);
417 this->prf->set_key(this->prf, this->skeyid);
418 this->prf->allocate_bytes(this->prf, data, &this->skeyid_a);
419 chunk_clear(&data);
420 DBG4(DBG_IKE, "SKEYID_a %B", &this->skeyid_a);
421
422 /* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */
423 data = chunk_cat("ccccc", this->skeyid_a, g_xy, spi_i, spi_r, octet_2);
424 this->prf->set_key(this->prf, this->skeyid);
425 this->prf->allocate_bytes(this->prf, data, &skeyid_e);
426 chunk_clear(&data);
427 DBG4(DBG_IKE, "SKEYID_e %B", &skeyid_e);
428
429 chunk_clear(&g_xy);
430
431 this->aead = create_aead(proposal, this->prf, skeyid_e);
432 if (!this->aead)
433 {
434 return FALSE;
435 }
436
437 if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &alg, NULL) ||
438 (alg = auth_to_hash(alg)) == HASH_UNKNOWN)
439 {
440 DBG1(DBG_IKE, "no %N selected", transform_type_names, HASH_ALGORITHM);
441 return FALSE;
442 }
443 this->hasher = lib->crypto->create_hasher(lib->crypto, alg);
444 if (!this->hasher)
445 {
446 DBG1(DBG_IKE, "%N %N not supported!",
447 transform_type_names, HASH_ALGORITHM,
448 hash_algorithm_names, alg);
449 return FALSE;
450 }
451
452 dh->get_my_public_value(dh, &dh_me);
453 g_xi = this->initiator ? dh_me : dh_other;
454 g_xr = this->initiator ? dh_other : dh_me;
455
456 /* initial IV = hash(g^xi | g^xr) */
457 data = chunk_cata("cc", g_xi, g_xr);
458 this->hasher->allocate_hash(this->hasher, data, &this->phase1_iv.iv);
459 if (this->phase1_iv.iv.len > this->aead->get_block_size(this->aead))
460 {
461 this->phase1_iv.iv.len = this->aead->get_block_size(this->aead);
462 }
463 chunk_free(&dh_me);
464 DBG4(DBG_IKE, "initial IV %B", &this->phase1_iv.iv);
465
466 return TRUE;
467 }
468
469 /**
470 * Generate an IV
471 */
472 static void generate_iv(private_keymat_v1_t *this, iv_data_t *iv)
473 {
474 if (iv->mid == 0 || iv->iv.ptr)
475 { /* use last block of previous encrypted message */
476 chunk_free(&iv->iv);
477 iv->iv = iv->last_block;
478 iv->last_block = chunk_empty;
479 }
480 else
481 {
482 /* initial phase 2 IV = hash(last_phase1_block | mid) */
483 u_int32_t net = htonl(iv->mid);
484 chunk_t data = chunk_cata("cc", this->phase1_iv.iv,
485 chunk_from_thing(net));
486 this->hasher->allocate_hash(this->hasher, data, &iv->iv);
487 if (iv->iv.len > this->aead->get_block_size(this->aead))
488 {
489 iv->iv.len = this->aead->get_block_size(this->aead);
490 }
491 }
492 DBG4(DBG_IKE, "next IV for MID %u %B", iv->mid, &iv->iv);
493 }
494
495 /**
496 * Try to find an IV for the given message ID, if not found, generate it.
497 */
498 static iv_data_t *lookup_iv(private_keymat_v1_t *this, u_int32_t mid)
499 {
500 enumerator_t *enumerator;
501 iv_data_t *iv, *found = NULL;
502
503 if (mid == 0)
504 {
505 return &this->phase1_iv;
506 }
507
508 enumerator = this->ivs->create_enumerator(this->ivs);
509 while (enumerator->enumerate(enumerator, &iv))
510 {
511 if (iv->mid == mid)
512 { /* IV gets moved to the front of the list */
513 this->ivs->remove_at(this->ivs, enumerator);
514 found = iv;
515 break;
516 }
517 }
518 enumerator->destroy(enumerator);
519 if (!found)
520 {
521 INIT(found,
522 .mid = mid,
523 );
524 generate_iv(this, found);
525 }
526 this->ivs->insert_first(this->ivs, found);
527 /* remove least recently used IV if maximum reached */
528 if (this->ivs->get_count(this->ivs) > MAX_IV &&
529 this->ivs->remove_last(this->ivs, (void**)&iv) == SUCCESS)
530 {
531 iv_data_destroy(iv);
532 }
533 return found;
534 }
535
536 METHOD(keymat_v1_t, get_iv, chunk_t,
537 private_keymat_v1_t *this, u_int32_t mid)
538 {
539 return chunk_clone(lookup_iv(this, mid)->iv);
540 }
541
542 METHOD(keymat_v1_t, update_iv, void,
543 private_keymat_v1_t *this, u_int32_t mid, chunk_t last_block)
544 {
545 iv_data_t *iv = lookup_iv(this, mid);
546 if (iv)
547 { /* update last block */
548 chunk_free(&iv->last_block);
549 iv->last_block = chunk_clone(last_block);
550 }
551 }
552
553 METHOD(keymat_v1_t, confirm_iv, void,
554 private_keymat_v1_t *this, u_int32_t mid)
555 {
556 iv_data_t *iv = lookup_iv(this, mid);
557 if (iv)
558 {
559 generate_iv(this, iv);
560 }
561 }
562
563 METHOD(keymat_t, create_dh, diffie_hellman_t*,
564 private_keymat_v1_t *this, diffie_hellman_group_t group)
565 {
566 return lib->crypto->create_dh(lib->crypto, group);
567 }
568
569 METHOD(keymat_t, get_aead, aead_t*,
570 private_keymat_v1_t *this, bool in)
571 {
572 return this->aead;
573 }
574
575 METHOD(keymat_t, destroy, void,
576 private_keymat_v1_t *this)
577 {
578 DESTROY_IF(this->prf);
579 DESTROY_IF(this->aead);
580 DESTROY_IF(this->hasher);
581 chunk_clear(&this->skeyid);
582 chunk_clear(&this->skeyid_d);
583 chunk_clear(&this->skeyid_a);
584 chunk_free(&this->phase1_iv.iv);
585 chunk_free(&this->phase1_iv.last_block);
586 this->ivs->destroy_function(this->ivs, (void*)iv_data_destroy);
587 free(this);
588 }
589
590 /**
591 * See header
592 */
593 keymat_v1_t *keymat_v1_create(bool initiator)
594 {
595 private_keymat_v1_t *this;
596
597 INIT(this,
598 .public = {
599 .keymat = {
600 .create_dh = _create_dh,
601 .get_aead = _get_aead,
602 .destroy = _destroy,
603 },
604 .derive_ike_keys = _derive_ike_keys,
605 .get_iv = _get_iv,
606 .update_iv = _update_iv,
607 .confirm_iv = _confirm_iv,
608 },
609 .ivs = linked_list_create(),
610 .initiator = initiator,
611 .prf_alg = PRF_UNDEFINED,
612 );
613
614 return &this->public;
615 }