Extended PRF+ by a non-counting variant as used by IKEv1
This commit is contained in:
@@ -316,7 +316,7 @@ METHOD(keymat_v2_t, derive_ike_keys, bool,
|
|||||||
this->prf->set_key(this->prf, fixed_nonce);
|
this->prf->set_key(this->prf, fixed_nonce);
|
||||||
this->prf->allocate_bytes(this->prf, secret, &skeyseed);
|
this->prf->allocate_bytes(this->prf, secret, &skeyseed);
|
||||||
this->prf->set_key(this->prf, skeyseed);
|
this->prf->set_key(this->prf, skeyseed);
|
||||||
prf_plus = prf_plus_create(this->prf, prf_plus_seed);
|
prf_plus = prf_plus_create(this->prf, TRUE, prf_plus_seed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -336,7 +336,7 @@ METHOD(keymat_v2_t, derive_ike_keys, bool,
|
|||||||
rekey_prf->set_key(rekey_prf, rekey_skd);
|
rekey_prf->set_key(rekey_prf, rekey_skd);
|
||||||
rekey_prf->allocate_bytes(rekey_prf, secret, &skeyseed);
|
rekey_prf->allocate_bytes(rekey_prf, secret, &skeyseed);
|
||||||
rekey_prf->set_key(rekey_prf, skeyseed);
|
rekey_prf->set_key(rekey_prf, skeyseed);
|
||||||
prf_plus = prf_plus_create(rekey_prf, prf_plus_seed);
|
prf_plus = prf_plus_create(rekey_prf, TRUE, prf_plus_seed);
|
||||||
}
|
}
|
||||||
DBG4(DBG_IKE, "SKEYSEED %B", &skeyseed);
|
DBG4(DBG_IKE, "SKEYSEED %B", &skeyseed);
|
||||||
|
|
||||||
@@ -503,7 +503,7 @@ METHOD(keymat_v2_t, derive_child_keys, bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->prf->set_key(this->prf, this->skd);
|
this->prf->set_key(this->prf, this->skd);
|
||||||
prf_plus = prf_plus_create(this->prf, seed);
|
prf_plus = prf_plus_create(this->prf, TRUE, seed);
|
||||||
|
|
||||||
prf_plus->allocate_bytes(prf_plus, enc_size, encr_i);
|
prf_plus->allocate_bytes(prf_plus, enc_size, encr_i);
|
||||||
prf_plus->allocate_bytes(prf_plus, int_size, integ_i);
|
prf_plus->allocate_bytes(prf_plus, int_size, integ_i);
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ typedef struct private_prf_plus_t private_prf_plus_t;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct private_prf_plus_t {
|
struct private_prf_plus_t {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public interface of prf_plus_t.
|
* Public interface of prf_plus_t.
|
||||||
*/
|
*/
|
||||||
@@ -48,42 +49,43 @@ struct private_prf_plus_t {
|
|||||||
/**
|
/**
|
||||||
* Already given out bytes in current buffer.
|
* Already given out bytes in current buffer.
|
||||||
*/
|
*/
|
||||||
size_t given_out;
|
size_t used;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Octet which will be appended to the seed.
|
* Octet which will be appended to the seed, 0 if not used
|
||||||
*/
|
*/
|
||||||
u_int8_t appending_octet;
|
u_int8_t counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
METHOD(prf_plus_t, get_bytes, void,
|
METHOD(prf_plus_t, get_bytes, void,
|
||||||
private_prf_plus_t *this, size_t length, u_int8_t *buffer)
|
private_prf_plus_t *this, size_t length, u_int8_t *buffer)
|
||||||
{
|
{
|
||||||
chunk_t appending_chunk;
|
size_t round, written = 0;
|
||||||
size_t bytes_in_round;
|
|
||||||
size_t total_bytes_written = 0;
|
|
||||||
|
|
||||||
appending_chunk.ptr = &(this->appending_octet);
|
|
||||||
appending_chunk.len = 1;
|
|
||||||
|
|
||||||
while (length > 0)
|
while (length > 0)
|
||||||
{ /* still more to do... */
|
{
|
||||||
if (this->buffer.len == this->given_out)
|
if (this->buffer.len == this->used)
|
||||||
{ /* no bytes left in buffer, get next*/
|
{ /* buffer used, get next round */
|
||||||
this->prf->get_bytes(this->prf, this->buffer, NULL);
|
this->prf->get_bytes(this->prf, this->buffer, NULL);
|
||||||
this->prf->get_bytes(this->prf, this->seed, NULL);
|
if (this->counter)
|
||||||
this->prf->get_bytes(this->prf, appending_chunk, this->buffer.ptr);
|
{
|
||||||
this->given_out = 0;
|
this->prf->get_bytes(this->prf, this->seed, NULL);
|
||||||
this->appending_octet++;
|
this->prf->get_bytes(this->prf, chunk_from_thing(this->counter),
|
||||||
|
this->buffer.ptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->prf->get_bytes(this->prf, this->seed, this->buffer.ptr);
|
||||||
|
}
|
||||||
|
this->counter++;
|
||||||
|
this->used = 0;
|
||||||
}
|
}
|
||||||
/* how many bytes can we write in this round ? */
|
round = min(length, this->buffer.len - this->used);
|
||||||
bytes_in_round = min(length, this->buffer.len - this->given_out);
|
memcpy(buffer + written, this->buffer.ptr + this->used, round);
|
||||||
/* copy bytes from buffer with offset */
|
|
||||||
memcpy(buffer + total_bytes_written, this->buffer.ptr + this->given_out, bytes_in_round);
|
|
||||||
|
|
||||||
length -= bytes_in_round;
|
length -= round;
|
||||||
this->given_out += bytes_in_round;
|
this->used += round;
|
||||||
total_bytes_written += bytes_in_round;
|
written += round;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,8 +94,7 @@ METHOD(prf_plus_t, allocate_bytes, void,
|
|||||||
{
|
{
|
||||||
if (length)
|
if (length)
|
||||||
{
|
{
|
||||||
chunk->ptr = malloc(length);
|
*chunk = chunk_alloc(length);
|
||||||
chunk->len = length;
|
|
||||||
get_bytes(this, length, chunk->ptr);
|
get_bytes(this, length, chunk->ptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -113,10 +114,9 @@ METHOD(prf_plus_t, destroy, void,
|
|||||||
/*
|
/*
|
||||||
* Description in header.
|
* Description in header.
|
||||||
*/
|
*/
|
||||||
prf_plus_t *prf_plus_create(prf_t *prf, chunk_t seed)
|
prf_plus_t *prf_plus_create(prf_t *prf, bool counter, chunk_t seed)
|
||||||
{
|
{
|
||||||
private_prf_plus_t *this;
|
private_prf_plus_t *this;
|
||||||
chunk_t appending_chunk;
|
|
||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
@@ -125,25 +125,22 @@ prf_plus_t *prf_plus_create(prf_t *prf, chunk_t seed)
|
|||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.prf = prf,
|
.prf = prf,
|
||||||
|
.buffer = chunk_alloc(prf->get_block_size(prf)),
|
||||||
|
.seed = chunk_clone(seed),
|
||||||
);
|
);
|
||||||
|
|
||||||
/* allocate buffer for prf output */
|
if (counter)
|
||||||
this->buffer.len = prf->get_block_size(prf);
|
{
|
||||||
this->buffer.ptr = malloc(this->buffer.len);
|
this->counter = 0x01;
|
||||||
|
this->prf->get_bytes(this->prf, this->seed, NULL);
|
||||||
|
this->prf->get_bytes(this->prf, chunk_from_thing(this->counter),
|
||||||
|
this->buffer.ptr);
|
||||||
|
this->counter++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->prf->get_bytes(this->prf, this->seed, this->buffer.ptr);
|
||||||
|
}
|
||||||
|
|
||||||
this->appending_octet = 0x01;
|
return &this->public;
|
||||||
|
|
||||||
/* clone seed */
|
|
||||||
this->seed.ptr = clalloc(seed.ptr, seed.len);
|
|
||||||
this->seed.len = seed.len;
|
|
||||||
|
|
||||||
/* do the first run */
|
|
||||||
appending_chunk.ptr = &(this->appending_octet);
|
|
||||||
appending_chunk.len = 1;
|
|
||||||
this->prf->get_bytes(this->prf, this->seed, NULL);
|
|
||||||
this->prf->get_bytes(this->prf, appending_chunk, this->buffer.ptr);
|
|
||||||
this->given_out = 0;
|
|
||||||
this->appending_octet++;
|
|
||||||
|
|
||||||
return &(this->public);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,19 +27,13 @@ typedef struct prf_plus_t prf_plus_t;
|
|||||||
#include <crypto/prfs/prf.h>
|
#include <crypto/prfs/prf.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of the prf+ function described in IKEv2 RFC.
|
* Implementation of the prf+ function used in IKEv1/IKEv2 keymat extension.
|
||||||
*
|
|
||||||
* This class implements the prf+ algorithm. Internally it uses a pseudo random
|
|
||||||
* function, which implements the prf_t interface.
|
|
||||||
* See IKEv2 RFC 2.13.
|
|
||||||
*/
|
*/
|
||||||
struct prf_plus_t {
|
struct prf_plus_t {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get pseudo random bytes.
|
* Get pseudo random bytes.
|
||||||
*
|
*
|
||||||
* Get the next few bytes of the prf+ output. Space
|
|
||||||
* must be allocated by the caller.
|
|
||||||
*
|
|
||||||
* @param length number of bytes to get
|
* @param length number of bytes to get
|
||||||
* @param buffer pointer where the generated bytes will be written
|
* @param buffer pointer where the generated bytes will be written
|
||||||
*/
|
*/
|
||||||
@@ -48,9 +42,6 @@ struct prf_plus_t {
|
|||||||
/**
|
/**
|
||||||
* Allocate pseudo random bytes.
|
* Allocate pseudo random bytes.
|
||||||
*
|
*
|
||||||
* Get the next few bytes of the prf+ output. This function
|
|
||||||
* will allocate the required space.
|
|
||||||
*
|
|
||||||
* @param length number of bytes to get
|
* @param length number of bytes to get
|
||||||
* @param chunk chunk which will hold generated bytes
|
* @param chunk chunk which will hold generated bytes
|
||||||
*/
|
*/
|
||||||
@@ -65,14 +56,11 @@ struct prf_plus_t {
|
|||||||
/**
|
/**
|
||||||
* Creates a new prf_plus_t object.
|
* Creates a new prf_plus_t object.
|
||||||
*
|
*
|
||||||
* Seed will be cloned. prf will
|
* @param prf prf object to use, must be destroyd after prf+.
|
||||||
* not be cloned, must be destroyed outside after
|
* @param counter use an appending counter byte (for IKEv2 variant)
|
||||||
* prf_plus_t usage.
|
|
||||||
*
|
|
||||||
* @param prf prf object to use
|
|
||||||
* @param seed input seed for prf
|
* @param seed input seed for prf
|
||||||
* @return prf_plus_t object
|
* @return prf_plus_t object
|
||||||
*/
|
*/
|
||||||
prf_plus_t *prf_plus_create(prf_t *prf, chunk_t seed);
|
prf_plus_t *prf_plus_create(prf_t *prf, bool counter, chunk_t seed);
|
||||||
|
|
||||||
#endif /** PRF_PLUS_H_ @}*/
|
#endif /** PRF_PLUS_H_ @}*/
|
||||||
|
|||||||
Reference in New Issue
Block a user