2 * Copyright (C) 2015 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * HSR Hochschule fuer Technik Rapperswil
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>.
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
17 #include "keymat_v2.h"
20 #include <crypto/prf_plus.h>
21 #include <crypto/hashers/hash_algorithm_set.h>
23 typedef struct private_keymat_v2_t private_keymat_v2_t
;
26 * Private data of an keymat_t object.
28 struct private_keymat_v2_t
{
31 * Public keymat_v2_t interface.
36 * IKE_SA Role, initiator or responder
56 * Negotiated PRF algorithm
58 pseudo_random_function_t prf_alg
;
61 * Key to derive key material from for CHILD_SAs, rekeying
66 * Key to build outging authentication data (SKp)
71 * Key to verify incoming authentication data (SKp)
76 * Set of hash algorithms supported by peer for signature authentication
78 hash_algorithm_set_t
*hash_algorithms
;
81 METHOD(keymat_t
, get_version
, ike_version_t
,
82 private_keymat_v2_t
*this)
87 METHOD(keymat_t
, create_dh
, diffie_hellman_t
*,
88 private_keymat_v2_t
*this, diffie_hellman_group_t group
)
90 return lib
->crypto
->create_dh(lib
->crypto
, group
);
93 METHOD(keymat_t
, create_nonce_gen
, nonce_gen_t
*,
94 private_keymat_v2_t
*this)
96 return lib
->crypto
->create_nonce_gen(lib
->crypto
);
100 * Derive IKE keys for a combined AEAD algorithm
102 static bool derive_ike_aead(private_keymat_v2_t
*this, uint16_t alg
,
103 uint16_t key_size
, prf_plus_t
*prf_plus
)
105 aead_t
*aead_i
, *aead_r
;
106 chunk_t sk_ei
= chunk_empty
, sk_er
= chunk_empty
;
111 case ENCR_AES_GCM_ICV8
:
112 case ENCR_AES_GCM_ICV12
:
113 case ENCR_AES_GCM_ICV16
:
115 case ENCR_CHACHA20_POLY1305
:
118 case ENCR_AES_CCM_ICV8
:
119 case ENCR_AES_CCM_ICV12
:
120 case ENCR_AES_CCM_ICV16
:
122 case ENCR_CAMELLIA_CCM_ICV8
:
123 case ENCR_CAMELLIA_CCM_ICV12
:
124 case ENCR_CAMELLIA_CCM_ICV16
:
129 DBG1(DBG_IKE
, "nonce size for %N unknown!",
130 encryption_algorithm_names
, alg
);
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
)
139 DBG1(DBG_IKE
, "%N %N (key size %d) not supported!",
140 transform_type_names
, ENCRYPTION_ALGORITHM
,
141 encryption_algorithm_names
, alg
, key_size
);
144 key_size
= aead_i
->get_key_size(aead_i
);
145 if (key_size
!= aead_r
->get_key_size(aead_r
))
149 if (!prf_plus
->allocate_bytes(prf_plus
, key_size
, &sk_ei
))
153 DBG4(DBG_IKE
, "Sk_ei secret %B", &sk_ei
);
154 if (!aead_i
->set_key(aead_i
, sk_ei
))
159 if (!prf_plus
->allocate_bytes(prf_plus
, key_size
, &sk_er
))
163 DBG4(DBG_IKE
, "Sk_er secret %B", &sk_er
);
164 if (!aead_r
->set_key(aead_r
, sk_er
))
171 this->aead_in
= aead_r
;
172 this->aead_out
= aead_i
;
176 this->aead_in
= aead_i
;
177 this->aead_out
= aead_r
;
179 aead_i
= aead_r
= NULL
;
180 charon
->bus
->ike_derived_keys(charon
->bus
, sk_ei
, sk_er
, chunk_empty
,
188 return this->aead_in
&& this->aead_out
;
192 * Derive IKE keys for traditional encryption and MAC algorithms
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
)
197 crypter_t
*crypter_i
= NULL
, *crypter_r
= NULL
;
198 signer_t
*signer_i
, *signer_r
;
199 iv_gen_t
*ivg_i
, *ivg_r
;
201 chunk_t sk_ei
= chunk_empty
, sk_er
= chunk_empty
,
202 sk_ai
= chunk_empty
, sk_ar
= chunk_empty
;
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
)
210 DBG1(DBG_IKE
, "%N %N not supported!",
211 transform_type_names
, INTEGRITY_ALGORITHM
,
212 integrity_algorithm_names
, int_alg
);
215 if (crypter_i
== NULL
|| crypter_r
== NULL
)
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
);
223 /* SK_ai/SK_ar used for integrity protection */
224 key_size
= signer_i
->get_key_size(signer_i
);
226 if (!prf_plus
->allocate_bytes(prf_plus
, key_size
, &sk_ai
))
230 DBG4(DBG_IKE
, "Sk_ai secret %B", &sk_ai
);
231 if (!signer_i
->set_key(signer_i
, sk_ai
))
236 if (!prf_plus
->allocate_bytes(prf_plus
, key_size
, &sk_ar
))
240 DBG4(DBG_IKE
, "Sk_ar secret %B", &sk_ar
);
241 if (!signer_r
->set_key(signer_r
, sk_ar
))
246 /* SK_ei/SK_er used for encryption */
247 key_size
= crypter_i
->get_key_size(crypter_i
);
249 if (!prf_plus
->allocate_bytes(prf_plus
, key_size
, &sk_ei
))
253 DBG4(DBG_IKE
, "Sk_ei secret %B", &sk_ei
);
254 if (!crypter_i
->set_key(crypter_i
, sk_ei
))
259 if (!prf_plus
->allocate_bytes(prf_plus
, key_size
, &sk_er
))
263 DBG4(DBG_IKE
, "Sk_er secret %B", &sk_er
);
264 if (!crypter_r
->set_key(crypter_r
, sk_er
))
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
)
277 this->aead_in
= aead_create(crypter_r
, signer_r
, ivg_r
);
278 this->aead_out
= aead_create(crypter_i
, signer_i
, ivg_i
);
282 this->aead_in
= aead_create(crypter_i
, signer_i
, ivg_i
);
283 this->aead_out
= aead_create(crypter_r
, signer_r
, ivg_r
);
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
);
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
;
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
)
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
;
312 spi_i
= chunk_alloca(sizeof(uint64_t));
313 spi_r
= chunk_alloca(sizeof(uint64_t));
315 if (!dh
->get_shared_secret(dh
, &secret
))
320 /* Create SAs general purpose PRF first, we may use it here */
321 if (!proposal
->get_algorithm(proposal
, PSEUDO_RANDOM_FUNCTION
, &alg
, NULL
))
323 DBG1(DBG_IKE
, "no %N selected",
324 transform_type_names
, PSEUDO_RANDOM_FUNCTION
);
325 chunk_clear(&secret
);
329 this->prf
= lib
->crypto
->create_prf(lib
->crypto
, alg
);
330 if (this->prf
== NULL
)
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
);
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
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
);
360 /* all other algorithms use variable key length, full nonce */
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
);
368 /* KEYMAT = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr)
370 * if we are rekeying, SKEYSEED is built on another way
372 if (rekey_function
== PRF_UNDEFINED
) /* not rekeying */
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
))
379 prf_plus
= prf_plus_create(this->prf
, TRUE
, prf_plus_seed
);
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
);
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
);
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
))
402 prf_plus
= prf_plus_create(rekey_prf
, TRUE
, prf_plus_seed
);
405 DBG4(DBG_IKE
, "SKEYSEED %B", &skeyseed
);
407 chunk_clear(&skeyseed
);
408 chunk_clear(&secret
);
409 chunk_free(&full_nonce
);
410 chunk_free(&fixed_nonce
);
411 chunk_clear(&prf_plus_seed
);
418 /* KEYMAT = SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr */
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
))
426 DBG4(DBG_IKE
, "Sk_d secret %B", &this->skd
);
428 if (!proposal
->get_algorithm(proposal
, ENCRYPTION_ALGORITHM
, &alg
, &key_size
))
430 DBG1(DBG_IKE
, "no %N selected",
431 transform_type_names
, ENCRYPTION_ALGORITHM
);
435 if (encryption_algorithm_is_aead(alg
))
437 if (!derive_ike_aead(this, alg
, key_size
, prf_plus
))
444 if (!proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
,
447 DBG1(DBG_IKE
, "no %N selected",
448 transform_type_names
, INTEGRITY_ALGORITHM
);
451 if (!derive_ike_traditional(this, alg
, key_size
, int_alg
, prf_plus
))
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
))
463 DBG4(DBG_IKE
, "Sk_pi secret %B", &key
);
466 this->skp_build
= key
;
470 this->skp_verify
= key
;
472 if (!prf_plus
->allocate_bytes(prf_plus
, key_size
, &key
))
476 DBG4(DBG_IKE
, "Sk_pr secret %B", &key
);
479 this->skp_verify
= key
;
483 this->skp_build
= key
;
486 /* all done, prf_plus not needed anymore */
488 DESTROY_IF(prf_plus
);
489 DESTROY_IF(rekey_prf
);
491 return this->skp_build
.len
&& this->skp_verify
.len
;
495 * Derives a key from the given key and a PRF that was initialized with a PPK
497 static bool derive_ppk_key(prf_t
*prf
, char *name
, chunk_t key
,
500 prf_plus_t
*prf_plus
;
502 prf_plus
= prf_plus_create(prf
, TRUE
, key
);
504 !prf_plus
->allocate_bytes(prf_plus
, key
.len
, new_key
))
506 DBG1(DBG_IKE
, "unable to derive %s with PPK", name
);
507 DESTROY_IF(prf_plus
);
510 prf_plus
->destroy(prf_plus
);
515 * Use the given PPK to derive a new SK_pi/r
517 static bool derive_skp_ppk(private_keymat_v2_t
*this, chunk_t ppk
, chunk_t skp
,
520 if (!this->prf
->set_key(this->prf
, ppk
))
522 DBG1(DBG_IKE
, "unable to set PPK in PRF");
525 return derive_ppk_key(this->prf
, "SK_p", skp
, new_skp
);
528 METHOD(keymat_v2_t
, derive_ike_keys_ppk
, bool,
529 private_keymat_v2_t
*this, chunk_t ppk
)
531 chunk_t skd
= chunk_empty
, new_skpi
= chunk_empty
, new_skpr
= chunk_empty
;
532 chunk_t
*skpi
, *skpr
;
541 skpi
= &this->skp_build
;
542 skpr
= &this->skp_verify
;
546 skpi
= &this->skp_verify
;
547 skpr
= &this->skp_build
;
550 DBG4(DBG_IKE
, "derive keys using PPK %B", &ppk
);
552 if (!this->prf
->set_key(this->prf
, ppk
))
554 DBG1(DBG_IKE
, "unable to set PPK in PRF");
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
))
562 chunk_clear(&new_skpi
);
563 chunk_clear(&new_skpr
);
567 DBG4(DBG_IKE
, "Sk_d secret %B", &skd
);
568 chunk_clear(&this->skd
);
571 DBG4(DBG_IKE
, "Sk_pi secret %B", &new_skpi
);
575 DBG4(DBG_IKE
, "Sk_pr secret %B", &new_skpr
);
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
)
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
;
590 if (proposal
->get_algorithm(proposal
, ENCRYPTION_ALGORITHM
,
591 &enc_alg
, &enc_size
))
593 DBG2(DBG_CHD
, " using %N for encryption",
594 encryption_algorithm_names
, enc_alg
);
598 enc_size
= keymat_get_keylen_encr(enc_alg
);
600 if (enc_alg
!= ENCR_NULL
&& !enc_size
)
602 DBG1(DBG_CHD
, "no keylength defined for %N",
603 encryption_algorithm_names
, enc_alg
);
609 /* CCM/GCM/CTR/GMAC needs additional bytes */
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
:
620 case ENCR_AES_GCM_ICV8
:
621 case ENCR_AES_GCM_ICV12
:
622 case ENCR_AES_GCM_ICV16
:
624 case ENCR_CAMELLIA_CTR
:
625 case ENCR_NULL_AUTH_AES_GMAC
:
626 case ENCR_CHACHA20_POLY1305
:
634 if (proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
,
635 &int_alg
, &int_size
))
637 DBG2(DBG_CHD
, " using %N for integrity",
638 integrity_algorithm_names
, int_alg
);
642 int_size
= keymat_get_keylen_integ(int_alg
);
646 DBG1(DBG_CHD
, "no keylength defined for %N",
647 integrity_algorithm_names
, int_alg
);
654 if (!this->prf
->set_key(this->prf
, this->skd
))
661 if (!dh
->get_shared_secret(dh
, &secret
))
665 DBG4(DBG_CHD
, "DH secret %B", &secret
);
667 seed
= chunk_cata("scc", secret
, nonce_i
, nonce_r
);
668 DBG4(DBG_CHD
, "seed %B", &seed
);
670 prf_plus
= prf_plus_create(this->prf
, TRUE
, seed
);
671 memwipe(seed
.ptr
, seed
.len
);
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
))
688 prf_plus
->destroy(prf_plus
);
692 prf_plus
->destroy(prf_plus
);
696 DBG4(DBG_CHD
, "encryption initiator key %B", encr_i
);
697 DBG4(DBG_CHD
, "encryption responder key %B", encr_r
);
701 DBG4(DBG_CHD
, "integrity initiator key %B", integ_i
);
702 DBG4(DBG_CHD
, "integrity responder key %B", integ_r
);
707 METHOD(keymat_v2_t
, get_skd
, pseudo_random_function_t
,
708 private_keymat_v2_t
*this, chunk_t
*skd
)
711 return this->prf_alg
;
714 METHOD(keymat_t
, get_aead
, aead_t
*,
715 private_keymat_v2_t
*this, bool in
)
717 return in ?
this->aead_in
: this->aead_out
;
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
)
726 chunk_t skp_ppk
= chunk_empty
;
729 skp
= verify ?
this->skp_verify
: this->skp_build
;
732 DBG4(DBG_IKE
, "PPK %B", &ppk
);
733 if (!derive_skp_ppk(this, ppk
, skp
, &skp_ppk
))
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
));
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
))
750 chunk_clear(&skp_ppk
);
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
);
760 * Key pad for the AUTH method SHARED_KEY_MESSAGE_INTEGRITY_CODE.
762 #define IKEV2_KEY_PAD "Key Pad for IKEv2"
763 #define IKEV2_KEY_PAD_LENGTH 17
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],
770 chunk_t skp_ppk
= chunk_empty
, key
= chunk_empty
, octets
= chunk_empty
;
772 bool success
= FALSE
;
775 { /* EAP uses SK_p if no MSK has been established */
776 secret
= verify ?
this->skp_verify
: this->skp_build
;
779 if (!derive_skp_ppk(this, ppk
, secret
, &skp_ppk
))
786 if (!get_auth_octets(this, verify
, ike_sa_init
, nonce
, ppk
, id
, reserved
,
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
))
798 if (!this->prf
->set_key(this->prf
, key
) ||
799 !this->prf
->allocate_bytes(this->prf
, octets
, sig
))
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
);
809 chunk_clear(&skp_ppk
);
816 METHOD(keymat_v2_t
, hash_algorithm_supported
, bool,
817 private_keymat_v2_t
*this, hash_algorithm_t hash
)
819 if (!this->hash_algorithms
)
823 return this->hash_algorithms
->contains(this->hash_algorithms
, hash
);
826 METHOD(keymat_v2_t
, add_hash_algorithm
, void,
827 private_keymat_v2_t
*this, hash_algorithm_t hash
)
829 if (!this->hash_algorithms
)
831 this->hash_algorithms
= hash_algorithm_set_create();
833 this->hash_algorithms
->add(this->hash_algorithms
, hash
);
836 METHOD(keymat_t
, destroy
, void,
837 private_keymat_v2_t
*this)
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
);
852 keymat_v2_t
*keymat_v2_create(bool initiator
)
854 private_keymat_v2_t
*this;
859 .get_version
= _get_version
,
860 .create_dh
= _create_dh
,
861 .create_nonce_gen
= _create_nonce_gen
,
862 .get_aead
= _get_aead
,
865 .derive_ike_keys
= _derive_ike_keys
,
866 .derive_ike_keys_ppk
= _derive_ike_keys_ppk
,
867 .derive_child_keys
= _derive_child_keys
,
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
,
875 .initiator
= initiator
,
876 .prf_alg
= PRF_UNDEFINED
,
879 return &this->public;