Annotation of embedaddon/strongswan/src/libcharon/sa/ikev1/keymat_v1.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2011 Tobias Brunner
3: * HSR 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 <sa/ikev1/iv_manager.h>
20: #include <encoding/generator.h>
21: #include <encoding/payloads/nonce_payload.h>
22:
23: typedef struct private_keymat_v1_t private_keymat_v1_t;
24:
25: /**
26: * Private data of an keymat_t object.
27: */
28: struct private_keymat_v1_t {
29:
30: /**
31: * Public keymat_v1_t interface.
32: */
33: keymat_v1_t public;
34:
35: /**
36: * IKE_SA Role, initiator or responder
37: */
38: bool initiator;
39:
40: /**
41: * General purpose PRF
42: */
43: prf_t *prf;
44:
45: /**
46: * PRF to create Phase 1 HASH payloads
47: */
48: prf_t *prf_auth;
49:
50: /**
51: * Crypter wrapped in an aead_t interface
52: */
53: aead_t *aead;
54:
55: /**
56: * Hasher used for IV generation (and other things like e.g. NAT-T)
57: */
58: hasher_t *hasher;
59:
60: /**
61: * Key to derive key material from for non-ISAKMP SAs, rekeying
62: */
63: chunk_t skeyid_d;
64:
65: /**
66: * Key used for authentication after main mode
67: */
68: chunk_t skeyid_a;
69:
70: /**
71: * IV and QM manager
72: */
73: iv_manager_t *iv_manager;
74: };
75:
76: /**
77: * Constants used in key derivation.
78: */
79: static const chunk_t octet_0 = chunk_from_chars(0x00);
80: static const chunk_t octet_1 = chunk_from_chars(0x01);
81: static const chunk_t octet_2 = chunk_from_chars(0x02);
82:
83: /**
84: * Simple aead_t implementation without support for authentication.
85: */
86: typedef struct {
87: /** implements aead_t interface */
88: aead_t aead;
89: /** crypter to be used */
90: crypter_t *crypter;
91: } private_aead_t;
92:
93:
94: METHOD(aead_t, encrypt, bool,
95: private_aead_t *this, chunk_t plain, chunk_t assoc, chunk_t iv,
96: chunk_t *encrypted)
97: {
98: return this->crypter->encrypt(this->crypter, plain, iv, encrypted);
99: }
100:
101: METHOD(aead_t, decrypt, bool,
102: private_aead_t *this, chunk_t encrypted, chunk_t assoc, chunk_t iv,
103: chunk_t *plain)
104: {
105: return this->crypter->decrypt(this->crypter, encrypted, iv, plain);
106: }
107:
108: METHOD(aead_t, get_block_size, size_t,
109: private_aead_t *this)
110: {
111: return this->crypter->get_block_size(this->crypter);
112: }
113:
114: METHOD(aead_t, get_icv_size, size_t,
115: private_aead_t *this)
116: {
117: return 0;
118: }
119:
120: METHOD(aead_t, get_iv_size, size_t,
121: private_aead_t *this)
122: {
123: /* in order to create the messages properly we return 0 here */
124: return 0;
125: }
126:
127: METHOD(aead_t, get_iv_gen, iv_gen_t*,
128: private_aead_t *this)
129: {
130: /* IVs are retrieved via keymat_v1.get_iv() */
131: return NULL;
132: }
133:
134: METHOD(aead_t, get_key_size, size_t,
135: private_aead_t *this)
136: {
137: return this->crypter->get_key_size(this->crypter);
138: }
139:
140: METHOD(aead_t, set_key, bool,
141: private_aead_t *this, chunk_t key)
142: {
143: return this->crypter->set_key(this->crypter, key);
144: }
145:
146: METHOD(aead_t, aead_destroy, void,
147: private_aead_t *this)
148: {
149: this->crypter->destroy(this->crypter);
150: free(this);
151: }
152:
153: /**
154: * Expand SKEYID_e according to Appendix B in RFC 2409.
155: * TODO-IKEv1: verify keys (e.g. for weak keys, see Appendix B)
156: */
157: static bool expand_skeyid_e(chunk_t skeyid_e, size_t key_size, prf_t *prf,
158: chunk_t *ka)
159: {
160: size_t block_size;
161: chunk_t seed;
162: int i;
163:
164: if (skeyid_e.len >= key_size)
165: { /* no expansion required, reduce to key_size */
166: skeyid_e.len = key_size;
167: *ka = skeyid_e;
168: return TRUE;
169: }
170: block_size = prf->get_block_size(prf);
171: *ka = chunk_alloc((key_size / block_size + 1) * block_size);
172: ka->len = key_size;
173:
174: /* Ka = K1 | K2 | ..., K1 = prf(SKEYID_e, 0), K2 = prf(SKEYID_e, K1) ... */
175: if (!prf->set_key(prf, skeyid_e))
176: {
177: chunk_clear(ka);
178: chunk_clear(&skeyid_e);
179: return FALSE;
180: }
181: seed = octet_0;
182: for (i = 0; i < key_size; i += block_size)
183: {
184: if (!prf->get_bytes(prf, seed, ka->ptr + i))
185: {
186: chunk_clear(ka);
187: chunk_clear(&skeyid_e);
188: return FALSE;
189: }
190: seed = chunk_create(ka->ptr + i, block_size);
191: }
192: chunk_clear(&skeyid_e);
193: return TRUE;
194: }
195:
196: /**
197: * Create a simple implementation of the aead_t interface which only encrypts
198: * or decrypts data.
199: */
200: static aead_t *create_aead(proposal_t *proposal, prf_t *prf, chunk_t skeyid_e,
201: chunk_t *ka)
202: {
203: private_aead_t *this;
204: uint16_t alg, key_size;
205: crypter_t *crypter;
206:
207: if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &alg,
208: &key_size))
209: {
210: DBG1(DBG_IKE, "no %N selected",
211: transform_type_names, ENCRYPTION_ALGORITHM);
212: return NULL;
213: }
214: crypter = lib->crypto->create_crypter(lib->crypto, alg, key_size / 8);
215: if (!crypter)
216: {
217: DBG1(DBG_IKE, "%N %N (key size %d) not supported!",
218: transform_type_names, ENCRYPTION_ALGORITHM,
219: encryption_algorithm_names, alg, key_size);
220: return NULL;
221: }
222: if (!expand_skeyid_e(skeyid_e, crypter->get_key_size(crypter), prf, ka))
223: {
224: return NULL;
225: }
226: DBG4(DBG_IKE, "encryption key Ka %B", ka);
227: if (!crypter->set_key(crypter, *ka))
228: {
229: chunk_clear(ka);
230: return NULL;
231: }
232:
233: INIT(this,
234: .aead = {
235: .encrypt = _encrypt,
236: .decrypt = _decrypt,
237: .get_block_size = _get_block_size,
238: .get_icv_size = _get_icv_size,
239: .get_iv_size = _get_iv_size,
240: .get_iv_gen = _get_iv_gen,
241: .get_key_size = _get_key_size,
242: .set_key = _set_key,
243: .destroy = _aead_destroy,
244: },
245: .crypter = crypter,
246: );
247: return &this->aead;
248: }
249:
250: /**
251: * Converts integrity algorithm to PRF algorithm
252: */
253: static uint16_t auth_to_prf(uint16_t alg)
254: {
255: switch (alg)
256: {
257: case AUTH_HMAC_SHA1_96:
258: return PRF_HMAC_SHA1;
259: case AUTH_HMAC_SHA2_256_128:
260: return PRF_HMAC_SHA2_256;
261: case AUTH_HMAC_SHA2_384_192:
262: return PRF_HMAC_SHA2_384;
263: case AUTH_HMAC_SHA2_512_256:
264: return PRF_HMAC_SHA2_512;
265: case AUTH_HMAC_MD5_96:
266: return PRF_HMAC_MD5;
267: case AUTH_AES_XCBC_96:
268: return PRF_AES128_XCBC;
269: default:
270: return PRF_UNDEFINED;
271: }
272: }
273:
274: /**
275: * Converts integrity algorithm to hash algorithm
276: */
277: static uint16_t auth_to_hash(uint16_t alg)
278: {
279: switch (alg)
280: {
281: case AUTH_HMAC_SHA1_96:
282: return HASH_SHA1;
283: case AUTH_HMAC_SHA2_256_128:
284: return HASH_SHA256;
285: case AUTH_HMAC_SHA2_384_192:
286: return HASH_SHA384;
287: case AUTH_HMAC_SHA2_512_256:
288: return HASH_SHA512;
289: case AUTH_HMAC_MD5_96:
290: return HASH_MD5;
291: default:
292: return HASH_UNKNOWN;
293: }
294: }
295:
296: /**
297: * Adjust the key length for PRF algorithms that expect a fixed key length.
298: */
299: static void adjust_keylen(uint16_t alg, chunk_t *key)
300: {
301: switch (alg)
302: {
303: case PRF_AES128_XCBC:
304: /* while rfc4434 defines variable keys for AES-XCBC, rfc3664 does
305: * not and therefore fixed key semantics apply to XCBC for key
306: * derivation. */
307: key->len = min(key->len, 16);
308: break;
309: default:
310: /* all other algorithms use variable key length */
311: break;
312: }
313: }
314:
315: METHOD(keymat_v1_t, derive_ike_keys, bool,
316: private_keymat_v1_t *this, proposal_t *proposal, diffie_hellman_t *dh,
317: chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id,
318: auth_method_t auth, shared_key_t *shared_key)
319: {
320: chunk_t g_xy, g_xi, g_xr, dh_me, spi_i, spi_r, nonces, data, skeyid_e;
321: chunk_t skeyid, ka;
322: uint16_t alg;
323:
324: spi_i = chunk_alloca(sizeof(uint64_t));
325: spi_r = chunk_alloca(sizeof(uint64_t));
326:
327: if (!proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &alg, NULL))
328: { /* no PRF negotiated, use HMAC version of integrity algorithm instead */
329: if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &alg, NULL)
330: || (alg = auth_to_prf(alg)) == PRF_UNDEFINED)
331: {
332: DBG1(DBG_IKE, "no %N selected",
333: transform_type_names, PSEUDO_RANDOM_FUNCTION);
334: return FALSE;
335: }
336: }
337: this->prf = lib->crypto->create_prf(lib->crypto, alg);
338: if (!this->prf)
339: {
340: DBG1(DBG_IKE, "%N %N not supported!",
341: transform_type_names, PSEUDO_RANDOM_FUNCTION,
342: pseudo_random_function_names, alg);
343: return FALSE;
344: }
345: if (this->prf->get_block_size(this->prf) <
346: this->prf->get_key_size(this->prf))
347: { /* TODO-IKEv1: support PRF output expansion (RFC 2409, Appendix B) */
348: DBG1(DBG_IKE, "expansion of %N %N output not supported!",
349: transform_type_names, PSEUDO_RANDOM_FUNCTION,
350: pseudo_random_function_names, alg);
351: return FALSE;
352: }
353:
354: if (!dh->get_shared_secret(dh, &g_xy))
355: {
356: return FALSE;
357: }
358: DBG4(DBG_IKE, "shared Diffie Hellman secret %B", &g_xy);
359:
360: *((uint64_t*)spi_i.ptr) = id->get_initiator_spi(id);
361: *((uint64_t*)spi_r.ptr) = id->get_responder_spi(id);
362: nonces = chunk_cata("cc", nonce_i, nonce_r);
363:
364: switch (auth)
365: {
366: case AUTH_PSK:
367: case AUTH_XAUTH_INIT_PSK:
368: case AUTH_XAUTH_RESP_PSK:
369: { /* SKEYID = prf(pre-shared-key, Ni_b | Nr_b) */
370: chunk_t psk;
371: if (!shared_key)
372: {
373: chunk_clear(&g_xy);
374: return FALSE;
375: }
376: psk = shared_key->get_key(shared_key);
377: adjust_keylen(alg, &psk);
378: if (!this->prf->set_key(this->prf, psk) ||
379: !this->prf->allocate_bytes(this->prf, nonces, &skeyid))
380: {
381: chunk_clear(&g_xy);
382: return FALSE;
383: }
384: break;
385: }
386: case AUTH_RSA:
387: case AUTH_ECDSA_256:
388: case AUTH_ECDSA_384:
389: case AUTH_ECDSA_521:
390: case AUTH_XAUTH_INIT_RSA:
391: case AUTH_XAUTH_RESP_RSA:
392: case AUTH_HYBRID_INIT_RSA:
393: case AUTH_HYBRID_RESP_RSA:
394: {
395: if (!this->prf->set_key(this->prf, nonces) ||
396: !this->prf->allocate_bytes(this->prf, g_xy, &skeyid))
397: {
398: chunk_clear(&g_xy);
399: return FALSE;
400: }
401: break;
402: }
403: default:
404: /* TODO-IKEv1: implement key derivation for other schemes */
405: /* authentication class not supported */
406: chunk_clear(&g_xy);
407: return FALSE;
408: }
409: adjust_keylen(alg, &skeyid);
410: DBG4(DBG_IKE, "SKEYID %B", &skeyid);
411:
412: /* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */
413: data = chunk_cat("cccc", g_xy, spi_i, spi_r, octet_0);
414: if (!this->prf->set_key(this->prf, skeyid) ||
415: !this->prf->allocate_bytes(this->prf, data, &this->skeyid_d))
416: {
417: chunk_clear(&g_xy);
418: chunk_clear(&data);
419: chunk_clear(&skeyid);
420: return FALSE;
421: }
422: chunk_clear(&data);
423: DBG4(DBG_IKE, "SKEYID_d %B", &this->skeyid_d);
424:
425: /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */
426: data = chunk_cat("ccccc", this->skeyid_d, g_xy, spi_i, spi_r, octet_1);
427: if (!this->prf->allocate_bytes(this->prf, data, &this->skeyid_a))
428: {
429: chunk_clear(&g_xy);
430: chunk_clear(&data);
431: chunk_clear(&skeyid);
432: return FALSE;
433: }
434: chunk_clear(&data);
435: DBG4(DBG_IKE, "SKEYID_a %B", &this->skeyid_a);
436:
437: /* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */
438: data = chunk_cat("ccccc", this->skeyid_a, g_xy, spi_i, spi_r, octet_2);
439: if (!this->prf->allocate_bytes(this->prf, data, &skeyid_e))
440: {
441: chunk_clear(&g_xy);
442: chunk_clear(&data);
443: chunk_clear(&skeyid);
444: return FALSE;
445: }
446: chunk_clear(&data);
447: DBG4(DBG_IKE, "SKEYID_e %B", &skeyid_e);
448:
449: chunk_clear(&g_xy);
450:
451: switch (auth)
452: {
453: case AUTH_ECDSA_256:
454: alg = PRF_HMAC_SHA2_256;
455: break;
456: case AUTH_ECDSA_384:
457: alg = PRF_HMAC_SHA2_384;
458: break;
459: case AUTH_ECDSA_521:
460: alg = PRF_HMAC_SHA2_512;
461: break;
462: default:
463: /* use proposal algorithm */
464: break;
465: }
466: this->prf_auth = lib->crypto->create_prf(lib->crypto, alg);
467: if (!this->prf_auth)
468: {
469: DBG1(DBG_IKE, "%N %N not supported!",
470: transform_type_names, PSEUDO_RANDOM_FUNCTION,
471: pseudo_random_function_names, alg);
472: chunk_clear(&skeyid);
473: return FALSE;
474: }
475: if (!this->prf_auth->set_key(this->prf_auth, skeyid))
476: {
477: chunk_clear(&skeyid);
478: return FALSE;
479: }
480: chunk_clear(&skeyid);
481:
482: this->aead = create_aead(proposal, this->prf, skeyid_e, &ka);
483: if (!this->aead)
484: {
485: return FALSE;
486: }
487: charon->bus->ike_derived_keys(charon->bus, ka, chunk_empty, this->skeyid_a,
488: chunk_empty);
489: chunk_clear(&ka);
490: if (!this->hasher && !this->public.create_hasher(&this->public, proposal))
491: {
492: return FALSE;
493: }
494:
495: if (!dh->get_my_public_value(dh, &dh_me))
496: {
497: return FALSE;
498: }
499: g_xi = this->initiator ? dh_me : dh_other;
500: g_xr = this->initiator ? dh_other : dh_me;
501:
502: /* initial IV = hash(g^xi | g^xr) */
503: data = chunk_cata("cc", g_xi, g_xr);
504: chunk_free(&dh_me);
505: return this->iv_manager->init_iv_chain(this->iv_manager, data, this->hasher,
506: this->aead->get_block_size(this->aead));
507: }
508:
509: METHOD(keymat_v1_t, derive_child_keys, bool,
510: private_keymat_v1_t *this, proposal_t *proposal, diffie_hellman_t *dh,
511: uint32_t spi_i, uint32_t spi_r, chunk_t nonce_i, chunk_t nonce_r,
512: chunk_t *encr_i, chunk_t *integ_i, chunk_t *encr_r, chunk_t *integ_r)
513: {
514: uint16_t enc_alg, int_alg, enc_size = 0, int_size = 0;
515: uint8_t protocol;
516: prf_plus_t *prf_plus;
517: chunk_t seed, secret = chunk_empty;
518: bool success = FALSE;
519:
520: if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM,
521: &enc_alg, &enc_size))
522: {
523: DBG2(DBG_CHD, " using %N for encryption",
524: encryption_algorithm_names, enc_alg);
525:
526: if (!enc_size)
527: {
528: enc_size = keymat_get_keylen_encr(enc_alg);
529: }
530: if (enc_alg != ENCR_NULL && !enc_size)
531: {
532: DBG1(DBG_CHD, "no keylength defined for %N",
533: encryption_algorithm_names, enc_alg);
534: return FALSE;
535: }
536: /* to bytes */
537: enc_size /= 8;
538:
539: /* CCM/GCM/CTR/GMAC needs additional bytes */
540: switch (enc_alg)
541: {
542: case ENCR_AES_CCM_ICV8:
543: case ENCR_AES_CCM_ICV12:
544: case ENCR_AES_CCM_ICV16:
545: case ENCR_CAMELLIA_CCM_ICV8:
546: case ENCR_CAMELLIA_CCM_ICV12:
547: case ENCR_CAMELLIA_CCM_ICV16:
548: enc_size += 3;
549: break;
550: case ENCR_AES_GCM_ICV8:
551: case ENCR_AES_GCM_ICV12:
552: case ENCR_AES_GCM_ICV16:
553: case ENCR_AES_CTR:
554: case ENCR_NULL_AUTH_AES_GMAC:
555: enc_size += 4;
556: break;
557: default:
558: break;
559: }
560: }
561:
562: if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM,
563: &int_alg, &int_size))
564: {
565: DBG2(DBG_CHD, " using %N for integrity",
566: integrity_algorithm_names, int_alg);
567:
568: if (!int_size)
569: {
570: int_size = keymat_get_keylen_integ(int_alg);
571: }
572: if (!int_size)
573: {
574: DBG1(DBG_CHD, "no keylength defined for %N",
575: integrity_algorithm_names, int_alg);
576: return FALSE;
577: }
578: /* to bytes */
579: int_size /= 8;
580: }
581:
582: /* KEYMAT = prf+(SKEYID_d, [ g(qm)^xy | ] protocol | SPI | Ni_b | Nr_b) */
583: if (!this->prf->set_key(this->prf, this->skeyid_d))
584: {
585: return FALSE;
586: }
587: protocol = proposal->get_protocol(proposal);
588: if (dh)
589: {
590: if (!dh->get_shared_secret(dh, &secret))
591: {
592: return FALSE;
593: }
594: DBG4(DBG_CHD, "DH secret %B", &secret);
595: }
596:
597: *encr_r = *integ_r = *encr_i = *integ_i = chunk_empty;
598: seed = chunk_cata("ccccc", secret, chunk_from_thing(protocol),
599: chunk_from_thing(spi_r), nonce_i, nonce_r);
600: DBG4(DBG_CHD, "initiator SA seed %B", &seed);
601:
602: prf_plus = prf_plus_create(this->prf, FALSE, seed);
603: if (!prf_plus ||
604: !prf_plus->allocate_bytes(prf_plus, enc_size, encr_i) ||
605: !prf_plus->allocate_bytes(prf_plus, int_size, integ_i))
606: {
607: goto failure;
608: }
609:
610: seed = chunk_cata("ccccc", secret, chunk_from_thing(protocol),
611: chunk_from_thing(spi_i), nonce_i, nonce_r);
612: DBG4(DBG_CHD, "responder SA seed %B", &seed);
613: prf_plus->destroy(prf_plus);
614: prf_plus = prf_plus_create(this->prf, FALSE, seed);
615: if (!prf_plus ||
616: !prf_plus->allocate_bytes(prf_plus, enc_size, encr_r) ||
617: !prf_plus->allocate_bytes(prf_plus, int_size, integ_r))
618: {
619: goto failure;
620: }
621:
622: if (enc_size)
623: {
624: DBG4(DBG_CHD, "encryption initiator key %B", encr_i);
625: DBG4(DBG_CHD, "encryption responder key %B", encr_r);
626: }
627: if (int_size)
628: {
629: DBG4(DBG_CHD, "integrity initiator key %B", integ_i);
630: DBG4(DBG_CHD, "integrity responder key %B", integ_r);
631: }
632: success = TRUE;
633:
634: failure:
635: if (!success)
636: {
637: chunk_clear(encr_i);
638: chunk_clear(integ_i);
639: chunk_clear(encr_r);
640: chunk_clear(integ_r);
641: }
642: DESTROY_IF(prf_plus);
643: chunk_clear(&secret);
644:
645: return success;
646: }
647:
648: METHOD(keymat_v1_t, create_hasher, bool,
649: private_keymat_v1_t *this, proposal_t *proposal)
650: {
651: uint16_t alg;
652: if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &alg, NULL) ||
653: (alg = auth_to_hash(alg)) == HASH_UNKNOWN)
654: {
655: DBG1(DBG_IKE, "no %N selected", transform_type_names, HASH_ALGORITHM);
656: return FALSE;
657: }
658: this->hasher = lib->crypto->create_hasher(lib->crypto, alg);
659: if (!this->hasher)
660: {
661: DBG1(DBG_IKE, "%N %N not supported!",
662: transform_type_names, HASH_ALGORITHM,
663: hash_algorithm_names, alg);
664: return FALSE;
665: }
666: return TRUE;
667: }
668:
669: METHOD(keymat_v1_t, get_hasher, hasher_t*,
670: private_keymat_v1_t *this)
671: {
672: return this->hasher;
673: }
674:
675: METHOD(keymat_v1_t, get_hash, bool,
676: private_keymat_v1_t *this, bool initiator, chunk_t dh, chunk_t dh_other,
677: ike_sa_id_t *ike_sa_id, chunk_t sa_i, chunk_t id, chunk_t *hash,
678: signature_scheme_t *scheme)
679: {
680: chunk_t data;
681: uint64_t spi, spi_other;
682:
683: /* HASH_I = prf(SKEYID, g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b )
684: * HASH_R = prf(SKEYID, g^xr | g^xi | CKY-R | CKY-I | SAi_b | IDir_b )
685: */
686: if (initiator)
687: {
688: spi = ike_sa_id->get_initiator_spi(ike_sa_id);
689: spi_other = ike_sa_id->get_responder_spi(ike_sa_id);
690: }
691: else
692: {
693: spi_other = ike_sa_id->get_initiator_spi(ike_sa_id);
694: spi = ike_sa_id->get_responder_spi(ike_sa_id);
695: }
696: data = chunk_cat("cccccc", dh, dh_other,
697: chunk_from_thing(spi), chunk_from_thing(spi_other),
698: sa_i, id);
699:
700: DBG3(DBG_IKE, "HASH_%c data %B", initiator ? 'I' : 'R', &data);
701:
702: if (!this->prf_auth->allocate_bytes(this->prf_auth, data, hash))
703: {
704: free(data.ptr);
705: return FALSE;
706: }
707:
708: DBG3(DBG_IKE, "HASH_%c %B", initiator ? 'I' : 'R', hash);
709:
710: free(data.ptr);
711: return TRUE;
712: }
713:
714: /**
715: * Get the nonce value found in the given message.
716: * Returns FALSE if none is found.
717: */
718: static bool get_nonce(message_t *message, chunk_t *n)
719: {
720: nonce_payload_t *nonce;
721: nonce = (nonce_payload_t*)message->get_payload(message, PLV1_NONCE);
722: if (nonce)
723: {
724: *n = nonce->get_nonce(nonce);
725: return TRUE;
726: }
727: return FALSE;
728: }
729:
730: /**
731: * Generate the message data in order to generate the hashes.
732: */
733: static chunk_t get_message_data(message_t *message, generator_t *generator)
734: {
735: payload_t *payload, *next;
736: enumerator_t *enumerator;
737: uint32_t *lenpos;
738:
739: if (message->is_encoded(message))
740: { /* inbound, although the message is generated, we cannot access the
741: * cleartext message data, so generate it anyway */
742: enumerator = message->create_payload_enumerator(message);
743: while (enumerator->enumerate(enumerator, &payload))
744: {
745: if (payload->get_type(payload) == PLV1_HASH)
746: {
747: continue;
748: }
749: generator->generate_payload(generator, payload);
750: }
751: enumerator->destroy(enumerator);
752: }
753: else
754: {
755: /* outbound, generate the payloads (there is no HASH payload yet) */
756: enumerator = message->create_payload_enumerator(message);
757: if (enumerator->enumerate(enumerator, &payload))
758: {
759: while (enumerator->enumerate(enumerator, &next))
760: {
761: payload->set_next_type(payload, next->get_type(next));
762: generator->generate_payload(generator, payload);
763: payload = next;
764: }
765: payload->set_next_type(payload, PL_NONE);
766: generator->generate_payload(generator, payload);
767: }
768: enumerator->destroy(enumerator);
769: }
770: return generator->get_chunk(generator, &lenpos);
771: }
772:
773: METHOD(keymat_v1_t, get_hash_phase2, bool,
774: private_keymat_v1_t *this, message_t *message, chunk_t *hash)
775: {
776: uint32_t mid, mid_n;
777: chunk_t data = chunk_empty, *n_i, *n_r;
778: bool add_message = TRUE;
779: char *name = "Hash";
780:
781: if (!this->prf)
782: { /* no keys derived yet */
783: return FALSE;
784: }
785:
786: mid = message->get_message_id(message);
787: mid_n = htonl(mid);
788:
789: /* Hashes are simple for most exchanges in Phase 2:
790: * Hash = prf(SKEYID_a, M-ID | Complete message after HASH payload)
791: * For Quick Mode there are three hashes:
792: * Hash(1) = same as above
793: * Hash(2) = prf(SKEYID_a, M-ID | Ni_b | Message after HASH payload)
794: * Hash(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b)
795: * So, for Quick Mode we keep track of the nonce values.
796: */
797: switch (message->get_exchange_type(message))
798: {
799: case QUICK_MODE:
800: {
801: this->iv_manager->lookup_quick_mode(this->iv_manager, mid, &n_i,
802: &n_r);
803: if (!n_i->ptr)
804: { /* Hash(1) = prf(SKEYID_a, M-ID | Message after HASH payload) */
805: name = "Hash(1)";
806: if (!get_nonce(message, n_i))
807: {
808: return FALSE;
809: }
810: data = chunk_from_thing(mid_n);
811: }
812: else if (!n_r->ptr)
813: { /* Hash(2) = prf(SKEYID_a, M-ID | Ni_b | Message after HASH) */
814: name = "Hash(2)";
815: if (!get_nonce(message, n_r))
816: {
817: return FALSE;
818: }
819: data = chunk_cata("cc", chunk_from_thing(mid_n), *n_i);
820: }
821: else
822: { /* Hash(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */
823: name = "Hash(3)";
824: data = chunk_cata("cccc", octet_0, chunk_from_thing(mid_n),
825: *n_i, *n_r);
826: add_message = FALSE;
827: /* we don't need the state anymore */
828: this->iv_manager->remove_quick_mode(this->iv_manager, mid);
829: }
830: break;
831: }
832: case TRANSACTION:
833: case INFORMATIONAL_V1:
834: /* Hash = prf(SKEYID_a, M-ID | Message after HASH payload) */
835: data = chunk_from_thing(mid_n);
836: break;
837: default:
838: return FALSE;
839: }
840: if (!this->prf->set_key(this->prf, this->skeyid_a))
841: {
842: return FALSE;
843: }
844: if (add_message)
845: {
846: generator_t *generator;
847: chunk_t msg;
848:
849: generator = generator_create_no_dbg();
850: msg = get_message_data(message, generator);
851: if (!this->prf->allocate_bytes(this->prf, data, NULL) ||
852: !this->prf->allocate_bytes(this->prf, msg, hash))
853: {
854: generator->destroy(generator);
855: return FALSE;
856: }
857: generator->destroy(generator);
858: }
859: else
860: {
861: if (!this->prf->allocate_bytes(this->prf, data, hash))
862: {
863: return FALSE;
864: }
865: }
866: DBG3(DBG_IKE, "%s %B", name, hash);
867: return TRUE;
868: }
869:
870: METHOD(keymat_v1_t, get_iv, bool,
871: private_keymat_v1_t *this, uint32_t mid, chunk_t *out)
872: {
873: return this->iv_manager->get_iv(this->iv_manager, mid, out);
874: }
875:
876: METHOD(keymat_v1_t, update_iv, bool,
877: private_keymat_v1_t *this, uint32_t mid, chunk_t last_block)
878: {
879: return this->iv_manager->update_iv(this->iv_manager, mid, last_block);
880: }
881:
882: METHOD(keymat_v1_t, confirm_iv, bool,
883: private_keymat_v1_t *this, uint32_t mid)
884: {
885: return this->iv_manager->confirm_iv(this->iv_manager, mid);
886: }
887:
888: METHOD(keymat_t, get_version, ike_version_t,
889: private_keymat_v1_t *this)
890: {
891: return IKEV1;
892: }
893:
894: METHOD(keymat_t, create_dh, diffie_hellman_t*,
895: private_keymat_v1_t *this, diffie_hellman_group_t group)
896: {
897: return lib->crypto->create_dh(lib->crypto, group);
898: }
899:
900: METHOD(keymat_t, create_nonce_gen, nonce_gen_t*,
901: private_keymat_v1_t *this)
902: {
903: return lib->crypto->create_nonce_gen(lib->crypto);
904: }
905:
906: METHOD(keymat_t, get_aead, aead_t*,
907: private_keymat_v1_t *this, bool in)
908: {
909: return this->aead;
910: }
911:
912: METHOD(keymat_t, destroy, void,
913: private_keymat_v1_t *this)
914: {
915: DESTROY_IF(this->prf);
916: DESTROY_IF(this->prf_auth);
917: DESTROY_IF(this->aead);
918: DESTROY_IF(this->hasher);
919: chunk_clear(&this->skeyid_d);
920: chunk_clear(&this->skeyid_a);
921: this->iv_manager->destroy(this->iv_manager);
922: free(this);
923: }
924:
925: /**
926: * See header
927: */
928: keymat_v1_t *keymat_v1_create(bool initiator)
929: {
930: private_keymat_v1_t *this;
931:
932: INIT(this,
933: .public = {
934: .keymat = {
935: .get_version = _get_version,
936: .create_dh = _create_dh,
937: .create_nonce_gen = _create_nonce_gen,
938: .get_aead = _get_aead,
939: .destroy = _destroy,
940: },
941: .derive_ike_keys = _derive_ike_keys,
942: .derive_child_keys = _derive_child_keys,
943: .create_hasher = _create_hasher,
944: .get_hasher = _get_hasher,
945: .get_hash = _get_hash,
946: .get_hash_phase2 = _get_hash_phase2,
947: .get_iv = _get_iv,
948: .update_iv = _update_iv,
949: .confirm_iv = _confirm_iv,
950: },
951: .initiator = initiator,
952: .iv_manager = iv_manager_create(0),
953: );
954: return &this->public;
955: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>