2 * Copyright (C) 2011 Tobias Brunner
4 * Copyright (C) secunet Security Networks AG
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_v1.h"
20 #include <sa/ikev1/iv_manager.h>
21 #include <encoding/generator.h>
22 #include <encoding/payloads/nonce_payload.h>
24 typedef struct private_keymat_v1_t private_keymat_v1_t
;
27 * Private data of an keymat_t object.
29 struct private_keymat_v1_t
{
32 * Public keymat_v1_t interface.
37 * IKE_SA Role, initiator or responder
47 * PRF to create Phase 1 HASH payloads
52 * Crypter wrapped in an aead_t interface
57 * Hasher used for IV generation (and other things like e.g. NAT-T)
62 * Key to derive key material from for non-ISAKMP SAs, rekeying
67 * Key used for authentication after main mode
74 iv_manager_t
*iv_manager
;
78 * Constants used in key derivation.
80 static const chunk_t octet_0
= chunk_from_chars(0x00);
81 static const chunk_t octet_1
= chunk_from_chars(0x01);
82 static const chunk_t octet_2
= chunk_from_chars(0x02);
85 * Simple aead_t implementation without support for authentication.
88 /** implements aead_t interface */
90 /** crypter to be used */
95 METHOD(aead_t
, encrypt
, bool,
96 private_aead_t
*this, chunk_t plain
, chunk_t assoc
, chunk_t iv
,
99 return this->crypter
->encrypt(this->crypter
, plain
, iv
, encrypted
);
102 METHOD(aead_t
, decrypt
, bool,
103 private_aead_t
*this, chunk_t encrypted
, chunk_t assoc
, chunk_t iv
,
106 return this->crypter
->decrypt(this->crypter
, encrypted
, iv
, plain
);
109 METHOD(aead_t
, get_block_size
, size_t,
110 private_aead_t
*this)
112 return this->crypter
->get_block_size(this->crypter
);
115 METHOD(aead_t
, get_icv_size
, size_t,
116 private_aead_t
*this)
121 METHOD(aead_t
, get_iv_size
, size_t,
122 private_aead_t
*this)
124 /* in order to create the messages properly we return 0 here */
128 METHOD(aead_t
, get_iv_gen
, iv_gen_t
*,
129 private_aead_t
*this)
131 /* IVs are retrieved via keymat_v1.get_iv() */
135 METHOD(aead_t
, get_key_size
, size_t,
136 private_aead_t
*this)
138 return this->crypter
->get_key_size(this->crypter
);
141 METHOD(aead_t
, set_key
, bool,
142 private_aead_t
*this, chunk_t key
)
144 return this->crypter
->set_key(this->crypter
, key
);
147 METHOD(aead_t
, aead_destroy
, void,
148 private_aead_t
*this)
150 this->crypter
->destroy(this->crypter
);
155 * Expand SKEYID_e according to Appendix B in RFC 2409.
156 * TODO-IKEv1: verify keys (e.g. for weak keys, see Appendix B)
158 static bool expand_skeyid_e(chunk_t skeyid_e
, size_t key_size
, prf_t
*prf
,
165 if (skeyid_e
.len
>= key_size
)
166 { /* no expansion required, reduce to key_size */
167 skeyid_e
.len
= key_size
;
171 block_size
= prf
->get_block_size(prf
);
172 *ka
= chunk_alloc((key_size
/ block_size
+ 1) * block_size
);
175 /* Ka = K1 | K2 | ..., K1 = prf(SKEYID_e, 0), K2 = prf(SKEYID_e, K1) ... */
176 if (!prf
->set_key(prf
, skeyid_e
))
179 chunk_clear(&skeyid_e
);
183 for (i
= 0; i
< key_size
; i
+= block_size
)
185 if (!prf
->get_bytes(prf
, seed
, ka
->ptr
+ i
))
188 chunk_clear(&skeyid_e
);
191 seed
= chunk_create(ka
->ptr
+ i
, block_size
);
193 chunk_clear(&skeyid_e
);
198 * Create a simple implementation of the aead_t interface which only encrypts
201 static aead_t
*create_aead(proposal_t
*proposal
, prf_t
*prf
, chunk_t skeyid_e
,
204 private_aead_t
*this;
205 uint16_t alg
, key_size
;
208 if (!proposal
->get_algorithm(proposal
, ENCRYPTION_ALGORITHM
, &alg
,
211 DBG1(DBG_IKE
, "no %N selected",
212 transform_type_names
, ENCRYPTION_ALGORITHM
);
215 crypter
= lib
->crypto
->create_crypter(lib
->crypto
, alg
, key_size
/ 8);
218 DBG1(DBG_IKE
, "%N %N (key size %d) not supported!",
219 transform_type_names
, ENCRYPTION_ALGORITHM
,
220 encryption_algorithm_names
, alg
, key_size
);
223 if (!expand_skeyid_e(skeyid_e
, crypter
->get_key_size(crypter
), prf
, ka
))
227 DBG4(DBG_IKE
, "encryption key Ka %B", ka
);
228 if (!crypter
->set_key(crypter
, *ka
))
238 .get_block_size
= _get_block_size
,
239 .get_icv_size
= _get_icv_size
,
240 .get_iv_size
= _get_iv_size
,
241 .get_iv_gen
= _get_iv_gen
,
242 .get_key_size
= _get_key_size
,
244 .destroy
= _aead_destroy
,
252 * Converts integrity algorithm to PRF algorithm
254 static uint16_t auth_to_prf(uint16_t alg
)
258 case AUTH_HMAC_SHA1_96
:
259 return PRF_HMAC_SHA1
;
260 case AUTH_HMAC_SHA2_256_128
:
261 return PRF_HMAC_SHA2_256
;
262 case AUTH_HMAC_SHA2_384_192
:
263 return PRF_HMAC_SHA2_384
;
264 case AUTH_HMAC_SHA2_512_256
:
265 return PRF_HMAC_SHA2_512
;
266 case AUTH_HMAC_MD5_96
:
268 case AUTH_AES_XCBC_96
:
269 return PRF_AES128_XCBC
;
271 return PRF_UNDEFINED
;
276 * Converts integrity algorithm to hash algorithm
278 static uint16_t auth_to_hash(uint16_t alg
)
282 case AUTH_HMAC_SHA1_96
:
284 case AUTH_HMAC_SHA2_256_128
:
286 case AUTH_HMAC_SHA2_384_192
:
288 case AUTH_HMAC_SHA2_512_256
:
290 case AUTH_HMAC_MD5_96
:
298 * Adjust the key length for PRF algorithms that expect a fixed key length.
300 static void adjust_keylen(uint16_t alg
, chunk_t
*key
)
304 case PRF_AES128_XCBC
:
305 /* while rfc4434 defines variable keys for AES-XCBC, rfc3664 does
306 * not and therefore fixed key semantics apply to XCBC for key
308 key
->len
= min(key
->len
, 16);
311 /* all other algorithms use variable key length */
316 METHOD(keymat_v1_t
, derive_ike_keys
, bool,
317 private_keymat_v1_t
*this, proposal_t
*proposal
, diffie_hellman_t
*dh
,
318 chunk_t dh_other
, chunk_t nonce_i
, chunk_t nonce_r
, ike_sa_id_t
*id
,
319 auth_method_t auth
, shared_key_t
*shared_key
)
321 chunk_t g_xy
, g_xi
, g_xr
, dh_me
, spi_i
, spi_r
, nonces
, data
, skeyid_e
;
325 spi_i
= chunk_alloca(sizeof(uint64_t));
326 spi_r
= chunk_alloca(sizeof(uint64_t));
328 if (!proposal
->get_algorithm(proposal
, PSEUDO_RANDOM_FUNCTION
, &alg
, NULL
))
329 { /* no PRF negotiated, use HMAC version of integrity algorithm instead */
330 if (!proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
, &alg
, NULL
)
331 || (alg
= auth_to_prf(alg
)) == PRF_UNDEFINED
)
333 DBG1(DBG_IKE
, "no %N selected",
334 transform_type_names
, PSEUDO_RANDOM_FUNCTION
);
338 this->prf
= lib
->crypto
->create_prf(lib
->crypto
, alg
);
341 DBG1(DBG_IKE
, "%N %N not supported!",
342 transform_type_names
, PSEUDO_RANDOM_FUNCTION
,
343 pseudo_random_function_names
, alg
);
346 if (this->prf
->get_block_size(this->prf
) <
347 this->prf
->get_key_size(this->prf
))
348 { /* TODO-IKEv1: support PRF output expansion (RFC 2409, Appendix B) */
349 DBG1(DBG_IKE
, "expansion of %N %N output not supported!",
350 transform_type_names
, PSEUDO_RANDOM_FUNCTION
,
351 pseudo_random_function_names
, alg
);
355 if (!dh
->get_shared_secret(dh
, &g_xy
))
359 DBG4(DBG_IKE
, "shared Diffie Hellman secret %B", &g_xy
);
361 *((uint64_t*)spi_i
.ptr
) = id
->get_initiator_spi(id
);
362 *((uint64_t*)spi_r
.ptr
) = id
->get_responder_spi(id
);
363 nonces
= chunk_cata("cc", nonce_i
, nonce_r
);
368 case AUTH_XAUTH_INIT_PSK
:
369 case AUTH_XAUTH_RESP_PSK
:
370 { /* SKEYID = prf(pre-shared-key, Ni_b | Nr_b) */
377 psk
= shared_key
->get_key(shared_key
);
378 adjust_keylen(alg
, &psk
);
379 if (!this->prf
->set_key(this->prf
, psk
) ||
380 !this->prf
->allocate_bytes(this->prf
, nonces
, &skeyid
))
391 case AUTH_XAUTH_INIT_RSA
:
392 case AUTH_XAUTH_RESP_RSA
:
393 case AUTH_HYBRID_INIT_RSA
:
394 case AUTH_HYBRID_RESP_RSA
:
396 if (!this->prf
->set_key(this->prf
, nonces
) ||
397 !this->prf
->allocate_bytes(this->prf
, g_xy
, &skeyid
))
405 /* TODO-IKEv1: implement key derivation for other schemes */
406 /* authentication class not supported */
410 adjust_keylen(alg
, &skeyid
);
411 DBG4(DBG_IKE
, "SKEYID %B", &skeyid
);
413 /* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */
414 data
= chunk_cat("cccc", g_xy
, spi_i
, spi_r
, octet_0
);
415 if (!this->prf
->set_key(this->prf
, skeyid
) ||
416 !this->prf
->allocate_bytes(this->prf
, data
, &this->skeyid_d
))
420 chunk_clear(&skeyid
);
424 DBG4(DBG_IKE
, "SKEYID_d %B", &this->skeyid_d
);
426 /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */
427 data
= chunk_cat("ccccc", this->skeyid_d
, g_xy
, spi_i
, spi_r
, octet_1
);
428 if (!this->prf
->allocate_bytes(this->prf
, data
, &this->skeyid_a
))
432 chunk_clear(&skeyid
);
436 DBG4(DBG_IKE
, "SKEYID_a %B", &this->skeyid_a
);
438 /* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */
439 data
= chunk_cat("ccccc", this->skeyid_a
, g_xy
, spi_i
, spi_r
, octet_2
);
440 if (!this->prf
->allocate_bytes(this->prf
, data
, &skeyid_e
))
444 chunk_clear(&skeyid
);
448 DBG4(DBG_IKE
, "SKEYID_e %B", &skeyid_e
);
455 alg
= PRF_HMAC_SHA2_256
;
458 alg
= PRF_HMAC_SHA2_384
;
461 alg
= PRF_HMAC_SHA2_512
;
464 /* use proposal algorithm */
467 this->prf_auth
= lib
->crypto
->create_prf(lib
->crypto
, alg
);
470 DBG1(DBG_IKE
, "%N %N not supported!",
471 transform_type_names
, PSEUDO_RANDOM_FUNCTION
,
472 pseudo_random_function_names
, alg
);
473 chunk_clear(&skeyid
);
476 if (!this->prf_auth
->set_key(this->prf_auth
, skeyid
))
478 chunk_clear(&skeyid
);
481 chunk_clear(&skeyid
);
483 this->aead
= create_aead(proposal
, this->prf
, skeyid_e
, &ka
);
488 charon
->bus
->ike_derived_keys(charon
->bus
, this->skeyid_d
, this->skeyid_a
,
489 chunk_empty
, ka
, chunk_empty
, chunk_empty
,
492 if (!this->hasher
&& !this->public.create_hasher(&this->public, proposal
))
497 if (!dh
->get_my_public_value(dh
, &dh_me
))
501 g_xi
= this->initiator
? dh_me
: dh_other
;
502 g_xr
= this->initiator
? dh_other
: dh_me
;
504 /* initial IV = hash(g^xi | g^xr) */
505 data
= chunk_cata("cc", g_xi
, g_xr
);
507 return this->iv_manager
->init_iv_chain(this->iv_manager
, data
, this->hasher
,
508 this->aead
->get_block_size(this->aead
));
512 * Derive key material for CHILD_SAs according to section 5.5. in RFC 2409.
514 static bool derive_child_keymat(private_keymat_v1_t
*this, chunk_t seed
,
515 uint16_t enc_size
, chunk_t
*encr
,
516 uint16_t int_size
, chunk_t
*integ
)
518 size_t block_size
, i
;
519 chunk_t keymat
, prev
= chunk_empty
;
521 block_size
= this->prf
->get_block_size(this->prf
);
522 keymat
= chunk_alloc(round_up(enc_size
+ int_size
, block_size
));
523 keymat
.len
= enc_size
+ int_size
;
525 for (i
= 0; i
< keymat
.len
; i
+= block_size
)
527 if (!this->prf
->get_bytes(this->prf
, prev
, NULL
) ||
528 !this->prf
->get_bytes(this->prf
, seed
, keymat
.ptr
+ i
))
530 chunk_clear(&keymat
);
533 prev
= chunk_create(keymat
.ptr
+ i
, block_size
);
536 chunk_split(keymat
, "aa", enc_size
, encr
, int_size
, integ
);
537 chunk_clear(&keymat
);
541 METHOD(keymat_v1_t
, derive_child_keys
, bool,
542 private_keymat_v1_t
*this, proposal_t
*proposal
, diffie_hellman_t
*dh
,
543 uint32_t spi_i
, uint32_t spi_r
, chunk_t nonce_i
, chunk_t nonce_r
,
544 chunk_t
*encr_i
, chunk_t
*integ_i
, chunk_t
*encr_r
, chunk_t
*integ_r
)
546 uint16_t enc_alg
, int_alg
, enc_size
= 0, int_size
= 0;
548 chunk_t seed
= chunk_empty
, secret
= chunk_empty
;
549 bool success
= FALSE
;
551 if (proposal
->get_algorithm(proposal
, ENCRYPTION_ALGORITHM
,
552 &enc_alg
, &enc_size
))
554 DBG2(DBG_CHD
, " using %N for encryption",
555 encryption_algorithm_names
, enc_alg
);
559 enc_size
= keymat_get_keylen_encr(enc_alg
);
561 if (enc_alg
!= ENCR_NULL
&& !enc_size
)
563 DBG1(DBG_CHD
, "no keylength defined for %N",
564 encryption_algorithm_names
, enc_alg
);
570 /* CCM/GCM/CTR/GMAC needs additional bytes */
573 case ENCR_AES_CCM_ICV8
:
574 case ENCR_AES_CCM_ICV12
:
575 case ENCR_AES_CCM_ICV16
:
576 case ENCR_CAMELLIA_CCM_ICV8
:
577 case ENCR_CAMELLIA_CCM_ICV12
:
578 case ENCR_CAMELLIA_CCM_ICV16
:
581 case ENCR_AES_GCM_ICV8
:
582 case ENCR_AES_GCM_ICV12
:
583 case ENCR_AES_GCM_ICV16
:
585 case ENCR_NULL_AUTH_AES_GMAC
:
593 if (proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
,
594 &int_alg
, &int_size
))
596 DBG2(DBG_CHD
, " using %N for integrity",
597 integrity_algorithm_names
, int_alg
);
601 int_size
= keymat_get_keylen_integ(int_alg
);
605 DBG1(DBG_CHD
, "no keylength defined for %N",
606 integrity_algorithm_names
, int_alg
);
613 /* KEYMAT = prf+(SKEYID_d, [ g(qm)^xy | ] protocol | SPI | Ni_b | Nr_b) */
614 if (!this->prf
->set_key(this->prf
, this->skeyid_d
))
618 protocol
= proposal
->get_protocol(proposal
);
621 if (!dh
->get_shared_secret(dh
, &secret
))
625 DBG4(DBG_CHD
, "DH secret %B", &secret
);
628 *encr_r
= *integ_r
= *encr_i
= *integ_i
= chunk_empty
;
629 seed
= chunk_cata("ccccc", secret
, chunk_from_thing(protocol
),
630 chunk_from_thing(spi_r
), nonce_i
, nonce_r
);
631 DBG4(DBG_CHD
, "initiator SA seed %B", &seed
);
632 if (!derive_child_keymat(this, seed
, enc_size
, encr_i
, int_size
, integ_i
))
637 seed
= chunk_cata("ccccc", secret
, chunk_from_thing(protocol
),
638 chunk_from_thing(spi_i
), nonce_i
, nonce_r
);
639 DBG4(DBG_CHD
, "responder SA seed %B", &seed
);
640 if (!derive_child_keymat(this, seed
, enc_size
, encr_r
, int_size
, integ_r
))
647 DBG4(DBG_CHD
, "encryption initiator key %B", encr_i
);
648 DBG4(DBG_CHD
, "encryption responder key %B", encr_r
);
652 DBG4(DBG_CHD
, "integrity initiator key %B", integ_i
);
653 DBG4(DBG_CHD
, "integrity responder key %B", integ_r
);
661 chunk_clear(integ_i
);
663 chunk_clear(integ_r
);
665 memwipe(seed
.ptr
, seed
.len
);
666 chunk_clear(&secret
);
671 METHOD(keymat_v1_t
, create_hasher
, bool,
672 private_keymat_v1_t
*this, proposal_t
*proposal
)
675 if (!proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
, &alg
, NULL
) ||
676 (alg
= auth_to_hash(alg
)) == HASH_UNKNOWN
)
678 DBG1(DBG_IKE
, "no %N selected", transform_type_names
, HASH_ALGORITHM
);
681 this->hasher
= lib
->crypto
->create_hasher(lib
->crypto
, alg
);
684 DBG1(DBG_IKE
, "%N %N not supported!",
685 transform_type_names
, HASH_ALGORITHM
,
686 hash_algorithm_names
, alg
);
692 METHOD(keymat_v1_t
, get_hasher
, hasher_t
*,
693 private_keymat_v1_t
*this)
698 METHOD(keymat_v1_t
, get_hash
, bool,
699 private_keymat_v1_t
*this, bool initiator
, chunk_t dh
, chunk_t dh_other
,
700 ike_sa_id_t
*ike_sa_id
, chunk_t sa_i
, chunk_t id
, chunk_t
*hash
,
701 signature_scheme_t
*scheme
)
704 uint64_t spi
, spi_other
;
706 /* HASH_I = prf(SKEYID, g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b )
707 * HASH_R = prf(SKEYID, g^xr | g^xi | CKY-R | CKY-I | SAi_b | IDir_b )
711 spi
= ike_sa_id
->get_initiator_spi(ike_sa_id
);
712 spi_other
= ike_sa_id
->get_responder_spi(ike_sa_id
);
716 spi_other
= ike_sa_id
->get_initiator_spi(ike_sa_id
);
717 spi
= ike_sa_id
->get_responder_spi(ike_sa_id
);
719 data
= chunk_cat("cccccc", dh
, dh_other
,
720 chunk_from_thing(spi
), chunk_from_thing(spi_other
),
723 DBG3(DBG_IKE
, "HASH_%c data %B", initiator
? 'I' : 'R', &data
);
725 if (!this->prf_auth
->allocate_bytes(this->prf_auth
, data
, hash
))
731 DBG3(DBG_IKE
, "HASH_%c %B", initiator
? 'I' : 'R', hash
);
738 * Get the nonce value found in the given message.
739 * Returns FALSE if none is found.
741 static bool get_nonce(message_t
*message
, chunk_t
*n
)
743 nonce_payload_t
*nonce
;
744 nonce
= (nonce_payload_t
*)message
->get_payload(message
, PLV1_NONCE
);
747 *n
= nonce
->get_nonce(nonce
);
754 * Generate the message data in order to generate the hashes.
756 static chunk_t
get_message_data(message_t
*message
, generator_t
*generator
)
758 payload_t
*payload
, *next
;
759 enumerator_t
*enumerator
;
762 if (message
->is_encoded(message
))
763 { /* inbound, although the message is generated, we cannot access the
764 * cleartext message data, so generate it anyway */
765 enumerator
= message
->create_payload_enumerator(message
);
766 while (enumerator
->enumerate(enumerator
, &payload
))
768 if (payload
->get_type(payload
) == PLV1_HASH
)
772 generator
->generate_payload(generator
, payload
);
774 enumerator
->destroy(enumerator
);
778 /* outbound, generate the payloads (there is no HASH payload yet) */
779 enumerator
= message
->create_payload_enumerator(message
);
780 if (enumerator
->enumerate(enumerator
, &payload
))
782 while (enumerator
->enumerate(enumerator
, &next
))
784 payload
->set_next_type(payload
, next
->get_type(next
));
785 generator
->generate_payload(generator
, payload
);
788 payload
->set_next_type(payload
, PL_NONE
);
789 generator
->generate_payload(generator
, payload
);
791 enumerator
->destroy(enumerator
);
793 return generator
->get_chunk(generator
, &lenpos
);
796 METHOD(keymat_v1_t
, get_hash_phase2
, bool,
797 private_keymat_v1_t
*this, message_t
*message
, chunk_t
*hash
)
800 chunk_t data
= chunk_empty
, *n_i
, *n_r
;
801 bool add_message
= TRUE
;
805 { /* no keys derived yet */
809 mid
= message
->get_message_id(message
);
812 /* Hashes are simple for most exchanges in Phase 2:
813 * Hash = prf(SKEYID_a, M-ID | Complete message after HASH payload)
814 * For Quick Mode there are three hashes:
815 * Hash(1) = same as above
816 * Hash(2) = prf(SKEYID_a, M-ID | Ni_b | Message after HASH payload)
817 * Hash(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b)
818 * So, for Quick Mode we keep track of the nonce values.
820 switch (message
->get_exchange_type(message
))
824 this->iv_manager
->lookup_quick_mode(this->iv_manager
, mid
, &n_i
,
827 { /* Hash(1) = prf(SKEYID_a, M-ID | Message after HASH payload) */
829 if (!get_nonce(message
, n_i
))
833 data
= chunk_from_thing(mid_n
);
836 { /* Hash(2) = prf(SKEYID_a, M-ID | Ni_b | Message after HASH) */
838 if (!get_nonce(message
, n_r
))
842 data
= chunk_cata("cc", chunk_from_thing(mid_n
), *n_i
);
845 { /* Hash(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */
847 data
= chunk_cata("cccc", octet_0
, chunk_from_thing(mid_n
),
850 /* we don't need the state anymore */
851 this->iv_manager
->remove_quick_mode(this->iv_manager
, mid
);
856 case INFORMATIONAL_V1
:
857 /* Hash = prf(SKEYID_a, M-ID | Message after HASH payload) */
858 data
= chunk_from_thing(mid_n
);
863 if (!this->prf
->set_key(this->prf
, this->skeyid_a
))
869 generator_t
*generator
;
872 generator
= generator_create_no_dbg();
873 msg
= get_message_data(message
, generator
);
874 if (!this->prf
->allocate_bytes(this->prf
, data
, NULL
) ||
875 !this->prf
->allocate_bytes(this->prf
, msg
, hash
))
877 generator
->destroy(generator
);
880 generator
->destroy(generator
);
884 if (!this->prf
->allocate_bytes(this->prf
, data
, hash
))
889 DBG3(DBG_IKE
, "%s %B", name
, hash
);
893 METHOD(keymat_v1_t
, get_iv
, bool,
894 private_keymat_v1_t
*this, uint32_t mid
, chunk_t
*out
)
896 return this->iv_manager
->get_iv(this->iv_manager
, mid
, out
);
899 METHOD(keymat_v1_t
, update_iv
, bool,
900 private_keymat_v1_t
*this, uint32_t mid
, chunk_t last_block
)
902 return this->iv_manager
->update_iv(this->iv_manager
, mid
, last_block
);
905 METHOD(keymat_v1_t
, confirm_iv
, bool,
906 private_keymat_v1_t
*this, uint32_t mid
)
908 return this->iv_manager
->confirm_iv(this->iv_manager
, mid
);
911 METHOD(keymat_t
, get_version
, ike_version_t
,
912 private_keymat_v1_t
*this)
917 METHOD(keymat_t
, create_dh
, diffie_hellman_t
*,
918 private_keymat_v1_t
*this, diffie_hellman_group_t group
)
920 return lib
->crypto
->create_dh(lib
->crypto
, group
);
923 METHOD(keymat_t
, create_nonce_gen
, nonce_gen_t
*,
924 private_keymat_v1_t
*this)
926 return lib
->crypto
->create_nonce_gen(lib
->crypto
);
929 METHOD(keymat_t
, get_aead
, aead_t
*,
930 private_keymat_v1_t
*this, bool in
)
935 METHOD(keymat_t
, destroy
, void,
936 private_keymat_v1_t
*this)
938 DESTROY_IF(this->prf
);
939 DESTROY_IF(this->prf_auth
);
940 DESTROY_IF(this->aead
);
941 DESTROY_IF(this->hasher
);
942 chunk_clear(&this->skeyid_d
);
943 chunk_clear(&this->skeyid_a
);
944 this->iv_manager
->destroy(this->iv_manager
);
951 keymat_v1_t
*keymat_v1_create(bool initiator
)
953 private_keymat_v1_t
*this;
958 .get_version
= _get_version
,
959 .create_dh
= _create_dh
,
960 .create_nonce_gen
= _create_nonce_gen
,
961 .get_aead
= _get_aead
,
964 .derive_ike_keys
= _derive_ike_keys
,
965 .derive_child_keys
= _derive_child_keys
,
966 .create_hasher
= _create_hasher
,
967 .get_hasher
= _get_hasher
,
968 .get_hash
= _get_hash
,
969 .get_hash_phase2
= _get_hash_phase2
,
971 .update_iv
= _update_iv
,
972 .confirm_iv
= _confirm_iv
,
974 .initiator
= initiator
,
975 .iv_manager
= iv_manager_create(0),
977 return &this->public;