mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-05 00:00:45 -04:00
keymat_v1: Derive CHILD_SA keys without using prf_plus_t
We already expand skeyid_e in a similar fashion so do this analogous without relying on prf_plus_t.
This commit is contained in:
parent
be07b9dc01
commit
9cb3c10418
@ -16,7 +16,6 @@
|
||||
#include "keymat_v1.h"
|
||||
|
||||
#include <daemon.h>
|
||||
#include <crypto/prf_plus.h>
|
||||
#include <sa/ikev1/iv_manager.h>
|
||||
#include <encoding/generator.h>
|
||||
#include <encoding/payloads/nonce_payload.h>
|
||||
@ -508,6 +507,36 @@ METHOD(keymat_v1_t, derive_ike_keys, bool,
|
||||
this->aead->get_block_size(this->aead));
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive key material for CHILD_SAs according to section 5.5. in RFC 2409.
|
||||
*/
|
||||
static bool derive_child_keymat(private_keymat_v1_t *this, chunk_t seed,
|
||||
uint16_t enc_size, chunk_t *encr,
|
||||
uint16_t int_size, chunk_t *integ)
|
||||
{
|
||||
size_t block_size, i;
|
||||
chunk_t keymat, prev = chunk_empty;
|
||||
|
||||
block_size = this->prf->get_block_size(this->prf);
|
||||
keymat = chunk_alloc(round_up(enc_size + int_size, block_size));
|
||||
keymat.len = enc_size + int_size;
|
||||
|
||||
for (i = 0; i < keymat.len; i += block_size)
|
||||
{
|
||||
if (!this->prf->get_bytes(this->prf, prev, NULL) ||
|
||||
!this->prf->get_bytes(this->prf, seed, keymat.ptr + i))
|
||||
{
|
||||
chunk_clear(&keymat);
|
||||
return FALSE;
|
||||
}
|
||||
prev = chunk_create(keymat.ptr + i, block_size);
|
||||
}
|
||||
|
||||
chunk_split(keymat, "aa", enc_size, encr, int_size, integ);
|
||||
chunk_clear(&keymat);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(keymat_v1_t, derive_child_keys, bool,
|
||||
private_keymat_v1_t *this, proposal_t *proposal, diffie_hellman_t *dh,
|
||||
uint32_t spi_i, uint32_t spi_r, chunk_t nonce_i, chunk_t nonce_r,
|
||||
@ -515,8 +544,7 @@ METHOD(keymat_v1_t, derive_child_keys, bool,
|
||||
{
|
||||
uint16_t enc_alg, int_alg, enc_size = 0, int_size = 0;
|
||||
uint8_t protocol;
|
||||
prf_plus_t *prf_plus;
|
||||
chunk_t seed, secret = chunk_empty;
|
||||
chunk_t seed = chunk_empty, secret = chunk_empty;
|
||||
bool success = FALSE;
|
||||
|
||||
if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM,
|
||||
@ -600,11 +628,7 @@ METHOD(keymat_v1_t, derive_child_keys, bool,
|
||||
seed = chunk_cata("ccccc", secret, chunk_from_thing(protocol),
|
||||
chunk_from_thing(spi_r), nonce_i, nonce_r);
|
||||
DBG4(DBG_CHD, "initiator SA seed %B", &seed);
|
||||
|
||||
prf_plus = prf_plus_create(this->prf, FALSE, seed);
|
||||
if (!prf_plus ||
|
||||
!prf_plus->allocate_bytes(prf_plus, enc_size, encr_i) ||
|
||||
!prf_plus->allocate_bytes(prf_plus, int_size, integ_i))
|
||||
if (!derive_child_keymat(this, seed, enc_size, encr_i, int_size, integ_i))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
@ -612,11 +636,7 @@ METHOD(keymat_v1_t, derive_child_keys, bool,
|
||||
seed = chunk_cata("ccccc", secret, chunk_from_thing(protocol),
|
||||
chunk_from_thing(spi_i), nonce_i, nonce_r);
|
||||
DBG4(DBG_CHD, "responder SA seed %B", &seed);
|
||||
prf_plus->destroy(prf_plus);
|
||||
prf_plus = prf_plus_create(this->prf, FALSE, seed);
|
||||
if (!prf_plus ||
|
||||
!prf_plus->allocate_bytes(prf_plus, enc_size, encr_r) ||
|
||||
!prf_plus->allocate_bytes(prf_plus, int_size, integ_r))
|
||||
if (!derive_child_keymat(this, seed, enc_size, encr_r, int_size, integ_r))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
@ -641,7 +661,7 @@ failure:
|
||||
chunk_clear(encr_r);
|
||||
chunk_clear(integ_r);
|
||||
}
|
||||
DESTROY_IF(prf_plus);
|
||||
memwipe(seed.ptr, seed.len);
|
||||
chunk_clear(&secret);
|
||||
|
||||
return success;
|
||||
|
Loading…
x
Reference in New Issue
Block a user