Annotation of embedaddon/strongswan/src/libcharon/sa/ikev2/keymat_v2.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2015 Tobias Brunner
3: * Copyright (C) 2008 Martin Willi
4: * HSR Hochschule fuer Technik Rapperswil
5: *
6: * This program is free software; you can redistribute it and/or modify it
7: * under the terms of the GNU General Public License as published by the
8: * Free Software Foundation; either version 2 of the License, or (at your
9: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10: *
11: * This program is distributed in the hope that it will be useful, but
12: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14: * for more details.
15: */
16:
17: #include "keymat_v2.h"
18:
19: #include <daemon.h>
20: #include <crypto/prf_plus.h>
21: #include <crypto/hashers/hash_algorithm_set.h>
22:
23: typedef struct private_keymat_v2_t private_keymat_v2_t;
24:
25: /**
26: * Private data of an keymat_t object.
27: */
28: struct private_keymat_v2_t {
29:
30: /**
31: * Public keymat_v2_t interface.
32: */
33: keymat_v2_t public;
34:
35: /**
36: * IKE_SA Role, initiator or responder
37: */
38: bool initiator;
39:
40: /**
41: * inbound AEAD
42: */
43: aead_t *aead_in;
44:
45: /**
46: * outbound AEAD
47: */
48: aead_t *aead_out;
49:
50: /**
51: * General purpose PRF
52: */
53: prf_t *prf;
54:
55: /**
56: * Negotiated PRF algorithm
57: */
58: pseudo_random_function_t prf_alg;
59:
60: /**
61: * Key to derive key material from for CHILD_SAs, rekeying
62: */
63: chunk_t skd;
64:
65: /**
66: * Key to build outgoing authentication data (SKp)
67: */
68: chunk_t skp_build;
69:
70: /**
71: * Key to verify incoming authentication data (SKp)
72: */
73: chunk_t skp_verify;
74:
75: /**
76: * Set of hash algorithms supported by peer for signature authentication
77: */
78: hash_algorithm_set_t *hash_algorithms;
79: };
80:
81: METHOD(keymat_t, get_version, ike_version_t,
82: private_keymat_v2_t *this)
83: {
84: return IKEV2;
85: }
86:
87: METHOD(keymat_t, create_dh, diffie_hellman_t*,
88: private_keymat_v2_t *this, diffie_hellman_group_t group)
89: {
90: return lib->crypto->create_dh(lib->crypto, group);
91: }
92:
93: METHOD(keymat_t, create_nonce_gen, nonce_gen_t*,
94: private_keymat_v2_t *this)
95: {
96: return lib->crypto->create_nonce_gen(lib->crypto);
97: }
98:
99: /**
100: * Derive IKE keys for a combined AEAD algorithm
101: */
102: static bool derive_ike_aead(private_keymat_v2_t *this, uint16_t alg,
103: uint16_t key_size, prf_plus_t *prf_plus)
104: {
105: aead_t *aead_i, *aead_r;
106: chunk_t sk_ei = chunk_empty, sk_er = chunk_empty;
107: u_int salt_size;
108:
109: switch (alg)
110: {
111: case ENCR_AES_GCM_ICV8:
112: case ENCR_AES_GCM_ICV12:
113: case ENCR_AES_GCM_ICV16:
114: /* RFC 4106 */
115: case ENCR_CHACHA20_POLY1305:
116: salt_size = 4;
117: break;
118: case ENCR_AES_CCM_ICV8:
119: case ENCR_AES_CCM_ICV12:
120: case ENCR_AES_CCM_ICV16:
121: /* RFC 4309 */
122: case ENCR_CAMELLIA_CCM_ICV8:
123: case ENCR_CAMELLIA_CCM_ICV12:
124: case ENCR_CAMELLIA_CCM_ICV16:
125: /* RFC 5529 */
126: salt_size = 3;
127: break;
128: default:
129: DBG1(DBG_IKE, "nonce size for %N unknown!",
130: encryption_algorithm_names, alg);
131: return FALSE;
132: }
133:
134: /* SK_ei/SK_er used for encryption */
135: aead_i = lib->crypto->create_aead(lib->crypto, alg, key_size / 8, salt_size);
136: aead_r = lib->crypto->create_aead(lib->crypto, alg, key_size / 8, salt_size);
137: if (aead_i == NULL || aead_r == NULL)
138: {
139: DBG1(DBG_IKE, "%N %N (key size %d) not supported!",
140: transform_type_names, ENCRYPTION_ALGORITHM,
141: encryption_algorithm_names, alg, key_size);
142: goto failure;
143: }
144: key_size = aead_i->get_key_size(aead_i);
145: if (key_size != aead_r->get_key_size(aead_r))
146: {
147: goto failure;
148: }
149: if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_ei))
150: {
151: goto failure;
152: }
153: DBG4(DBG_IKE, "Sk_ei secret %B", &sk_ei);
154: if (!aead_i->set_key(aead_i, sk_ei))
155: {
156: goto failure;
157: }
158:
159: if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_er))
160: {
161: goto failure;
162: }
163: DBG4(DBG_IKE, "Sk_er secret %B", &sk_er);
164: if (!aead_r->set_key(aead_r, sk_er))
165: {
166: goto failure;
167: }
168:
169: if (this->initiator)
170: {
171: this->aead_in = aead_r;
172: this->aead_out = aead_i;
173: }
174: else
175: {
176: this->aead_in = aead_i;
177: this->aead_out = aead_r;
178: }
179: aead_i = aead_r = NULL;
180: charon->bus->ike_derived_keys(charon->bus, sk_ei, sk_er, chunk_empty,
181: chunk_empty);
182:
183: failure:
184: DESTROY_IF(aead_i);
185: DESTROY_IF(aead_r);
186: chunk_clear(&sk_ei);
187: chunk_clear(&sk_er);
188: return this->aead_in && this->aead_out;
189: }
190:
191: /**
192: * Derive IKE keys for traditional encryption and MAC algorithms
193: */
194: static bool derive_ike_traditional(private_keymat_v2_t *this, uint16_t enc_alg,
195: uint16_t enc_size, uint16_t int_alg, prf_plus_t *prf_plus)
196: {
197: crypter_t *crypter_i = NULL, *crypter_r = NULL;
198: signer_t *signer_i, *signer_r;
199: iv_gen_t *ivg_i, *ivg_r;
200: size_t key_size;
201: chunk_t sk_ei = chunk_empty, sk_er = chunk_empty,
202: sk_ai = chunk_empty, sk_ar = chunk_empty;
203:
204: signer_i = lib->crypto->create_signer(lib->crypto, int_alg);
205: signer_r = lib->crypto->create_signer(lib->crypto, int_alg);
206: crypter_i = lib->crypto->create_crypter(lib->crypto, enc_alg, enc_size / 8);
207: crypter_r = lib->crypto->create_crypter(lib->crypto, enc_alg, enc_size / 8);
208: if (signer_i == NULL || signer_r == NULL)
209: {
210: DBG1(DBG_IKE, "%N %N not supported!",
211: transform_type_names, INTEGRITY_ALGORITHM,
212: integrity_algorithm_names, int_alg);
213: goto failure;
214: }
215: if (crypter_i == NULL || crypter_r == NULL)
216: {
217: DBG1(DBG_IKE, "%N %N (key size %d) not supported!",
218: transform_type_names, ENCRYPTION_ALGORITHM,
219: encryption_algorithm_names, enc_alg, enc_size);
220: goto failure;
221: }
222:
223: /* SK_ai/SK_ar used for integrity protection */
224: key_size = signer_i->get_key_size(signer_i);
225:
226: if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_ai))
227: {
228: goto failure;
229: }
230: DBG4(DBG_IKE, "Sk_ai secret %B", &sk_ai);
231: if (!signer_i->set_key(signer_i, sk_ai))
232: {
233: goto failure;
234: }
235:
236: if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_ar))
237: {
238: goto failure;
239: }
240: DBG4(DBG_IKE, "Sk_ar secret %B", &sk_ar);
241: if (!signer_r->set_key(signer_r, sk_ar))
242: {
243: goto failure;
244: }
245:
246: /* SK_ei/SK_er used for encryption */
247: key_size = crypter_i->get_key_size(crypter_i);
248:
249: if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_ei))
250: {
251: goto failure;
252: }
253: DBG4(DBG_IKE, "Sk_ei secret %B", &sk_ei);
254: if (!crypter_i->set_key(crypter_i, sk_ei))
255: {
256: goto failure;
257: }
258:
259: if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_er))
260: {
261: goto failure;
262: }
263: DBG4(DBG_IKE, "Sk_er secret %B", &sk_er);
264: if (!crypter_r->set_key(crypter_r, sk_er))
265: {
266: goto failure;
267: }
268:
269: ivg_i = iv_gen_create_for_alg(enc_alg);
270: ivg_r = iv_gen_create_for_alg(enc_alg);
271: if (!ivg_i || !ivg_r)
272: {
273: goto failure;
274: }
275: if (this->initiator)
276: {
277: this->aead_in = aead_create(crypter_r, signer_r, ivg_r);
278: this->aead_out = aead_create(crypter_i, signer_i, ivg_i);
279: }
280: else
281: {
282: this->aead_in = aead_create(crypter_i, signer_i, ivg_i);
283: this->aead_out = aead_create(crypter_r, signer_r, ivg_r);
284: }
285: signer_i = signer_r = NULL;
286: crypter_i = crypter_r = NULL;
287: charon->bus->ike_derived_keys(charon->bus, sk_ei, sk_er, sk_ai, sk_ar);
288:
289: failure:
290: chunk_clear(&sk_ai);
291: chunk_clear(&sk_ar);
292: chunk_clear(&sk_ei);
293: chunk_clear(&sk_er);
294: DESTROY_IF(signer_i);
295: DESTROY_IF(signer_r);
296: DESTROY_IF(crypter_i);
297: DESTROY_IF(crypter_r);
298: return this->aead_in && this->aead_out;
299: }
300:
301: METHOD(keymat_v2_t, derive_ike_keys, bool,
302: private_keymat_v2_t *this, proposal_t *proposal, diffie_hellman_t *dh,
303: chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id,
304: pseudo_random_function_t rekey_function, chunk_t rekey_skd)
305: {
306: chunk_t skeyseed = chunk_empty, key, secret, full_nonce, fixed_nonce;
307: chunk_t prf_plus_seed, spi_i, spi_r;
308: prf_plus_t *prf_plus = NULL;
309: uint16_t alg, key_size, int_alg;
310: prf_t *rekey_prf = NULL;
311:
312: spi_i = chunk_alloca(sizeof(uint64_t));
313: spi_r = chunk_alloca(sizeof(uint64_t));
314:
315: if (!dh->get_shared_secret(dh, &secret))
316: {
317: return FALSE;
318: }
319:
320: /* Create SAs general purpose PRF first, we may use it here */
321: if (!proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &alg, NULL))
322: {
323: DBG1(DBG_IKE, "no %N selected",
324: transform_type_names, PSEUDO_RANDOM_FUNCTION);
325: chunk_clear(&secret);
326: return FALSE;
327: }
328: this->prf_alg = alg;
329: this->prf = lib->crypto->create_prf(lib->crypto, alg);
330: if (this->prf == NULL)
331: {
332: DBG1(DBG_IKE, "%N %N not supported!",
333: transform_type_names, PSEUDO_RANDOM_FUNCTION,
334: pseudo_random_function_names, alg);
335: chunk_clear(&secret);
336: return FALSE;
337: }
338: DBG4(DBG_IKE, "shared Diffie Hellman secret %B", &secret);
339: /* full nonce is used as seed for PRF+ ... */
340: full_nonce = chunk_cat("cc", nonce_i, nonce_r);
341: /* but the PRF may need a fixed key which only uses the first bytes of
342: * the nonces. */
343: switch (alg)
344: {
345: case PRF_AES128_CMAC:
346: /* while variable keys may be used according to RFC 4615, RFC 7296
347: * explicitly limits the key size to 128 bit for this application */
348: case PRF_AES128_XCBC:
349: /* while RFC 4434 defines variable keys for AES-XCBC, RFC 3664 does
350: * not and therefore fixed key semantics apply to XCBC for key
351: * derivation, which is also reinforced by RFC 7296 */
352: case PRF_CAMELLIA128_XCBC:
353: /* draft-kanno-ipsecme-camellia-xcbc refers to rfc 4434, we
354: * assume fixed key length. */
355: key_size = this->prf->get_key_size(this->prf)/2;
356: nonce_i.len = min(nonce_i.len, key_size);
357: nonce_r.len = min(nonce_r.len, key_size);
358: break;
359: default:
360: /* all other algorithms use variable key length, full nonce */
361: break;
362: }
363: fixed_nonce = chunk_cat("cc", nonce_i, nonce_r);
364: *((uint64_t*)spi_i.ptr) = id->get_initiator_spi(id);
365: *((uint64_t*)spi_r.ptr) = id->get_responder_spi(id);
366: prf_plus_seed = chunk_cat("ccc", full_nonce, spi_i, spi_r);
367:
368: /* KEYMAT = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr)
369: *
370: * if we are rekeying, SKEYSEED is built on another way
371: */
372: if (rekey_function == PRF_UNDEFINED) /* not rekeying */
373: {
374: /* SKEYSEED = prf(Ni | Nr, g^ir) */
375: if (this->prf->set_key(this->prf, fixed_nonce) &&
376: this->prf->allocate_bytes(this->prf, secret, &skeyseed) &&
377: this->prf->set_key(this->prf, skeyseed))
378: {
379: prf_plus = prf_plus_create(this->prf, TRUE, prf_plus_seed);
380: }
381: }
382: else
383: {
384: /* SKEYSEED = prf(SK_d (old), [g^ir (new)] | Ni | Nr)
385: * use OLD SAs PRF functions for both prf_plus and prf */
386: rekey_prf = lib->crypto->create_prf(lib->crypto, rekey_function);
387: if (!rekey_prf)
388: {
389: DBG1(DBG_IKE, "PRF of old SA %N not supported!",
390: pseudo_random_function_names, rekey_function);
391: chunk_clear(&secret);
392: chunk_free(&full_nonce);
393: chunk_free(&fixed_nonce);
394: chunk_clear(&prf_plus_seed);
395: return FALSE;
396: }
397: secret = chunk_cat("mc", secret, full_nonce);
398: if (rekey_prf->set_key(rekey_prf, rekey_skd) &&
399: rekey_prf->allocate_bytes(rekey_prf, secret, &skeyseed) &&
400: rekey_prf->set_key(rekey_prf, skeyseed))
401: {
402: prf_plus = prf_plus_create(rekey_prf, TRUE, prf_plus_seed);
403: }
404: }
405: DBG4(DBG_IKE, "SKEYSEED %B", &skeyseed);
406:
407: chunk_clear(&skeyseed);
408: chunk_clear(&secret);
409: chunk_free(&full_nonce);
410: chunk_free(&fixed_nonce);
411: chunk_clear(&prf_plus_seed);
412:
413: if (!prf_plus)
414: {
415: goto failure;
416: }
417:
418: /* KEYMAT = SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr */
419:
420: /* SK_d is used for generating CHILD_SA key mat => store for later use */
421: key_size = this->prf->get_key_size(this->prf);
422: if (!prf_plus->allocate_bytes(prf_plus, key_size, &this->skd))
423: {
424: goto failure;
425: }
426: DBG4(DBG_IKE, "Sk_d secret %B", &this->skd);
427:
428: if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &alg, &key_size))
429: {
430: DBG1(DBG_IKE, "no %N selected",
431: transform_type_names, ENCRYPTION_ALGORITHM);
432: goto failure;
433: }
434:
435: if (encryption_algorithm_is_aead(alg))
436: {
437: if (!derive_ike_aead(this, alg, key_size, prf_plus))
438: {
439: goto failure;
440: }
441: }
442: else
443: {
444: if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM,
445: &int_alg, NULL))
446: {
447: DBG1(DBG_IKE, "no %N selected",
448: transform_type_names, INTEGRITY_ALGORITHM);
449: goto failure;
450: }
451: if (!derive_ike_traditional(this, alg, key_size, int_alg, prf_plus))
452: {
453: goto failure;
454: }
455: }
456:
457: /* SK_pi/SK_pr used for authentication => stored for later */
458: key_size = this->prf->get_key_size(this->prf);
459: if (!prf_plus->allocate_bytes(prf_plus, key_size, &key))
460: {
461: goto failure;
462: }
463: DBG4(DBG_IKE, "Sk_pi secret %B", &key);
464: if (this->initiator)
465: {
466: this->skp_build = key;
467: }
468: else
469: {
470: this->skp_verify = key;
471: }
472: if (!prf_plus->allocate_bytes(prf_plus, key_size, &key))
473: {
474: goto failure;
475: }
476: DBG4(DBG_IKE, "Sk_pr secret %B", &key);
477: if (this->initiator)
478: {
479: this->skp_verify = key;
480: }
481: else
482: {
483: this->skp_build = key;
484: }
485:
486: /* all done, prf_plus not needed anymore */
487: failure:
488: DESTROY_IF(prf_plus);
489: DESTROY_IF(rekey_prf);
490:
491: return this->skp_build.len && this->skp_verify.len;
492: }
493:
494: /**
495: * Derives a key from the given key and a PRF that was initialized with a PPK
496: */
497: static bool derive_ppk_key(prf_t *prf, char *name, chunk_t key,
498: chunk_t *new_key)
499: {
500: prf_plus_t *prf_plus;
501:
502: prf_plus = prf_plus_create(prf, TRUE, key);
503: if (!prf_plus ||
504: !prf_plus->allocate_bytes(prf_plus, key.len, new_key))
505: {
506: DBG1(DBG_IKE, "unable to derive %s with PPK", name);
507: DESTROY_IF(prf_plus);
508: return FALSE;
509: }
510: prf_plus->destroy(prf_plus);
511: return TRUE;
512: }
513:
514: /**
515: * Use the given PPK to derive a new SK_pi/r
516: */
517: static bool derive_skp_ppk(private_keymat_v2_t *this, chunk_t ppk, chunk_t skp,
518: chunk_t *new_skp)
519: {
520: if (!this->prf->set_key(this->prf, ppk))
521: {
522: DBG1(DBG_IKE, "unable to set PPK in PRF");
523: return FALSE;
524: }
525: return derive_ppk_key(this->prf, "SK_p", skp, new_skp);
526: }
527:
528: METHOD(keymat_v2_t, derive_ike_keys_ppk, bool,
529: private_keymat_v2_t *this, chunk_t ppk)
530: {
531: chunk_t skd = chunk_empty, new_skpi = chunk_empty, new_skpr = chunk_empty;
532: chunk_t *skpi, *skpr;
533:
534: if (!this->skd.ptr)
535: {
536: return FALSE;
537: }
538:
539: if (this->initiator)
540: {
541: skpi = &this->skp_build;
542: skpr = &this->skp_verify;
543: }
544: else
545: {
546: skpi = &this->skp_verify;
547: skpr = &this->skp_build;
548: }
549:
550: DBG4(DBG_IKE, "derive keys using PPK %B", &ppk);
551:
552: if (!this->prf->set_key(this->prf, ppk))
553: {
554: DBG1(DBG_IKE, "unable to set PPK in PRF");
555: return FALSE;
556: }
557: if (!derive_ppk_key(this->prf, "Sk_d", this->skd, &skd) ||
558: !derive_ppk_key(this->prf, "Sk_pi", *skpi, &new_skpi) ||
559: !derive_ppk_key(this->prf, "Sk_pr", *skpr, &new_skpr))
560: {
561: chunk_clear(&skd);
562: chunk_clear(&new_skpi);
563: chunk_clear(&new_skpr);
564: return FALSE;
565: }
566:
567: DBG4(DBG_IKE, "Sk_d secret %B", &skd);
568: chunk_clear(&this->skd);
569: this->skd = skd;
570:
571: DBG4(DBG_IKE, "Sk_pi secret %B", &new_skpi);
572: chunk_clear(skpi);
573: *skpi = new_skpi;
574:
575: DBG4(DBG_IKE, "Sk_pr secret %B", &new_skpr);
576: chunk_clear(skpr);
577: *skpr = new_skpr;
578: return TRUE;
579: }
580:
581: METHOD(keymat_v2_t, derive_child_keys, bool,
582: private_keymat_v2_t *this, proposal_t *proposal, diffie_hellman_t *dh,
583: chunk_t nonce_i, chunk_t nonce_r, chunk_t *encr_i, chunk_t *integ_i,
584: chunk_t *encr_r, chunk_t *integ_r)
585: {
586: uint16_t enc_alg, int_alg, enc_size = 0, int_size = 0;
587: chunk_t seed, secret = chunk_empty;
588: prf_plus_t *prf_plus;
589:
590: if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM,
591: &enc_alg, &enc_size))
592: {
593: DBG2(DBG_CHD, " using %N for encryption",
594: encryption_algorithm_names, enc_alg);
595:
596: if (!enc_size)
597: {
598: enc_size = keymat_get_keylen_encr(enc_alg);
599: }
600: if (enc_alg != ENCR_NULL && !enc_size)
601: {
602: DBG1(DBG_CHD, "no keylength defined for %N",
603: encryption_algorithm_names, enc_alg);
604: return FALSE;
605: }
606: /* to bytes */
607: enc_size /= 8;
608:
609: /* CCM/GCM/CTR/GMAC needs additional bytes */
610: switch (enc_alg)
611: {
612: case ENCR_AES_CCM_ICV8:
613: case ENCR_AES_CCM_ICV12:
614: case ENCR_AES_CCM_ICV16:
615: case ENCR_CAMELLIA_CCM_ICV8:
616: case ENCR_CAMELLIA_CCM_ICV12:
617: case ENCR_CAMELLIA_CCM_ICV16:
618: enc_size += 3;
619: break;
620: case ENCR_AES_GCM_ICV8:
621: case ENCR_AES_GCM_ICV12:
622: case ENCR_AES_GCM_ICV16:
623: case ENCR_AES_CTR:
624: case ENCR_CAMELLIA_CTR:
625: case ENCR_NULL_AUTH_AES_GMAC:
626: case ENCR_CHACHA20_POLY1305:
627: enc_size += 4;
628: break;
629: default:
630: break;
631: }
632: }
633:
634: if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM,
635: &int_alg, &int_size))
636: {
637: DBG2(DBG_CHD, " using %N for integrity",
638: integrity_algorithm_names, int_alg);
639:
640: if (!int_size)
641: {
642: int_size = keymat_get_keylen_integ(int_alg);
643: }
644: if (!int_size)
645: {
646: DBG1(DBG_CHD, "no keylength defined for %N",
647: integrity_algorithm_names, int_alg);
648: return FALSE;
649: }
650: /* to bytes */
651: int_size /= 8;
652: }
653:
654: if (!this->prf->set_key(this->prf, this->skd))
655: {
656: return FALSE;
657: }
658:
659: if (dh)
660: {
661: if (!dh->get_shared_secret(dh, &secret))
662: {
663: return FALSE;
664: }
665: DBG4(DBG_CHD, "DH secret %B", &secret);
666: }
667: seed = chunk_cata("scc", secret, nonce_i, nonce_r);
668: DBG4(DBG_CHD, "seed %B", &seed);
669:
670: prf_plus = prf_plus_create(this->prf, TRUE, seed);
671: memwipe(seed.ptr, seed.len);
672:
673: if (!prf_plus)
674: {
675: return FALSE;
676: }
677:
678: *encr_i = *integ_i = *encr_r = *integ_r = chunk_empty;
679: if (!prf_plus->allocate_bytes(prf_plus, enc_size, encr_i) ||
680: !prf_plus->allocate_bytes(prf_plus, int_size, integ_i) ||
681: !prf_plus->allocate_bytes(prf_plus, enc_size, encr_r) ||
682: !prf_plus->allocate_bytes(prf_plus, int_size, integ_r))
683: {
684: chunk_free(encr_i);
685: chunk_free(integ_i);
686: chunk_free(encr_r);
687: chunk_free(integ_r);
688: prf_plus->destroy(prf_plus);
689: return FALSE;
690: }
691:
692: prf_plus->destroy(prf_plus);
693:
694: if (enc_size)
695: {
696: DBG4(DBG_CHD, "encryption initiator key %B", encr_i);
697: DBG4(DBG_CHD, "encryption responder key %B", encr_r);
698: }
699: if (int_size)
700: {
701: DBG4(DBG_CHD, "integrity initiator key %B", integ_i);
702: DBG4(DBG_CHD, "integrity responder key %B", integ_r);
703: }
704: return TRUE;
705: }
706:
707: METHOD(keymat_v2_t, get_skd, pseudo_random_function_t,
708: private_keymat_v2_t *this, chunk_t *skd)
709: {
710: *skd = this->skd;
711: return this->prf_alg;
712: }
713:
714: METHOD(keymat_t, get_aead, aead_t*,
715: private_keymat_v2_t *this, bool in)
716: {
717: return in ? this->aead_in : this->aead_out;
718: }
719:
720: METHOD(keymat_v2_t, get_auth_octets, bool,
721: private_keymat_v2_t *this, bool verify, chunk_t ike_sa_init,
722: chunk_t nonce, chunk_t ppk, identification_t *id, char reserved[3],
723: chunk_t *octets, array_t *schemes)
724: {
725: chunk_t chunk, idx;
726: chunk_t skp_ppk = chunk_empty;
727: chunk_t skp;
728:
729: skp = verify ? this->skp_verify : this->skp_build;
730: if (ppk.ptr)
731: {
732: DBG4(DBG_IKE, "PPK %B", &ppk);
733: if (!derive_skp_ppk(this, ppk, skp, &skp_ppk))
734: {
735: return FALSE;
736: }
737: skp = skp_ppk;
738: }
739:
740: chunk = chunk_alloca(4);
741: chunk.ptr[0] = id->get_type(id);
742: memcpy(chunk.ptr + 1, reserved, 3);
743: idx = chunk_cata("cc", chunk, id->get_encoding(id));
744:
745: DBG3(DBG_IKE, "IDx' %B", &idx);
746: DBG4(DBG_IKE, "SK_p %B", &skp);
747: if (!this->prf->set_key(this->prf, skp) ||
748: !this->prf->allocate_bytes(this->prf, idx, &chunk))
749: {
750: chunk_clear(&skp_ppk);
751: return FALSE;
752: }
753: chunk_clear(&skp_ppk);
754: *octets = chunk_cat("ccm", ike_sa_init, nonce, chunk);
755: DBG3(DBG_IKE, "octets = message + nonce + prf(Sk_px, IDx') %B", octets);
756: return TRUE;
757: }
758:
759: /**
760: * Key pad for the AUTH method SHARED_KEY_MESSAGE_INTEGRITY_CODE.
761: */
762: #define IKEV2_KEY_PAD "Key Pad for IKEv2"
763: #define IKEV2_KEY_PAD_LENGTH 17
764:
765: METHOD(keymat_v2_t, get_psk_sig, bool,
766: private_keymat_v2_t *this, bool verify, chunk_t ike_sa_init, chunk_t nonce,
767: chunk_t secret, chunk_t ppk, identification_t *id, char reserved[3],
768: chunk_t *sig)
769: {
770: chunk_t skp_ppk = chunk_empty, key = chunk_empty, octets = chunk_empty;
771: chunk_t key_pad;
772: bool success = FALSE;
773:
774: if (!secret.len)
775: { /* EAP uses SK_p if no MSK has been established */
776: secret = verify ? this->skp_verify : this->skp_build;
777: if (ppk.ptr)
778: {
779: if (!derive_skp_ppk(this, ppk, secret, &skp_ppk))
780: {
781: return FALSE;
782: }
783: secret = skp_ppk;
784: }
785: }
786: if (!get_auth_octets(this, verify, ike_sa_init, nonce, ppk, id, reserved,
787: &octets, NULL))
788: {
789: goto failure;
790: }
791: /* AUTH = prf(prf(Shared Secret,"Key Pad for IKEv2"), <msg octets>) */
792: key_pad = chunk_create(IKEV2_KEY_PAD, IKEV2_KEY_PAD_LENGTH);
793: if (!this->prf->set_key(this->prf, secret) ||
794: !this->prf->allocate_bytes(this->prf, key_pad, &key))
795: {
796: goto failure;
797: }
798: if (!this->prf->set_key(this->prf, key) ||
799: !this->prf->allocate_bytes(this->prf, octets, sig))
800: {
801: goto failure;
802: }
803: DBG4(DBG_IKE, "secret %B", &secret);
804: DBG4(DBG_IKE, "prf(secret, keypad) %B", &key);
805: DBG3(DBG_IKE, "AUTH = prf(prf(secret, keypad), octets) %B", sig);
806: success = TRUE;
807:
808: failure:
809: chunk_clear(&skp_ppk);
810: chunk_free(&octets);
811: chunk_free(&key);
812: return success;
813:
814: }
815:
816: METHOD(keymat_v2_t, hash_algorithm_supported, bool,
817: private_keymat_v2_t *this, hash_algorithm_t hash)
818: {
819: if (!this->hash_algorithms)
820: {
821: return FALSE;
822: }
823: return this->hash_algorithms->contains(this->hash_algorithms, hash);
824: }
825:
826: METHOD(keymat_v2_t, add_hash_algorithm, void,
827: private_keymat_v2_t *this, hash_algorithm_t hash)
828: {
829: if (!this->hash_algorithms)
830: {
831: this->hash_algorithms = hash_algorithm_set_create();
832: }
833: this->hash_algorithms->add(this->hash_algorithms, hash);
834: }
835:
836: METHOD(keymat_t, destroy, void,
837: private_keymat_v2_t *this)
838: {
839: DESTROY_IF(this->aead_in);
840: DESTROY_IF(this->aead_out);
841: DESTROY_IF(this->prf);
842: chunk_clear(&this->skd);
843: chunk_clear(&this->skp_verify);
844: chunk_clear(&this->skp_build);
845: DESTROY_IF(this->hash_algorithms);
846: free(this);
847: }
848:
849: /**
850: * See header
851: */
852: keymat_v2_t *keymat_v2_create(bool initiator)
853: {
854: private_keymat_v2_t *this;
855:
856: INIT(this,
857: .public = {
858: .keymat = {
859: .get_version = _get_version,
860: .create_dh = _create_dh,
861: .create_nonce_gen = _create_nonce_gen,
862: .get_aead = _get_aead,
863: .destroy = _destroy,
864: },
865: .derive_ike_keys = _derive_ike_keys,
866: .derive_ike_keys_ppk = _derive_ike_keys_ppk,
867: .derive_child_keys = _derive_child_keys,
868: .get_skd = _get_skd,
869: .get_auth_octets = _get_auth_octets,
870: .get_psk_sig = _get_psk_sig,
871: .add_hash_algorithm = _add_hash_algorithm,
872: .hash_algorithm_supported = _hash_algorithm_supported,
873:
874: },
875: .initiator = initiator,
876: .prf_alg = PRF_UNDEFINED,
877: );
878:
879: return &this->public;
880: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>