2 * Copyright (C) 2008 Martin Willi
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_v2.h"
19 #include <crypto/prf_plus.h>
21 typedef struct private_keymat_v2_t private_keymat_v2_t
;
24 * Private data of an keymat_t object.
26 struct private_keymat_v2_t
{
29 * Public keymat_v2_t interface.
34 * IKE_SA Role, initiator or responder
54 * Negotiated PRF algorithm
56 pseudo_random_function_t prf_alg
;
59 * Key to derive key material from for CHILD_SAs, rekeying
64 * Key to build outging authentication data (SKp)
69 * Key to verify incoming authentication data (SKp)
74 METHOD(keymat_t
, get_version
, ike_version_t
,
75 private_keymat_v2_t
*this)
80 METHOD(keymat_t
, create_dh
, diffie_hellman_t
*,
81 private_keymat_v2_t
*this, diffie_hellman_group_t group
)
83 return lib
->crypto
->create_dh(lib
->crypto
, group
);
86 METHOD(keymat_t
, create_nonce_gen
, nonce_gen_t
*,
87 private_keymat_v2_t
*this)
89 return lib
->crypto
->create_nonce_gen(lib
->crypto
);
93 * Derive IKE keys for a combined AEAD algorithm
95 static bool derive_ike_aead(private_keymat_v2_t
*this, u_int16_t alg
,
96 u_int16_t key_size
, prf_plus_t
*prf_plus
)
98 aead_t
*aead_i
, *aead_r
;
99 chunk_t key
= chunk_empty
;
101 /* SK_ei/SK_er used for encryption */
102 aead_i
= lib
->crypto
->create_aead(lib
->crypto
, alg
, key_size
/ 8);
103 aead_r
= lib
->crypto
->create_aead(lib
->crypto
, alg
, key_size
/ 8);
104 if (aead_i
== NULL
|| aead_r
== NULL
)
106 DBG1(DBG_IKE
, "%N %N (key size %d) not supported!",
107 transform_type_names
, ENCRYPTION_ALGORITHM
,
108 encryption_algorithm_names
, alg
, key_size
);
111 key_size
= aead_i
->get_key_size(aead_i
);
112 if (key_size
!= aead_r
->get_key_size(aead_r
))
116 if (!prf_plus
->allocate_bytes(prf_plus
, key_size
, &key
))
120 DBG4(DBG_IKE
, "Sk_ei secret %B", &key
);
121 if (!aead_i
->set_key(aead_i
, key
))
127 if (!prf_plus
->allocate_bytes(prf_plus
, key_size
, &key
))
131 DBG4(DBG_IKE
, "Sk_er secret %B", &key
);
132 if (!aead_r
->set_key(aead_r
, key
))
139 this->aead_in
= aead_r
;
140 this->aead_out
= aead_i
;
144 this->aead_in
= aead_i
;
145 this->aead_out
= aead_r
;
147 aead_i
= aead_r
= NULL
;
153 return this->aead_in
&& this->aead_out
;
157 * Derive IKE keys for traditional encryption and MAC algorithms
159 static bool derive_ike_traditional(private_keymat_v2_t
*this, u_int16_t enc_alg
,
160 u_int16_t enc_size
, u_int16_t int_alg
, prf_plus_t
*prf_plus
)
162 crypter_t
*crypter_i
= NULL
, *crypter_r
= NULL
;
163 signer_t
*signer_i
, *signer_r
;
165 chunk_t key
= chunk_empty
;
167 signer_i
= lib
->crypto
->create_signer(lib
->crypto
, int_alg
);
168 signer_r
= lib
->crypto
->create_signer(lib
->crypto
, int_alg
);
169 crypter_i
= lib
->crypto
->create_crypter(lib
->crypto
, enc_alg
, enc_size
/ 8);
170 crypter_r
= lib
->crypto
->create_crypter(lib
->crypto
, enc_alg
, enc_size
/ 8);
171 if (signer_i
== NULL
|| signer_r
== NULL
)
173 DBG1(DBG_IKE
, "%N %N not supported!",
174 transform_type_names
, INTEGRITY_ALGORITHM
,
175 integrity_algorithm_names
, int_alg
);
178 if (crypter_i
== NULL
|| crypter_r
== NULL
)
180 DBG1(DBG_IKE
, "%N %N (key size %d) not supported!",
181 transform_type_names
, ENCRYPTION_ALGORITHM
,
182 encryption_algorithm_names
, enc_alg
, enc_size
);
186 /* SK_ai/SK_ar used for integrity protection */
187 key_size
= signer_i
->get_key_size(signer_i
);
189 if (!prf_plus
->allocate_bytes(prf_plus
, key_size
, &key
))
193 DBG4(DBG_IKE
, "Sk_ai secret %B", &key
);
194 if (!signer_i
->set_key(signer_i
, key
))
200 if (!prf_plus
->allocate_bytes(prf_plus
, key_size
, &key
))
204 DBG4(DBG_IKE
, "Sk_ar secret %B", &key
);
205 if (!signer_r
->set_key(signer_r
, key
))
211 /* SK_ei/SK_er used for encryption */
212 key_size
= crypter_i
->get_key_size(crypter_i
);
214 if (!prf_plus
->allocate_bytes(prf_plus
, key_size
, &key
))
218 DBG4(DBG_IKE
, "Sk_ei secret %B", &key
);
219 if (!crypter_i
->set_key(crypter_i
, key
))
225 if (!prf_plus
->allocate_bytes(prf_plus
, key_size
, &key
))
229 DBG4(DBG_IKE
, "Sk_er secret %B", &key
);
230 if (!crypter_r
->set_key(crypter_r
, key
))
237 this->aead_in
= aead_create(crypter_r
, signer_r
);
238 this->aead_out
= aead_create(crypter_i
, signer_i
);
242 this->aead_in
= aead_create(crypter_i
, signer_i
);
243 this->aead_out
= aead_create(crypter_r
, signer_r
);
245 signer_i
= signer_r
= NULL
;
246 crypter_i
= crypter_r
= NULL
;
250 DESTROY_IF(signer_i
);
251 DESTROY_IF(signer_r
);
252 DESTROY_IF(crypter_i
);
253 DESTROY_IF(crypter_r
);
254 return this->aead_in
&& this->aead_out
;
257 METHOD(keymat_v2_t
, derive_ike_keys
, bool,
258 private_keymat_v2_t
*this, proposal_t
*proposal
, diffie_hellman_t
*dh
,
259 chunk_t nonce_i
, chunk_t nonce_r
, ike_sa_id_t
*id
,
260 pseudo_random_function_t rekey_function
, chunk_t rekey_skd
)
262 chunk_t skeyseed
, key
, secret
, full_nonce
, fixed_nonce
, prf_plus_seed
;
263 chunk_t spi_i
, spi_r
;
264 prf_plus_t
*prf_plus
= NULL
;
265 u_int16_t alg
, key_size
, int_alg
;
266 prf_t
*rekey_prf
= NULL
;
268 spi_i
= chunk_alloca(sizeof(u_int64_t
));
269 spi_r
= chunk_alloca(sizeof(u_int64_t
));
271 if (dh
->get_shared_secret(dh
, &secret
) != SUCCESS
)
276 /* Create SAs general purpose PRF first, we may use it here */
277 if (!proposal
->get_algorithm(proposal
, PSEUDO_RANDOM_FUNCTION
, &alg
, NULL
))
279 DBG1(DBG_IKE
, "no %N selected",
280 transform_type_names
, PSEUDO_RANDOM_FUNCTION
);
281 chunk_clear(&secret
);
285 this->prf
= lib
->crypto
->create_prf(lib
->crypto
, alg
);
286 if (this->prf
== NULL
)
288 DBG1(DBG_IKE
, "%N %N not supported!",
289 transform_type_names
, PSEUDO_RANDOM_FUNCTION
,
290 pseudo_random_function_names
, alg
);
291 chunk_clear(&secret
);
294 DBG4(DBG_IKE
, "shared Diffie Hellman secret %B", &secret
);
295 /* full nonce is used as seed for PRF+ ... */
296 full_nonce
= chunk_cat("cc", nonce_i
, nonce_r
);
297 /* but the PRF may need a fixed key which only uses the first bytes of
301 case PRF_AES128_XCBC
:
302 /* while rfc4434 defines variable keys for AES-XCBC, rfc3664 does
303 * not and therefore fixed key semantics apply to XCBC for key
305 case PRF_CAMELLIA128_XCBC
:
306 /* draft-kanno-ipsecme-camellia-xcbc refers to rfc 4434, we
307 * assume fixed key length. */
308 key_size
= this->prf
->get_key_size(this->prf
)/2;
309 nonce_i
.len
= min(nonce_i
.len
, key_size
);
310 nonce_r
.len
= min(nonce_r
.len
, key_size
);
313 /* all other algorithms use variable key length, full nonce */
316 fixed_nonce
= chunk_cat("cc", nonce_i
, nonce_r
);
317 *((u_int64_t
*)spi_i
.ptr
) = id
->get_initiator_spi(id
);
318 *((u_int64_t
*)spi_r
.ptr
) = id
->get_responder_spi(id
);
319 prf_plus_seed
= chunk_cat("ccc", full_nonce
, spi_i
, spi_r
);
321 /* KEYMAT = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr)
323 * if we are rekeying, SKEYSEED is built on another way
325 if (rekey_function
== PRF_UNDEFINED
) /* not rekeying */
327 /* SKEYSEED = prf(Ni | Nr, g^ir) */
328 if (this->prf
->set_key(this->prf
, fixed_nonce
) &&
329 this->prf
->allocate_bytes(this->prf
, secret
, &skeyseed
) &&
330 this->prf
->set_key(this->prf
, skeyseed
))
332 prf_plus
= prf_plus_create(this->prf
, TRUE
, prf_plus_seed
);
337 /* SKEYSEED = prf(SK_d (old), [g^ir (new)] | Ni | Nr)
338 * use OLD SAs PRF functions for both prf_plus and prf */
339 rekey_prf
= lib
->crypto
->create_prf(lib
->crypto
, rekey_function
);
342 DBG1(DBG_IKE
, "PRF of old SA %N not supported!",
343 pseudo_random_function_names
, rekey_function
);
344 chunk_clear(&secret
);
345 chunk_free(&full_nonce
);
346 chunk_free(&fixed_nonce
);
347 chunk_clear(&prf_plus_seed
);
350 secret
= chunk_cat("mc", secret
, full_nonce
);
351 if (rekey_prf
->set_key(rekey_prf
, rekey_skd
) &&
352 rekey_prf
->allocate_bytes(rekey_prf
, secret
, &skeyseed
) &&
353 rekey_prf
->set_key(rekey_prf
, skeyseed
))
355 prf_plus
= prf_plus_create(rekey_prf
, TRUE
, prf_plus_seed
);
358 DBG4(DBG_IKE
, "SKEYSEED %B", &skeyseed
);
360 chunk_clear(&skeyseed
);
361 chunk_clear(&secret
);
362 chunk_free(&full_nonce
);
363 chunk_free(&fixed_nonce
);
364 chunk_clear(&prf_plus_seed
);
371 /* KEYMAT = SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr */
373 /* SK_d is used for generating CHILD_SA key mat => store for later use */
374 key_size
= this->prf
->get_key_size(this->prf
);
375 if (!prf_plus
->allocate_bytes(prf_plus
, key_size
, &this->skd
))
379 DBG4(DBG_IKE
, "Sk_d secret %B", &this->skd
);
381 if (!proposal
->get_algorithm(proposal
, ENCRYPTION_ALGORITHM
, &alg
, &key_size
))
383 DBG1(DBG_IKE
, "no %N selected",
384 transform_type_names
, ENCRYPTION_ALGORITHM
);
388 if (encryption_algorithm_is_aead(alg
))
390 if (!derive_ike_aead(this, alg
, key_size
, prf_plus
))
397 if (!proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
,
400 DBG1(DBG_IKE
, "no %N selected",
401 transform_type_names
, INTEGRITY_ALGORITHM
);
404 if (!derive_ike_traditional(this, alg
, key_size
, int_alg
, prf_plus
))
410 /* SK_pi/SK_pr used for authentication => stored for later */
411 key_size
= this->prf
->get_key_size(this->prf
);
412 if (!prf_plus
->allocate_bytes(prf_plus
, key_size
, &key
))
416 DBG4(DBG_IKE
, "Sk_pi secret %B", &key
);
419 this->skp_build
= key
;
423 this->skp_verify
= key
;
425 if (!prf_plus
->allocate_bytes(prf_plus
, key_size
, &key
))
429 DBG4(DBG_IKE
, "Sk_pr secret %B", &key
);
432 this->skp_verify
= key
;
436 this->skp_build
= key
;
439 /* all done, prf_plus not needed anymore */
441 DESTROY_IF(prf_plus
);
442 DESTROY_IF(rekey_prf
);
444 return this->skp_build
.len
&& this->skp_verify
.len
;
447 METHOD(keymat_v2_t
, derive_child_keys
, bool,
448 private_keymat_v2_t
*this, proposal_t
*proposal
, diffie_hellman_t
*dh
,
449 chunk_t nonce_i
, chunk_t nonce_r
, chunk_t
*encr_i
, chunk_t
*integ_i
,
450 chunk_t
*encr_r
, chunk_t
*integ_r
)
452 u_int16_t enc_alg
, int_alg
, enc_size
= 0, int_size
= 0;
453 chunk_t seed
, secret
= chunk_empty
;
454 prf_plus_t
*prf_plus
;
458 if (dh
->get_shared_secret(dh
, &secret
) != SUCCESS
)
462 DBG4(DBG_CHD
, "DH secret %B", &secret
);
464 seed
= chunk_cata("mcc", secret
, nonce_i
, nonce_r
);
465 DBG4(DBG_CHD
, "seed %B", &seed
);
467 if (proposal
->get_algorithm(proposal
, ENCRYPTION_ALGORITHM
,
468 &enc_alg
, &enc_size
))
470 DBG2(DBG_CHD
, " using %N for encryption",
471 encryption_algorithm_names
, enc_alg
);
475 enc_size
= keymat_get_keylen_encr(enc_alg
);
477 if (enc_alg
!= ENCR_NULL
&& !enc_size
)
479 DBG1(DBG_CHD
, "no keylength defined for %N",
480 encryption_algorithm_names
, enc_alg
);
486 /* CCM/GCM/CTR/GMAC needs additional bytes */
489 case ENCR_AES_CCM_ICV8
:
490 case ENCR_AES_CCM_ICV12
:
491 case ENCR_AES_CCM_ICV16
:
492 case ENCR_CAMELLIA_CCM_ICV8
:
493 case ENCR_CAMELLIA_CCM_ICV12
:
494 case ENCR_CAMELLIA_CCM_ICV16
:
497 case ENCR_AES_GCM_ICV8
:
498 case ENCR_AES_GCM_ICV12
:
499 case ENCR_AES_GCM_ICV16
:
501 case ENCR_NULL_AUTH_AES_GMAC
:
509 if (proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
,
510 &int_alg
, &int_size
))
512 DBG2(DBG_CHD
, " using %N for integrity",
513 integrity_algorithm_names
, int_alg
);
517 int_size
= keymat_get_keylen_integ(int_alg
);
521 DBG1(DBG_CHD
, "no keylength defined for %N",
522 integrity_algorithm_names
, int_alg
);
529 if (!this->prf
->set_key(this->prf
, this->skd
))
533 prf_plus
= prf_plus_create(this->prf
, TRUE
, seed
);
539 *encr_i
= *integ_i
= *encr_r
= *integ_r
= chunk_empty
;
540 if (!prf_plus
->allocate_bytes(prf_plus
, enc_size
, encr_i
) ||
541 !prf_plus
->allocate_bytes(prf_plus
, int_size
, integ_i
) ||
542 !prf_plus
->allocate_bytes(prf_plus
, enc_size
, encr_r
) ||
543 !prf_plus
->allocate_bytes(prf_plus
, int_size
, integ_r
))
549 prf_plus
->destroy(prf_plus
);
553 prf_plus
->destroy(prf_plus
);
557 DBG4(DBG_CHD
, "encryption initiator key %B", encr_i
);
558 DBG4(DBG_CHD
, "encryption responder key %B", encr_r
);
562 DBG4(DBG_CHD
, "integrity initiator key %B", integ_i
);
563 DBG4(DBG_CHD
, "integrity responder key %B", integ_r
);
568 METHOD(keymat_v2_t
, get_skd
, pseudo_random_function_t
,
569 private_keymat_v2_t
*this, chunk_t
*skd
)
572 return this->prf_alg
;
575 METHOD(keymat_t
, get_aead
, aead_t
*,
576 private_keymat_v2_t
*this, bool in
)
578 return in
? this->aead_in
: this->aead_out
;
581 METHOD(keymat_v2_t
, get_auth_octets
, bool,
582 private_keymat_v2_t
*this, bool verify
, chunk_t ike_sa_init
,
583 chunk_t nonce
, identification_t
*id
, char reserved
[3], chunk_t
*octets
)
588 skp
= verify
? this->skp_verify
: this->skp_build
;
590 chunk
= chunk_alloca(4);
591 chunk
.ptr
[0] = id
->get_type(id
);
592 memcpy(chunk
.ptr
+ 1, reserved
, 3);
593 idx
= chunk_cata("cc", chunk
, id
->get_encoding(id
));
595 DBG3(DBG_IKE
, "IDx' %B", &idx
);
596 DBG4(DBG_IKE
, "SK_p %B", &skp
);
597 if (!this->prf
->set_key(this->prf
, skp
) ||
598 !this->prf
->allocate_bytes(this->prf
, idx
, &chunk
))
602 *octets
= chunk_cat("ccm", ike_sa_init
, nonce
, chunk
);
603 DBG3(DBG_IKE
, "octets = message + nonce + prf(Sk_px, IDx') %B", octets
);
608 * Key pad for the AUTH method SHARED_KEY_MESSAGE_INTEGRITY_CODE.
610 #define IKEV2_KEY_PAD "Key Pad for IKEv2"
611 #define IKEV2_KEY_PAD_LENGTH 17
613 METHOD(keymat_v2_t
, get_psk_sig
, bool,
614 private_keymat_v2_t
*this, bool verify
, chunk_t ike_sa_init
, chunk_t nonce
,
615 chunk_t secret
, identification_t
*id
, char reserved
[3], chunk_t
*sig
)
617 chunk_t key_pad
, key
, octets
;
620 { /* EAP uses SK_p if no MSK has been established */
621 secret
= verify
? this->skp_verify
: this->skp_build
;
623 if (!get_auth_octets(this, verify
, ike_sa_init
, nonce
, id
, reserved
, &octets
))
627 /* AUTH = prf(prf(Shared Secret,"Key Pad for IKEv2"), <msg octets>) */
628 key_pad
= chunk_create(IKEV2_KEY_PAD
, IKEV2_KEY_PAD_LENGTH
);
629 if (!this->prf
->set_key(this->prf
, secret
) ||
630 !this->prf
->allocate_bytes(this->prf
, key_pad
, &key
))
635 if (!this->prf
->set_key(this->prf
, key
) ||
636 !this->prf
->allocate_bytes(this->prf
, octets
, sig
))
642 DBG4(DBG_IKE
, "secret %B", &secret
);
643 DBG4(DBG_IKE
, "prf(secret, keypad) %B", &key
);
644 DBG3(DBG_IKE
, "AUTH = prf(prf(secret, keypad), octets) %B", sig
);
651 METHOD(keymat_t
, destroy
, void,
652 private_keymat_v2_t
*this)
654 DESTROY_IF(this->aead_in
);
655 DESTROY_IF(this->aead_out
);
656 DESTROY_IF(this->prf
);
657 chunk_clear(&this->skd
);
658 chunk_clear(&this->skp_verify
);
659 chunk_clear(&this->skp_build
);
666 keymat_v2_t
*keymat_v2_create(bool initiator
)
668 private_keymat_v2_t
*this;
673 .get_version
= _get_version
,
674 .create_dh
= _create_dh
,
675 .create_nonce_gen
= _create_nonce_gen
,
676 .get_aead
= _get_aead
,
679 .derive_ike_keys
= _derive_ike_keys
,
680 .derive_child_keys
= _derive_child_keys
,
682 .get_auth_octets
= _get_auth_octets
,
683 .get_psk_sig
= _get_psk_sig
,
685 .initiator
= initiator
,
686 .prf_alg
= PRF_UNDEFINED
,
689 return &this->public;