using fixed size keys in key derivation for AES-XCBC PRF
This commit is contained in:
+24
-7
@@ -1517,7 +1517,7 @@ static status_t derive_keys(private_ike_sa_t *this,
|
|||||||
bool initiator, prf_t *child_prf, prf_t *old_prf)
|
bool initiator, prf_t *child_prf, prf_t *old_prf)
|
||||||
{
|
{
|
||||||
prf_plus_t *prf_plus;
|
prf_plus_t *prf_plus;
|
||||||
chunk_t skeyseed, key, nonces, prf_plus_seed;
|
chunk_t skeyseed, key, full_nonce, fixed_nonce, prf_plus_seed;
|
||||||
u_int16_t alg, key_size;
|
u_int16_t alg, key_size;
|
||||||
crypter_t *crypter_i, *crypter_r;
|
crypter_t *crypter_i, *crypter_r;
|
||||||
signer_t *signer_i, *signer_r;
|
signer_t *signer_i, *signer_r;
|
||||||
@@ -1540,12 +1540,28 @@ static status_t derive_keys(private_ike_sa_t *this,
|
|||||||
pseudo_random_function_names, alg);
|
pseudo_random_function_names, alg);
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG4(DBG_IKE, "shared Diffie Hellman secret %B", &secret);
|
DBG4(DBG_IKE, "shared Diffie Hellman secret %B", &secret);
|
||||||
nonces = chunk_cat("cc", nonce_i, nonce_r);
|
/* full nonce is used as seed for PRF+ ... */
|
||||||
|
full_nonce = chunk_cat("cc", nonce_i, nonce_r);
|
||||||
|
/* but the PRF may need a fixed key which only uses the first bytes of
|
||||||
|
* the nonces. */
|
||||||
|
switch (alg)
|
||||||
|
{
|
||||||
|
case PRF_AES128_XCBC:
|
||||||
|
/* while rfc4434 defines variable keys for AES-XCBC, rfc3664 does
|
||||||
|
* not and therefore fixed key semantics apply to XCBC for key
|
||||||
|
* derivation. */
|
||||||
|
nonce_i.len = min(nonce_i.len, this->prf->get_key_size(this->prf)/2);
|
||||||
|
nonce_r.len = min(nonce_r.len, this->prf->get_key_size(this->prf)/2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* all other algorithms use variable key length, full nonce */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fixed_nonce = chunk_cat("cc", nonce_i, nonce_r);
|
||||||
*((u_int64_t*)spi_i.ptr) = this->ike_sa_id->get_initiator_spi(this->ike_sa_id);
|
*((u_int64_t*)spi_i.ptr) = this->ike_sa_id->get_initiator_spi(this->ike_sa_id);
|
||||||
*((u_int64_t*)spi_r.ptr) = this->ike_sa_id->get_responder_spi(this->ike_sa_id);
|
*((u_int64_t*)spi_r.ptr) = this->ike_sa_id->get_responder_spi(this->ike_sa_id);
|
||||||
prf_plus_seed = chunk_cat("ccc", nonces, spi_i, spi_r);
|
prf_plus_seed = chunk_cat("ccc", full_nonce, spi_i, spi_r);
|
||||||
|
|
||||||
/* KEYMAT = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr)
|
/* KEYMAT = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr)
|
||||||
*
|
*
|
||||||
@@ -1554,7 +1570,7 @@ static status_t derive_keys(private_ike_sa_t *this,
|
|||||||
if (child_prf == NULL) /* not rekeying */
|
if (child_prf == NULL) /* not rekeying */
|
||||||
{
|
{
|
||||||
/* SKEYSEED = prf(Ni | Nr, g^ir) */
|
/* SKEYSEED = prf(Ni | Nr, g^ir) */
|
||||||
this->prf->set_key(this->prf, nonces);
|
this->prf->set_key(this->prf, fixed_nonce);
|
||||||
this->prf->allocate_bytes(this->prf, secret, &skeyseed);
|
this->prf->allocate_bytes(this->prf, secret, &skeyseed);
|
||||||
DBG4(DBG_IKE, "SKEYSEED %B", &skeyseed);
|
DBG4(DBG_IKE, "SKEYSEED %B", &skeyseed);
|
||||||
this->prf->set_key(this->prf, skeyseed);
|
this->prf->set_key(this->prf, skeyseed);
|
||||||
@@ -1566,7 +1582,7 @@ static status_t derive_keys(private_ike_sa_t *this,
|
|||||||
{
|
{
|
||||||
/* SKEYSEED = prf(SK_d (old), [g^ir (new)] | Ni | Nr)
|
/* SKEYSEED = prf(SK_d (old), [g^ir (new)] | Ni | Nr)
|
||||||
* use OLD SAs PRF functions for both prf_plus and prf */
|
* use OLD SAs PRF functions for both prf_plus and prf */
|
||||||
secret = chunk_cat("mc", secret, nonces);
|
secret = chunk_cat("mc", secret, full_nonce);
|
||||||
child_prf->allocate_bytes(child_prf, secret, &skeyseed);
|
child_prf->allocate_bytes(child_prf, secret, &skeyseed);
|
||||||
DBG4(DBG_IKE, "SKEYSEED %B", &skeyseed);
|
DBG4(DBG_IKE, "SKEYSEED %B", &skeyseed);
|
||||||
old_prf->set_key(old_prf, skeyseed);
|
old_prf->set_key(old_prf, skeyseed);
|
||||||
@@ -1574,7 +1590,8 @@ static status_t derive_keys(private_ike_sa_t *this,
|
|||||||
chunk_free(&secret);
|
chunk_free(&secret);
|
||||||
prf_plus = prf_plus_create(old_prf, prf_plus_seed);
|
prf_plus = prf_plus_create(old_prf, prf_plus_seed);
|
||||||
}
|
}
|
||||||
chunk_free(&nonces);
|
chunk_free(&full_nonce);
|
||||||
|
chunk_free(&fixed_nonce);
|
||||||
chunk_free(&prf_plus_seed);
|
chunk_free(&prf_plus_seed);
|
||||||
|
|
||||||
/* KEYMAT = SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr */
|
/* KEYMAT = SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr */
|
||||||
|
|||||||
Reference in New Issue
Block a user