2 * Copyright (C) 2011 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
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>.
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
16 #include "keymat_v1.h"
19 #include <encoding/generator.h>
20 #include <encoding/payloads/nonce_payload.h>
21 #include <collections/linked_list.h>
23 typedef struct private_keymat_v1_t private_keymat_v1_t
;
26 * Max. number of IVs to track.
31 * Max. number of Quick Modes to track.
43 /** last block of encrypted message */
48 * Private data of an keymat_t object.
50 struct private_keymat_v1_t
{
53 * Public keymat_v1_t interface.
58 * IKE_SA Role, initiator or responder
68 * PRF to create Phase 1 HASH payloads
73 * Crypter wrapped in an aead_t interface
78 * Hasher used for IV generation (and other things like e.g. NAT-T)
83 * Key used for authentication during main mode
88 * Key to derive key material from for non-ISAKMP SAs, rekeying
93 * Key used for authentication after main mode
103 * Keep track of IVs for exchanges after phase 1. We store only a limited
104 * number of IVs in an MRU sort of way. Stores iv_data_t objects.
109 * Keep track of Nonces during Quick Mode exchanges. Only a limited number
110 * of QMs are tracked at the same time. Stores qm_data_t objects.
117 * Destroy an iv_data_t object.
119 static void iv_data_destroy(iv_data_t
*this)
121 chunk_free(&this->last_block
);
122 chunk_free(&this->iv
);
127 * Data stored for Quick Mode exchanges
132 /** Ni_b (Nonce from first message) */
134 /** Nr_b (Nonce from second message) */
139 * Destroy a qm_data_t object.
141 static void qm_data_destroy(qm_data_t
*this)
143 chunk_free(&this->n_i
);
144 chunk_free(&this->n_r
);
149 * Constants used in key derivation.
151 static const chunk_t octet_0
= chunk_from_chars(0x00);
152 static const chunk_t octet_1
= chunk_from_chars(0x01);
153 static const chunk_t octet_2
= chunk_from_chars(0x02);
156 * Simple aead_t implementation without support for authentication.
159 /** implements aead_t interface */
161 /** crypter to be used */
166 METHOD(aead_t
, encrypt
, bool,
167 private_aead_t
*this, chunk_t plain
, chunk_t assoc
, chunk_t iv
,
170 return this->crypter
->encrypt(this->crypter
, plain
, iv
, encrypted
);
173 METHOD(aead_t
, decrypt
, bool,
174 private_aead_t
*this, chunk_t encrypted
, chunk_t assoc
, chunk_t iv
,
177 return this->crypter
->decrypt(this->crypter
, encrypted
, iv
, plain
);
180 METHOD(aead_t
, get_block_size
, size_t,
181 private_aead_t
*this)
183 return this->crypter
->get_block_size(this->crypter
);
186 METHOD(aead_t
, get_icv_size
, size_t,
187 private_aead_t
*this)
192 METHOD(aead_t
, get_iv_size
, size_t,
193 private_aead_t
*this)
195 /* in order to create the messages properly we return 0 here */
199 METHOD(aead_t
, get_key_size
, size_t,
200 private_aead_t
*this)
202 return this->crypter
->get_key_size(this->crypter
);
205 METHOD(aead_t
, set_key
, bool,
206 private_aead_t
*this, chunk_t key
)
208 return this->crypter
->set_key(this->crypter
, key
);
211 METHOD(aead_t
, aead_destroy
, void,
212 private_aead_t
*this)
214 this->crypter
->destroy(this->crypter
);
219 * Expand SKEYID_e according to Appendix B in RFC 2409.
220 * TODO-IKEv1: verify keys (e.g. for weak keys, see Appendix B)
222 static bool expand_skeyid_e(chunk_t skeyid_e
, size_t key_size
, prf_t
*prf
,
229 if (skeyid_e
.len
>= key_size
)
230 { /* no expansion required, reduce to key_size */
231 skeyid_e
.len
= key_size
;
235 block_size
= prf
->get_block_size(prf
);
236 *ka
= chunk_alloc((key_size
/ block_size
+ 1) * block_size
);
239 /* Ka = K1 | K2 | ..., K1 = prf(SKEYID_e, 0), K2 = prf(SKEYID_e, K1) ... */
240 if (!prf
->set_key(prf
, skeyid_e
))
243 chunk_clear(&skeyid_e
);
247 for (i
= 0; i
< key_size
; i
+= block_size
)
249 if (!prf
->get_bytes(prf
, seed
, ka
->ptr
+ i
))
252 chunk_clear(&skeyid_e
);
255 seed
= chunk_create(ka
->ptr
+ i
, block_size
);
257 chunk_clear(&skeyid_e
);
262 * Create a simple implementation of the aead_t interface which only encrypts
265 static aead_t
*create_aead(proposal_t
*proposal
, prf_t
*prf
, chunk_t skeyid_e
)
267 private_aead_t
*this;
268 u_int16_t alg
, key_size
;
272 if (!proposal
->get_algorithm(proposal
, ENCRYPTION_ALGORITHM
, &alg
,
275 DBG1(DBG_IKE
, "no %N selected",
276 transform_type_names
, ENCRYPTION_ALGORITHM
);
279 crypter
= lib
->crypto
->create_crypter(lib
->crypto
, alg
, key_size
/ 8);
282 DBG1(DBG_IKE
, "%N %N (key size %d) not supported!",
283 transform_type_names
, ENCRYPTION_ALGORITHM
,
284 encryption_algorithm_names
, alg
, key_size
);
287 key_size
= crypter
->get_key_size(crypter
);
288 if (!expand_skeyid_e(skeyid_e
, crypter
->get_key_size(crypter
), prf
, &ka
))
292 DBG4(DBG_IKE
, "encryption key Ka %B", &ka
);
293 if (!crypter
->set_key(crypter
, ka
))
304 .get_block_size
= _get_block_size
,
305 .get_icv_size
= _get_icv_size
,
306 .get_iv_size
= _get_iv_size
,
307 .get_key_size
= _get_key_size
,
309 .destroy
= _aead_destroy
,
317 * Converts integrity algorithm to PRF algorithm
319 static u_int16_t
auth_to_prf(u_int16_t alg
)
323 case AUTH_HMAC_SHA1_96
:
324 return PRF_HMAC_SHA1
;
325 case AUTH_HMAC_SHA2_256_128
:
326 return PRF_HMAC_SHA2_256
;
327 case AUTH_HMAC_SHA2_384_192
:
328 return PRF_HMAC_SHA2_384
;
329 case AUTH_HMAC_SHA2_512_256
:
330 return PRF_HMAC_SHA2_512
;
331 case AUTH_HMAC_MD5_96
:
333 case AUTH_AES_XCBC_96
:
334 return PRF_AES128_XCBC
;
336 return PRF_UNDEFINED
;
341 * Converts integrity algorithm to hash algorithm
343 static u_int16_t
auth_to_hash(u_int16_t alg
)
347 case AUTH_HMAC_SHA1_96
:
349 case AUTH_HMAC_SHA2_256_128
:
351 case AUTH_HMAC_SHA2_384_192
:
353 case AUTH_HMAC_SHA2_512_256
:
355 case AUTH_HMAC_MD5_96
:
363 * Adjust the key length for PRF algorithms that expect a fixed key length.
365 static void adjust_keylen(u_int16_t alg
, chunk_t
*key
)
369 case PRF_AES128_XCBC
:
370 /* while rfc4434 defines variable keys for AES-XCBC, rfc3664 does
371 * not and therefore fixed key semantics apply to XCBC for key
373 key
->len
= min(key
->len
, 16);
376 /* all other algorithms use variable key length */
381 METHOD(keymat_v1_t
, derive_ike_keys
, bool,
382 private_keymat_v1_t
*this, proposal_t
*proposal
, diffie_hellman_t
*dh
,
383 chunk_t dh_other
, chunk_t nonce_i
, chunk_t nonce_r
, ike_sa_id_t
*id
,
384 auth_method_t auth
, shared_key_t
*shared_key
)
386 chunk_t g_xy
, g_xi
, g_xr
, dh_me
, spi_i
, spi_r
, nonces
, data
, skeyid_e
;
390 spi_i
= chunk_alloca(sizeof(u_int64_t
));
391 spi_r
= chunk_alloca(sizeof(u_int64_t
));
393 if (!proposal
->get_algorithm(proposal
, PSEUDO_RANDOM_FUNCTION
, &alg
, NULL
))
394 { /* no PRF negotiated, use HMAC version of integrity algorithm instead */
395 if (!proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
, &alg
, NULL
)
396 || (alg
= auth_to_prf(alg
)) == PRF_UNDEFINED
)
398 DBG1(DBG_IKE
, "no %N selected",
399 transform_type_names
, PSEUDO_RANDOM_FUNCTION
);
403 this->prf
= lib
->crypto
->create_prf(lib
->crypto
, alg
);
406 DBG1(DBG_IKE
, "%N %N not supported!",
407 transform_type_names
, PSEUDO_RANDOM_FUNCTION
,
408 pseudo_random_function_names
, alg
);
411 if (this->prf
->get_block_size(this->prf
) <
412 this->prf
->get_key_size(this->prf
))
413 { /* TODO-IKEv1: support PRF output expansion (RFC 2409, Appendix B) */
414 DBG1(DBG_IKE
, "expansion of %N %N output not supported!",
415 transform_type_names
, PSEUDO_RANDOM_FUNCTION
,
416 pseudo_random_function_names
, alg
);
420 if (dh
->get_shared_secret(dh
, &g_xy
) != SUCCESS
)
424 DBG4(DBG_IKE
, "shared Diffie Hellman secret %B", &g_xy
);
426 *((u_int64_t
*)spi_i
.ptr
) = id
->get_initiator_spi(id
);
427 *((u_int64_t
*)spi_r
.ptr
) = id
->get_responder_spi(id
);
428 nonces
= chunk_cata("cc", nonce_i
, nonce_r
);
433 case AUTH_XAUTH_INIT_PSK
:
434 { /* SKEYID = prf(pre-shared-key, Ni_b | Nr_b) */
441 psk
= shared_key
->get_key(shared_key
);
442 adjust_keylen(alg
, &psk
);
443 if (!this->prf
->set_key(this->prf
, psk
) ||
444 !this->prf
->allocate_bytes(this->prf
, nonces
, &skeyid
))
455 case AUTH_XAUTH_INIT_RSA
:
456 case AUTH_XAUTH_RESP_RSA
:
457 case AUTH_HYBRID_INIT_RSA
:
458 case AUTH_HYBRID_RESP_RSA
:
460 if (!this->prf
->set_key(this->prf
, nonces
) ||
461 !this->prf
->allocate_bytes(this->prf
, g_xy
, &skeyid
))
469 /* TODO-IKEv1: implement key derivation for other schemes */
470 /* authentication class not supported */
474 adjust_keylen(alg
, &skeyid
);
475 DBG4(DBG_IKE
, "SKEYID %B", &skeyid
);
477 /* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */
478 data
= chunk_cat("cccc", g_xy
, spi_i
, spi_r
, octet_0
);
479 if (!this->prf
->set_key(this->prf
, skeyid
) ||
480 !this->prf
->allocate_bytes(this->prf
, data
, &this->skeyid_d
))
487 DBG4(DBG_IKE
, "SKEYID_d %B", &this->skeyid_d
);
489 /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */
490 data
= chunk_cat("ccccc", this->skeyid_d
, g_xy
, spi_i
, spi_r
, octet_1
);
491 if (!this->prf
->allocate_bytes(this->prf
, data
, &this->skeyid_a
))
498 DBG4(DBG_IKE
, "SKEYID_a %B", &this->skeyid_a
);
500 /* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */
501 data
= chunk_cat("ccccc", this->skeyid_a
, g_xy
, spi_i
, spi_r
, octet_2
);
502 if (!this->prf
->allocate_bytes(this->prf
, data
, &skeyid_e
))
509 DBG4(DBG_IKE
, "SKEYID_e %B", &skeyid_e
);
516 alg
= PRF_HMAC_SHA2_256
;
519 alg
= PRF_HMAC_SHA2_384
;
522 alg
= PRF_HMAC_SHA2_512
;
525 /* use proposal algorithm */
528 this->prf_auth
= lib
->crypto
->create_prf(lib
->crypto
, alg
);
531 DBG1(DBG_IKE
, "%N %N not supported!",
532 transform_type_names
, PSEUDO_RANDOM_FUNCTION
,
533 pseudo_random_function_names
, alg
);
534 chunk_clear(&skeyid
);
537 if (!this->prf_auth
->set_key(this->prf_auth
, skeyid
))
539 chunk_clear(&skeyid
);
542 chunk_clear(&skeyid
);
544 this->aead
= create_aead(proposal
, this->prf
, skeyid_e
);
549 if (!this->hasher
&& !this->public.create_hasher(&this->public, proposal
))
554 dh
->get_my_public_value(dh
, &dh_me
);
555 g_xi
= this->initiator ? dh_me
: dh_other
;
556 g_xr
= this->initiator ? dh_other
: dh_me
;
558 /* initial IV = hash(g^xi | g^xr) */
559 data
= chunk_cata("cc", g_xi
, g_xr
);
561 if (!this->hasher
->allocate_hash(this->hasher
, data
, &this->phase1_iv
.iv
))
565 if (this->phase1_iv
.iv
.len
> this->aead
->get_block_size(this->aead
))
567 this->phase1_iv
.iv
.len
= this->aead
->get_block_size(this->aead
);
569 DBG4(DBG_IKE
, "initial IV %B", &this->phase1_iv
.iv
);
574 METHOD(keymat_v1_t
, derive_child_keys
, bool,
575 private_keymat_v1_t
*this, proposal_t
*proposal
, diffie_hellman_t
*dh
,
576 u_int32_t spi_i
, u_int32_t spi_r
, chunk_t nonce_i
, chunk_t nonce_r
,
577 chunk_t
*encr_i
, chunk_t
*integ_i
, chunk_t
*encr_r
, chunk_t
*integ_r
)
579 u_int16_t enc_alg
, int_alg
, enc_size
= 0, int_size
= 0;
581 prf_plus_t
*prf_plus
;
582 chunk_t seed
, secret
= chunk_empty
;
583 bool success
= FALSE
;
585 if (proposal
->get_algorithm(proposal
, ENCRYPTION_ALGORITHM
,
586 &enc_alg
, &enc_size
))
588 DBG2(DBG_CHD
, " using %N for encryption",
589 encryption_algorithm_names
, enc_alg
);
593 enc_size
= keymat_get_keylen_encr(enc_alg
);
595 if (enc_alg
!= ENCR_NULL
&& !enc_size
)
597 DBG1(DBG_CHD
, "no keylength defined for %N",
598 encryption_algorithm_names
, enc_alg
);
604 /* CCM/GCM/CTR/GMAC needs additional bytes */
607 case ENCR_AES_CCM_ICV8
:
608 case ENCR_AES_CCM_ICV12
:
609 case ENCR_AES_CCM_ICV16
:
610 case ENCR_CAMELLIA_CCM_ICV8
:
611 case ENCR_CAMELLIA_CCM_ICV12
:
612 case ENCR_CAMELLIA_CCM_ICV16
:
615 case ENCR_AES_GCM_ICV8
:
616 case ENCR_AES_GCM_ICV12
:
617 case ENCR_AES_GCM_ICV16
:
619 case ENCR_NULL_AUTH_AES_GMAC
:
627 if (proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
,
628 &int_alg
, &int_size
))
630 DBG2(DBG_CHD
, " using %N for integrity",
631 integrity_algorithm_names
, int_alg
);
635 int_size
= keymat_get_keylen_integ(int_alg
);
639 DBG1(DBG_CHD
, "no keylength defined for %N",
640 integrity_algorithm_names
, int_alg
);
647 /* KEYMAT = prf+(SKEYID_d, [ g(qm)^xy | ] protocol | SPI | Ni_b | Nr_b) */
648 if (!this->prf
->set_key(this->prf
, this->skeyid_d
))
652 protocol
= proposal
->get_protocol(proposal
);
655 if (dh
->get_shared_secret(dh
, &secret
) != SUCCESS
)
659 DBG4(DBG_CHD
, "DH secret %B", &secret
);
662 *encr_r
= *integ_r
= *encr_i
= *integ_i
= chunk_empty
;
663 seed
= chunk_cata("ccccc", secret
, chunk_from_thing(protocol
),
664 chunk_from_thing(spi_r
), nonce_i
, nonce_r
);
665 DBG4(DBG_CHD
, "initiator SA seed %B", &seed
);
667 prf_plus
= prf_plus_create(this->prf
, FALSE
, seed
);
669 !prf_plus
->allocate_bytes(prf_plus
, enc_size
, encr_i
) ||
670 !prf_plus
->allocate_bytes(prf_plus
, int_size
, integ_i
))
675 seed
= chunk_cata("ccccc", secret
, chunk_from_thing(protocol
),
676 chunk_from_thing(spi_i
), nonce_i
, nonce_r
);
677 DBG4(DBG_CHD
, "responder SA seed %B", &seed
);
678 prf_plus
->destroy(prf_plus
);
679 prf_plus
= prf_plus_create(this->prf
, FALSE
, seed
);
681 !prf_plus
->allocate_bytes(prf_plus
, enc_size
, encr_r
) ||
682 !prf_plus
->allocate_bytes(prf_plus
, int_size
, integ_r
))
689 DBG4(DBG_CHD
, "encryption initiator key %B", encr_i
);
690 DBG4(DBG_CHD
, "encryption responder key %B", encr_r
);
694 DBG4(DBG_CHD
, "integrity initiator key %B", integ_i
);
695 DBG4(DBG_CHD
, "integrity responder key %B", integ_r
);
703 chunk_clear(integ_i
);
705 chunk_clear(integ_r
);
707 DESTROY_IF(prf_plus
);
708 chunk_clear(&secret
);
713 METHOD(keymat_v1_t
, create_hasher
, bool,
714 private_keymat_v1_t
*this, proposal_t
*proposal
)
717 if (!proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
, &alg
, NULL
) ||
718 (alg
= auth_to_hash(alg
)) == HASH_UNKNOWN
)
720 DBG1(DBG_IKE
, "no %N selected", transform_type_names
, HASH_ALGORITHM
);
723 this->hasher
= lib
->crypto
->create_hasher(lib
->crypto
, alg
);
726 DBG1(DBG_IKE
, "%N %N not supported!",
727 transform_type_names
, HASH_ALGORITHM
,
728 hash_algorithm_names
, alg
);
734 METHOD(keymat_v1_t
, get_hasher
, hasher_t
*,
735 private_keymat_v1_t
*this)
740 METHOD(keymat_v1_t
, get_hash
, bool,
741 private_keymat_v1_t
*this, bool initiator
, chunk_t dh
, chunk_t dh_other
,
742 ike_sa_id_t
*ike_sa_id
, chunk_t sa_i
, chunk_t id
, chunk_t
*hash
)
745 u_int64_t spi
, spi_other
;
747 /* HASH_I = prf(SKEYID, g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b )
748 * HASH_R = prf(SKEYID, g^xr | g^xi | CKY-R | CKY-I | SAi_b | IDir_b )
752 spi
= ike_sa_id
->get_initiator_spi(ike_sa_id
);
753 spi_other
= ike_sa_id
->get_responder_spi(ike_sa_id
);
757 spi_other
= ike_sa_id
->get_initiator_spi(ike_sa_id
);
758 spi
= ike_sa_id
->get_responder_spi(ike_sa_id
);
760 data
= chunk_cat("cccccc", dh
, dh_other
,
761 chunk_from_thing(spi
), chunk_from_thing(spi_other
),
764 DBG3(DBG_IKE
, "HASH_%c data %B", initiator ?
'I' : 'R', &data
);
766 if (!this->prf_auth
->allocate_bytes(this->prf_auth
, data
, hash
))
772 DBG3(DBG_IKE
, "HASH_%c %B", initiator ?
'I' : 'R', hash
);
779 * Get the nonce value found in the given message.
780 * Returns FALSE if none is found.
782 static bool get_nonce(message_t
*message
, chunk_t
*n
)
784 nonce_payload_t
*nonce
;
785 nonce
= (nonce_payload_t
*)message
->get_payload(message
, NONCE_V1
);
788 *n
= nonce
->get_nonce(nonce
);
795 * Generate the message data in order to generate the hashes.
797 static chunk_t
get_message_data(message_t
*message
, generator_t
*generator
)
799 payload_t
*payload
, *next
;
800 enumerator_t
*enumerator
;
803 if (message
->is_encoded(message
))
804 { /* inbound, although the message is generated, we cannot access the
805 * cleartext message data, so generate it anyway */
806 enumerator
= message
->create_payload_enumerator(message
);
807 while (enumerator
->enumerate(enumerator
, &payload
))
809 if (payload
->get_type(payload
) == HASH_V1
)
813 generator
->generate_payload(generator
, payload
);
815 enumerator
->destroy(enumerator
);
819 /* outbound, generate the payloads (there is no HASH payload yet) */
820 enumerator
= message
->create_payload_enumerator(message
);
821 if (enumerator
->enumerate(enumerator
, &payload
))
823 while (enumerator
->enumerate(enumerator
, &next
))
825 payload
->set_next_type(payload
, next
->get_type(next
));
826 generator
->generate_payload(generator
, payload
);
829 payload
->set_next_type(payload
, NO_PAYLOAD
);
830 generator
->generate_payload(generator
, payload
);
832 enumerator
->destroy(enumerator
);
834 return generator
->get_chunk(generator
, &lenpos
);
838 * Try to find data about a Quick Mode with the given message ID,
839 * if none is found, state is generated.
841 static qm_data_t
*lookup_quick_mode(private_keymat_v1_t
*this, u_int32_t mid
)
843 enumerator_t
*enumerator
;
844 qm_data_t
*qm
, *found
= NULL
;
846 enumerator
= this->qms
->create_enumerator(this->qms
);
847 while (enumerator
->enumerate(enumerator
, &qm
))
850 { /* state gets moved to the front of the list */
851 this->qms
->remove_at(this->qms
, enumerator
);
856 enumerator
->destroy(enumerator
);
863 this->qms
->insert_first(this->qms
, found
);
864 /* remove least recently used state if maximum reached */
865 if (this->qms
->get_count(this->qms
) > MAX_QM
&&
866 this->qms
->remove_last(this->qms
, (void**)&qm
) == SUCCESS
)
873 METHOD(keymat_v1_t
, get_hash_phase2
, bool,
874 private_keymat_v1_t
*this, message_t
*message
, chunk_t
*hash
)
876 u_int32_t mid
, mid_n
;
877 chunk_t data
= chunk_empty
;
878 bool add_message
= TRUE
;
882 { /* no keys derived yet */
886 mid
= message
->get_message_id(message
);
889 /* Hashes are simple for most exchanges in Phase 2:
890 * Hash = prf(SKEYID_a, M-ID | Complete message after HASH payload)
891 * For Quick Mode there are three hashes:
892 * Hash(1) = same as above
893 * Hash(2) = prf(SKEYID_a, M-ID | Ni_b | Message after HASH payload)
894 * Hash(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b)
895 * So, for Quick Mode we keep track of the nonce values.
897 switch (message
->get_exchange_type(message
))
901 qm_data_t
*qm
= lookup_quick_mode(this, mid
);
903 { /* Hash(1) = prf(SKEYID_a, M-ID | Message after HASH payload) */
905 if (!get_nonce(message
, &qm
->n_i
))
909 data
= chunk_from_thing(mid_n
);
911 else if (!qm
->n_r
.ptr
)
912 { /* Hash(2) = prf(SKEYID_a, M-ID | Ni_b | Message after HASH) */
914 if (!get_nonce(message
, &qm
->n_r
))
918 data
= chunk_cata("cc", chunk_from_thing(mid_n
), qm
->n_i
);
921 { /* Hash(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */
923 data
= chunk_cata("cccc", octet_0
, chunk_from_thing(mid_n
),
926 /* we don't need the state anymore */
927 this->qms
->remove(this->qms
, qm
, NULL
);
933 case INFORMATIONAL_V1
:
934 /* Hash = prf(SKEYID_a, M-ID | Message after HASH payload) */
935 data
= chunk_from_thing(mid_n
);
940 if (!this->prf
->set_key(this->prf
, this->skeyid_a
))
946 generator_t
*generator
;
949 generator
= generator_create_no_dbg();
950 msg
= get_message_data(message
, generator
);
951 if (!this->prf
->allocate_bytes(this->prf
, data
, NULL
) ||
952 !this->prf
->allocate_bytes(this->prf
, msg
, hash
))
954 generator
->destroy(generator
);
957 generator
->destroy(generator
);
961 if (!this->prf
->allocate_bytes(this->prf
, data
, hash
))
966 DBG3(DBG_IKE
, "%s %B", name
, hash
);
973 static bool generate_iv(private_keymat_v1_t
*this, iv_data_t
*iv
)
975 if (iv
->mid
== 0 || iv
->iv
.ptr
)
976 { /* use last block of previous encrypted message */
978 iv
->iv
= iv
->last_block
;
979 iv
->last_block
= chunk_empty
;
983 /* initial phase 2 IV = hash(last_phase1_block | mid) */
987 net
= htonl(iv
->mid
);
988 data
= chunk_cata("cc", this->phase1_iv
.iv
, chunk_from_thing(net
));
989 if (!this->hasher
->allocate_hash(this->hasher
, data
, &iv
->iv
))
993 if (iv
->iv
.len
> this->aead
->get_block_size(this->aead
))
995 iv
->iv
.len
= this->aead
->get_block_size(this->aead
);
998 DBG4(DBG_IKE
, "next IV for MID %u %B", iv
->mid
, &iv
->iv
);
1003 * Try to find an IV for the given message ID, if not found, generate it.
1005 static iv_data_t
*lookup_iv(private_keymat_v1_t
*this, u_int32_t mid
)
1007 enumerator_t
*enumerator
;
1008 iv_data_t
*iv
, *found
= NULL
;
1012 return &this->phase1_iv
;
1015 enumerator
= this->ivs
->create_enumerator(this->ivs
);
1016 while (enumerator
->enumerate(enumerator
, &iv
))
1019 { /* IV gets moved to the front of the list */
1020 this->ivs
->remove_at(this->ivs
, enumerator
);
1025 enumerator
->destroy(enumerator
);
1031 if (!generate_iv(this, found
))
1033 iv_data_destroy(found
);
1037 this->ivs
->insert_first(this->ivs
, found
);
1038 /* remove least recently used IV if maximum reached */
1039 if (this->ivs
->get_count(this->ivs
) > MAX_IV
&&
1040 this->ivs
->remove_last(this->ivs
, (void**)&iv
) == SUCCESS
)
1042 iv_data_destroy(iv
);
1047 METHOD(keymat_v1_t
, get_iv
, bool,
1048 private_keymat_v1_t
*this, u_int32_t mid
, chunk_t
*out
)
1052 iv
= lookup_iv(this, mid
);
1061 METHOD(keymat_v1_t
, update_iv
, bool,
1062 private_keymat_v1_t
*this, u_int32_t mid
, chunk_t last_block
)
1064 iv_data_t
*iv
= lookup_iv(this, mid
);
1066 { /* update last block */
1067 chunk_free(&iv
->last_block
);
1068 iv
->last_block
= chunk_clone(last_block
);
1074 METHOD(keymat_v1_t
, confirm_iv
, bool,
1075 private_keymat_v1_t
*this, u_int32_t mid
)
1077 iv_data_t
*iv
= lookup_iv(this, mid
);
1080 return generate_iv(this, iv
);
1085 METHOD(keymat_t
, get_version
, ike_version_t
,
1086 private_keymat_v1_t
*this)
1091 METHOD(keymat_t
, create_dh
, diffie_hellman_t
*,
1092 private_keymat_v1_t
*this, diffie_hellman_group_t group
)
1094 return lib
->crypto
->create_dh(lib
->crypto
, group
);
1097 METHOD(keymat_t
, create_nonce_gen
, nonce_gen_t
*,
1098 private_keymat_v1_t
*this)
1100 return lib
->crypto
->create_nonce_gen(lib
->crypto
);
1103 METHOD(keymat_t
, get_aead
, aead_t
*,
1104 private_keymat_v1_t
*this, bool in
)
1109 METHOD(keymat_t
, destroy
, void,
1110 private_keymat_v1_t
*this)
1112 DESTROY_IF(this->prf
);
1113 DESTROY_IF(this->prf_auth
);
1114 DESTROY_IF(this->aead
);
1115 DESTROY_IF(this->hasher
);
1116 chunk_clear(&this->skeyid_d
);
1117 chunk_clear(&this->skeyid_a
);
1118 chunk_free(&this->phase1_iv
.iv
);
1119 chunk_free(&this->phase1_iv
.last_block
);
1120 this->ivs
->destroy_function(this->ivs
, (void*)iv_data_destroy
);
1121 this->qms
->destroy_function(this->qms
, (void*)qm_data_destroy
);
1128 keymat_v1_t
*keymat_v1_create(bool initiator
)
1130 private_keymat_v1_t
*this;
1135 .get_version
= _get_version
,
1136 .create_dh
= _create_dh
,
1137 .create_nonce_gen
= _create_nonce_gen
,
1138 .get_aead
= _get_aead
,
1139 .destroy
= _destroy
,
1141 .derive_ike_keys
= _derive_ike_keys
,
1142 .derive_child_keys
= _derive_child_keys
,
1143 .create_hasher
= _create_hasher
,
1144 .get_hasher
= _get_hasher
,
1145 .get_hash
= _get_hash
,
1146 .get_hash_phase2
= _get_hash_phase2
,
1148 .update_iv
= _update_iv
,
1149 .confirm_iv
= _confirm_iv
,
1151 .ivs
= linked_list_create(),
1152 .qms
= linked_list_create(),
1153 .initiator
= initiator
,
1156 return &this->public;