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 case AUTH_XAUTH_RESP_PSK
:
435 { /* SKEYID = prf(pre-shared-key, Ni_b | Nr_b) */
442 psk
= shared_key
->get_key(shared_key
);
443 adjust_keylen(alg
, &psk
);
444 if (!this->prf
->set_key(this->prf
, psk
) ||
445 !this->prf
->allocate_bytes(this->prf
, nonces
, &skeyid
))
456 case AUTH_XAUTH_INIT_RSA
:
457 case AUTH_XAUTH_RESP_RSA
:
458 case AUTH_HYBRID_INIT_RSA
:
459 case AUTH_HYBRID_RESP_RSA
:
461 if (!this->prf
->set_key(this->prf
, nonces
) ||
462 !this->prf
->allocate_bytes(this->prf
, g_xy
, &skeyid
))
470 /* TODO-IKEv1: implement key derivation for other schemes */
471 /* authentication class not supported */
475 adjust_keylen(alg
, &skeyid
);
476 DBG4(DBG_IKE
, "SKEYID %B", &skeyid
);
478 /* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */
479 data
= chunk_cat("cccc", g_xy
, spi_i
, spi_r
, octet_0
);
480 if (!this->prf
->set_key(this->prf
, skeyid
) ||
481 !this->prf
->allocate_bytes(this->prf
, data
, &this->skeyid_d
))
488 DBG4(DBG_IKE
, "SKEYID_d %B", &this->skeyid_d
);
490 /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */
491 data
= chunk_cat("ccccc", this->skeyid_d
, g_xy
, spi_i
, spi_r
, octet_1
);
492 if (!this->prf
->allocate_bytes(this->prf
, data
, &this->skeyid_a
))
499 DBG4(DBG_IKE
, "SKEYID_a %B", &this->skeyid_a
);
501 /* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */
502 data
= chunk_cat("ccccc", this->skeyid_a
, g_xy
, spi_i
, spi_r
, octet_2
);
503 if (!this->prf
->allocate_bytes(this->prf
, data
, &skeyid_e
))
510 DBG4(DBG_IKE
, "SKEYID_e %B", &skeyid_e
);
517 alg
= PRF_HMAC_SHA2_256
;
520 alg
= PRF_HMAC_SHA2_384
;
523 alg
= PRF_HMAC_SHA2_512
;
526 /* use proposal algorithm */
529 this->prf_auth
= lib
->crypto
->create_prf(lib
->crypto
, alg
);
532 DBG1(DBG_IKE
, "%N %N not supported!",
533 transform_type_names
, PSEUDO_RANDOM_FUNCTION
,
534 pseudo_random_function_names
, alg
);
535 chunk_clear(&skeyid
);
538 if (!this->prf_auth
->set_key(this->prf_auth
, skeyid
))
540 chunk_clear(&skeyid
);
543 chunk_clear(&skeyid
);
545 this->aead
= create_aead(proposal
, this->prf
, skeyid_e
);
550 if (!this->hasher
&& !this->public.create_hasher(&this->public, proposal
))
555 dh
->get_my_public_value(dh
, &dh_me
);
556 g_xi
= this->initiator ? dh_me
: dh_other
;
557 g_xr
= this->initiator ? dh_other
: dh_me
;
559 /* initial IV = hash(g^xi | g^xr) */
560 data
= chunk_cata("cc", g_xi
, g_xr
);
562 if (!this->hasher
->allocate_hash(this->hasher
, data
, &this->phase1_iv
.iv
))
566 if (this->phase1_iv
.iv
.len
> this->aead
->get_block_size(this->aead
))
568 this->phase1_iv
.iv
.len
= this->aead
->get_block_size(this->aead
);
570 DBG4(DBG_IKE
, "initial IV %B", &this->phase1_iv
.iv
);
575 METHOD(keymat_v1_t
, derive_child_keys
, bool,
576 private_keymat_v1_t
*this, proposal_t
*proposal
, diffie_hellman_t
*dh
,
577 u_int32_t spi_i
, u_int32_t spi_r
, chunk_t nonce_i
, chunk_t nonce_r
,
578 chunk_t
*encr_i
, chunk_t
*integ_i
, chunk_t
*encr_r
, chunk_t
*integ_r
)
580 u_int16_t enc_alg
, int_alg
, enc_size
= 0, int_size
= 0;
582 prf_plus_t
*prf_plus
;
583 chunk_t seed
, secret
= chunk_empty
;
584 bool success
= FALSE
;
586 if (proposal
->get_algorithm(proposal
, ENCRYPTION_ALGORITHM
,
587 &enc_alg
, &enc_size
))
589 DBG2(DBG_CHD
, " using %N for encryption",
590 encryption_algorithm_names
, enc_alg
);
594 enc_size
= keymat_get_keylen_encr(enc_alg
);
596 if (enc_alg
!= ENCR_NULL
&& !enc_size
)
598 DBG1(DBG_CHD
, "no keylength defined for %N",
599 encryption_algorithm_names
, enc_alg
);
605 /* CCM/GCM/CTR/GMAC needs additional bytes */
608 case ENCR_AES_CCM_ICV8
:
609 case ENCR_AES_CCM_ICV12
:
610 case ENCR_AES_CCM_ICV16
:
611 case ENCR_CAMELLIA_CCM_ICV8
:
612 case ENCR_CAMELLIA_CCM_ICV12
:
613 case ENCR_CAMELLIA_CCM_ICV16
:
616 case ENCR_AES_GCM_ICV8
:
617 case ENCR_AES_GCM_ICV12
:
618 case ENCR_AES_GCM_ICV16
:
620 case ENCR_NULL_AUTH_AES_GMAC
:
628 if (proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
,
629 &int_alg
, &int_size
))
631 DBG2(DBG_CHD
, " using %N for integrity",
632 integrity_algorithm_names
, int_alg
);
636 int_size
= keymat_get_keylen_integ(int_alg
);
640 DBG1(DBG_CHD
, "no keylength defined for %N",
641 integrity_algorithm_names
, int_alg
);
648 /* KEYMAT = prf+(SKEYID_d, [ g(qm)^xy | ] protocol | SPI | Ni_b | Nr_b) */
649 if (!this->prf
->set_key(this->prf
, this->skeyid_d
))
653 protocol
= proposal
->get_protocol(proposal
);
656 if (dh
->get_shared_secret(dh
, &secret
) != SUCCESS
)
660 DBG4(DBG_CHD
, "DH secret %B", &secret
);
663 *encr_r
= *integ_r
= *encr_i
= *integ_i
= chunk_empty
;
664 seed
= chunk_cata("ccccc", secret
, chunk_from_thing(protocol
),
665 chunk_from_thing(spi_r
), nonce_i
, nonce_r
);
666 DBG4(DBG_CHD
, "initiator SA seed %B", &seed
);
668 prf_plus
= prf_plus_create(this->prf
, FALSE
, seed
);
670 !prf_plus
->allocate_bytes(prf_plus
, enc_size
, encr_i
) ||
671 !prf_plus
->allocate_bytes(prf_plus
, int_size
, integ_i
))
676 seed
= chunk_cata("ccccc", secret
, chunk_from_thing(protocol
),
677 chunk_from_thing(spi_i
), nonce_i
, nonce_r
);
678 DBG4(DBG_CHD
, "responder SA seed %B", &seed
);
679 prf_plus
->destroy(prf_plus
);
680 prf_plus
= prf_plus_create(this->prf
, FALSE
, seed
);
682 !prf_plus
->allocate_bytes(prf_plus
, enc_size
, encr_r
) ||
683 !prf_plus
->allocate_bytes(prf_plus
, int_size
, integ_r
))
690 DBG4(DBG_CHD
, "encryption initiator key %B", encr_i
);
691 DBG4(DBG_CHD
, "encryption responder key %B", encr_r
);
695 DBG4(DBG_CHD
, "integrity initiator key %B", integ_i
);
696 DBG4(DBG_CHD
, "integrity responder key %B", integ_r
);
704 chunk_clear(integ_i
);
706 chunk_clear(integ_r
);
708 DESTROY_IF(prf_plus
);
709 chunk_clear(&secret
);
714 METHOD(keymat_v1_t
, create_hasher
, bool,
715 private_keymat_v1_t
*this, proposal_t
*proposal
)
718 if (!proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
, &alg
, NULL
) ||
719 (alg
= auth_to_hash(alg
)) == HASH_UNKNOWN
)
721 DBG1(DBG_IKE
, "no %N selected", transform_type_names
, HASH_ALGORITHM
);
724 this->hasher
= lib
->crypto
->create_hasher(lib
->crypto
, alg
);
727 DBG1(DBG_IKE
, "%N %N not supported!",
728 transform_type_names
, HASH_ALGORITHM
,
729 hash_algorithm_names
, alg
);
735 METHOD(keymat_v1_t
, get_hasher
, hasher_t
*,
736 private_keymat_v1_t
*this)
741 METHOD(keymat_v1_t
, get_hash
, bool,
742 private_keymat_v1_t
*this, bool initiator
, chunk_t dh
, chunk_t dh_other
,
743 ike_sa_id_t
*ike_sa_id
, chunk_t sa_i
, chunk_t id
, chunk_t
*hash
)
746 u_int64_t spi
, spi_other
;
748 /* HASH_I = prf(SKEYID, g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b )
749 * HASH_R = prf(SKEYID, g^xr | g^xi | CKY-R | CKY-I | SAi_b | IDir_b )
753 spi
= ike_sa_id
->get_initiator_spi(ike_sa_id
);
754 spi_other
= ike_sa_id
->get_responder_spi(ike_sa_id
);
758 spi_other
= ike_sa_id
->get_initiator_spi(ike_sa_id
);
759 spi
= ike_sa_id
->get_responder_spi(ike_sa_id
);
761 data
= chunk_cat("cccccc", dh
, dh_other
,
762 chunk_from_thing(spi
), chunk_from_thing(spi_other
),
765 DBG3(DBG_IKE
, "HASH_%c data %B", initiator ?
'I' : 'R', &data
);
767 if (!this->prf_auth
->allocate_bytes(this->prf_auth
, data
, hash
))
773 DBG3(DBG_IKE
, "HASH_%c %B", initiator ?
'I' : 'R', hash
);
780 * Get the nonce value found in the given message.
781 * Returns FALSE if none is found.
783 static bool get_nonce(message_t
*message
, chunk_t
*n
)
785 nonce_payload_t
*nonce
;
786 nonce
= (nonce_payload_t
*)message
->get_payload(message
, NONCE_V1
);
789 *n
= nonce
->get_nonce(nonce
);
796 * Generate the message data in order to generate the hashes.
798 static chunk_t
get_message_data(message_t
*message
, generator_t
*generator
)
800 payload_t
*payload
, *next
;
801 enumerator_t
*enumerator
;
804 if (message
->is_encoded(message
))
805 { /* inbound, although the message is generated, we cannot access the
806 * cleartext message data, so generate it anyway */
807 enumerator
= message
->create_payload_enumerator(message
);
808 while (enumerator
->enumerate(enumerator
, &payload
))
810 if (payload
->get_type(payload
) == HASH_V1
)
814 generator
->generate_payload(generator
, payload
);
816 enumerator
->destroy(enumerator
);
820 /* outbound, generate the payloads (there is no HASH payload yet) */
821 enumerator
= message
->create_payload_enumerator(message
);
822 if (enumerator
->enumerate(enumerator
, &payload
))
824 while (enumerator
->enumerate(enumerator
, &next
))
826 payload
->set_next_type(payload
, next
->get_type(next
));
827 generator
->generate_payload(generator
, payload
);
830 payload
->set_next_type(payload
, NO_PAYLOAD
);
831 generator
->generate_payload(generator
, payload
);
833 enumerator
->destroy(enumerator
);
835 return generator
->get_chunk(generator
, &lenpos
);
839 * Try to find data about a Quick Mode with the given message ID,
840 * if none is found, state is generated.
842 static qm_data_t
*lookup_quick_mode(private_keymat_v1_t
*this, u_int32_t mid
)
844 enumerator_t
*enumerator
;
845 qm_data_t
*qm
, *found
= NULL
;
847 enumerator
= this->qms
->create_enumerator(this->qms
);
848 while (enumerator
->enumerate(enumerator
, &qm
))
851 { /* state gets moved to the front of the list */
852 this->qms
->remove_at(this->qms
, enumerator
);
857 enumerator
->destroy(enumerator
);
864 this->qms
->insert_first(this->qms
, found
);
865 /* remove least recently used state if maximum reached */
866 if (this->qms
->get_count(this->qms
) > MAX_QM
&&
867 this->qms
->remove_last(this->qms
, (void**)&qm
) == SUCCESS
)
874 METHOD(keymat_v1_t
, get_hash_phase2
, bool,
875 private_keymat_v1_t
*this, message_t
*message
, chunk_t
*hash
)
877 u_int32_t mid
, mid_n
;
878 chunk_t data
= chunk_empty
;
879 bool add_message
= TRUE
;
883 { /* no keys derived yet */
887 mid
= message
->get_message_id(message
);
890 /* Hashes are simple for most exchanges in Phase 2:
891 * Hash = prf(SKEYID_a, M-ID | Complete message after HASH payload)
892 * For Quick Mode there are three hashes:
893 * Hash(1) = same as above
894 * Hash(2) = prf(SKEYID_a, M-ID | Ni_b | Message after HASH payload)
895 * Hash(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b)
896 * So, for Quick Mode we keep track of the nonce values.
898 switch (message
->get_exchange_type(message
))
902 qm_data_t
*qm
= lookup_quick_mode(this, mid
);
904 { /* Hash(1) = prf(SKEYID_a, M-ID | Message after HASH payload) */
906 if (!get_nonce(message
, &qm
->n_i
))
910 data
= chunk_from_thing(mid_n
);
912 else if (!qm
->n_r
.ptr
)
913 { /* Hash(2) = prf(SKEYID_a, M-ID | Ni_b | Message after HASH) */
915 if (!get_nonce(message
, &qm
->n_r
))
919 data
= chunk_cata("cc", chunk_from_thing(mid_n
), qm
->n_i
);
922 { /* Hash(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */
924 data
= chunk_cata("cccc", octet_0
, chunk_from_thing(mid_n
),
927 /* we don't need the state anymore */
928 this->qms
->remove(this->qms
, qm
, NULL
);
934 case INFORMATIONAL_V1
:
935 /* Hash = prf(SKEYID_a, M-ID | Message after HASH payload) */
936 data
= chunk_from_thing(mid_n
);
941 if (!this->prf
->set_key(this->prf
, this->skeyid_a
))
947 generator_t
*generator
;
950 generator
= generator_create_no_dbg();
951 msg
= get_message_data(message
, generator
);
952 if (!this->prf
->allocate_bytes(this->prf
, data
, NULL
) ||
953 !this->prf
->allocate_bytes(this->prf
, msg
, hash
))
955 generator
->destroy(generator
);
958 generator
->destroy(generator
);
962 if (!this->prf
->allocate_bytes(this->prf
, data
, hash
))
967 DBG3(DBG_IKE
, "%s %B", name
, hash
);
974 static bool generate_iv(private_keymat_v1_t
*this, iv_data_t
*iv
)
976 if (iv
->mid
== 0 || iv
->iv
.ptr
)
977 { /* use last block of previous encrypted message */
979 iv
->iv
= iv
->last_block
;
980 iv
->last_block
= chunk_empty
;
984 /* initial phase 2 IV = hash(last_phase1_block | mid) */
988 net
= htonl(iv
->mid
);
989 data
= chunk_cata("cc", this->phase1_iv
.iv
, chunk_from_thing(net
));
990 if (!this->hasher
->allocate_hash(this->hasher
, data
, &iv
->iv
))
994 if (iv
->iv
.len
> this->aead
->get_block_size(this->aead
))
996 iv
->iv
.len
= this->aead
->get_block_size(this->aead
);
999 DBG4(DBG_IKE
, "next IV for MID %u %B", iv
->mid
, &iv
->iv
);
1004 * Try to find an IV for the given message ID, if not found, generate it.
1006 static iv_data_t
*lookup_iv(private_keymat_v1_t
*this, u_int32_t mid
)
1008 enumerator_t
*enumerator
;
1009 iv_data_t
*iv
, *found
= NULL
;
1013 return &this->phase1_iv
;
1016 enumerator
= this->ivs
->create_enumerator(this->ivs
);
1017 while (enumerator
->enumerate(enumerator
, &iv
))
1020 { /* IV gets moved to the front of the list */
1021 this->ivs
->remove_at(this->ivs
, enumerator
);
1026 enumerator
->destroy(enumerator
);
1032 if (!generate_iv(this, found
))
1034 iv_data_destroy(found
);
1038 this->ivs
->insert_first(this->ivs
, found
);
1039 /* remove least recently used IV if maximum reached */
1040 if (this->ivs
->get_count(this->ivs
) > MAX_IV
&&
1041 this->ivs
->remove_last(this->ivs
, (void**)&iv
) == SUCCESS
)
1043 iv_data_destroy(iv
);
1048 METHOD(keymat_v1_t
, get_iv
, bool,
1049 private_keymat_v1_t
*this, u_int32_t mid
, chunk_t
*out
)
1053 iv
= lookup_iv(this, mid
);
1062 METHOD(keymat_v1_t
, update_iv
, bool,
1063 private_keymat_v1_t
*this, u_int32_t mid
, chunk_t last_block
)
1065 iv_data_t
*iv
= lookup_iv(this, mid
);
1067 { /* update last block */
1068 chunk_free(&iv
->last_block
);
1069 iv
->last_block
= chunk_clone(last_block
);
1075 METHOD(keymat_v1_t
, confirm_iv
, bool,
1076 private_keymat_v1_t
*this, u_int32_t mid
)
1078 iv_data_t
*iv
= lookup_iv(this, mid
);
1081 return generate_iv(this, iv
);
1086 METHOD(keymat_t
, get_version
, ike_version_t
,
1087 private_keymat_v1_t
*this)
1092 METHOD(keymat_t
, create_dh
, diffie_hellman_t
*,
1093 private_keymat_v1_t
*this, diffie_hellman_group_t group
)
1095 return lib
->crypto
->create_dh(lib
->crypto
, group
);
1098 METHOD(keymat_t
, create_nonce_gen
, nonce_gen_t
*,
1099 private_keymat_v1_t
*this)
1101 return lib
->crypto
->create_nonce_gen(lib
->crypto
);
1104 METHOD(keymat_t
, get_aead
, aead_t
*,
1105 private_keymat_v1_t
*this, bool in
)
1110 METHOD(keymat_t
, destroy
, void,
1111 private_keymat_v1_t
*this)
1113 DESTROY_IF(this->prf
);
1114 DESTROY_IF(this->prf_auth
);
1115 DESTROY_IF(this->aead
);
1116 DESTROY_IF(this->hasher
);
1117 chunk_clear(&this->skeyid_d
);
1118 chunk_clear(&this->skeyid_a
);
1119 chunk_free(&this->phase1_iv
.iv
);
1120 chunk_free(&this->phase1_iv
.last_block
);
1121 this->ivs
->destroy_function(this->ivs
, (void*)iv_data_destroy
);
1122 this->qms
->destroy_function(this->qms
, (void*)qm_data_destroy
);
1129 keymat_v1_t
*keymat_v1_create(bool initiator
)
1131 private_keymat_v1_t
*this;
1136 .get_version
= _get_version
,
1137 .create_dh
= _create_dh
,
1138 .create_nonce_gen
= _create_nonce_gen
,
1139 .get_aead
= _get_aead
,
1140 .destroy
= _destroy
,
1142 .derive_ike_keys
= _derive_ike_keys
,
1143 .derive_child_keys
= _derive_child_keys
,
1144 .create_hasher
= _create_hasher
,
1145 .get_hasher
= _get_hasher
,
1146 .get_hash
= _get_hash
,
1147 .get_hash_phase2
= _get_hash_phase2
,
1149 .update_iv
= _update_iv
,
1150 .confirm_iv
= _confirm_iv
,
1152 .ivs
= linked_list_create(),
1153 .qms
= linked_list_create(),
1154 .initiator
= initiator
,
1157 return &this->public;