diff options
Diffstat (limited to 'src/libcharon')
-rw-r--r-- | src/libcharon/sa/ikev1/keymat_v1.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/src/libcharon/sa/ikev1/keymat_v1.c b/src/libcharon/sa/ikev1/keymat_v1.c index 77f0a5651..2b22b14f8 100644 --- a/src/libcharon/sa/ikev1/keymat_v1.c +++ b/src/libcharon/sa/ikev1/keymat_v1.c @@ -222,31 +222,38 @@ METHOD(aead_t, aead_destroy, void, * Expand SKEYID_e according to Appendix B in RFC 2409. * TODO-IKEv1: verify keys (e.g. for weak keys, see Appendix B) */ -static chunk_t expand_skeyid_e(chunk_t skeyid_e, size_t key_size, prf_t *prf) +static bool expand_skeyid_e(chunk_t skeyid_e, size_t key_size, prf_t *prf, + chunk_t *ka) { size_t block_size; - chunk_t seed, ka; + chunk_t seed; int i; if (skeyid_e.len >= key_size) { /* no expansion required, reduce to key_size */ skeyid_e.len = key_size; - return skeyid_e; + *ka = skeyid_e; + return TRUE; } block_size = prf->get_block_size(prf); - ka = chunk_alloc((key_size / block_size + 1) * block_size); - ka.len = key_size; + *ka = chunk_alloc((key_size / block_size + 1) * block_size); + ka->len = key_size; /* Ka = K1 | K2 | ..., K1 = prf(SKEYID_e, 0), K2 = prf(SKEYID_e, K1) ... */ prf->set_key(prf, skeyid_e); seed = octet_0; for (i = 0; i < key_size; i += block_size) { - prf->get_bytes(prf, seed, ka.ptr + i); - seed = chunk_create(ka.ptr + i, block_size); + if (!prf->get_bytes(prf, seed, ka->ptr + i)) + { + chunk_clear(ka); + chunk_clear(&skeyid_e); + return FALSE; + } + seed = chunk_create(ka->ptr + i, block_size); } chunk_clear(&skeyid_e); - return ka; + return TRUE; } /** @@ -276,7 +283,10 @@ static aead_t *create_aead(proposal_t *proposal, prf_t *prf, chunk_t skeyid_e) return NULL; } key_size = crypter->get_key_size(crypter); - ka = expand_skeyid_e(skeyid_e, crypter->get_key_size(crypter), prf); + if (!expand_skeyid_e(skeyid_e, crypter->get_key_size(crypter), prf, &ka)) + { + return NULL; + } DBG4(DBG_IKE, "encryption key Ka %B", &ka); crypter->set_key(crypter, ka); chunk_clear(&ka); |