iv_gen: Provide external sequence number (IKE, ESP)
This prevents duplicate sequential IVs in case of a HA failover.
This commit is contained in:
@@ -33,21 +33,23 @@ struct iv_gen_t {
|
||||
/**
|
||||
* Generates an IV and writes it into the buffer.
|
||||
*
|
||||
* @param seq external sequence number
|
||||
* @param size size of IV in bytes
|
||||
* @param buffer pointer where the generated IV will be written
|
||||
* @return TRUE if IV allocation was successful, FALSE otherwise
|
||||
*/
|
||||
bool (*get_iv)(iv_gen_t *this, size_t size,
|
||||
bool (*get_iv)(iv_gen_t *this, u_int64_t seq, size_t size,
|
||||
u_int8_t *buffer) __attribute__((warn_unused_result));
|
||||
|
||||
/**
|
||||
* Generates an IV and allocates space for it.
|
||||
*
|
||||
* @param seq external sequence number
|
||||
* @param size size of IV in bytes
|
||||
* @param chunk chunk which will hold the generated IV
|
||||
* @return TRUE if IV allocation was successful, FALSE otherwise
|
||||
*/
|
||||
bool (*allocate_iv)(iv_gen_t *this, size_t size,
|
||||
bool (*allocate_iv)(iv_gen_t *this, u_int64_t seq, size_t size,
|
||||
chunk_t *chunk) __attribute__((warn_unused_result));
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,7 +36,7 @@ struct private_iv_gen_t {
|
||||
};
|
||||
|
||||
METHOD(iv_gen_t, get_iv, bool,
|
||||
private_iv_gen_t *this, size_t size, u_int8_t *buffer)
|
||||
private_iv_gen_t *this, u_int64_t seq, size_t size, u_int8_t *buffer)
|
||||
{
|
||||
if (!this->rng)
|
||||
{
|
||||
@@ -46,7 +46,7 @@ METHOD(iv_gen_t, get_iv, bool,
|
||||
}
|
||||
|
||||
METHOD(iv_gen_t, allocate_iv, bool,
|
||||
private_iv_gen_t *this, size_t size, chunk_t *chunk)
|
||||
private_iv_gen_t *this, u_int64_t seq, size_t size, chunk_t *chunk)
|
||||
{
|
||||
if (!this->rng)
|
||||
{
|
||||
|
||||
@@ -26,38 +26,29 @@ struct private_iv_gen_t {
|
||||
* Public iv_gen_t interface.
|
||||
*/
|
||||
iv_gen_t public;
|
||||
|
||||
/**
|
||||
* sequence number
|
||||
*/
|
||||
u_int64_t seq;
|
||||
};
|
||||
|
||||
METHOD(iv_gen_t, get_iv, bool,
|
||||
private_iv_gen_t *this, size_t size, u_int8_t *buffer)
|
||||
private_iv_gen_t *this, u_int64_t seq, size_t size, u_int8_t *buffer)
|
||||
{
|
||||
u_int8_t iv[sizeof(u_int64_t)];
|
||||
size_t len = size;
|
||||
|
||||
if (this->seq == UINT64_MAX || len < sizeof(u_int64_t))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (len > sizeof(u_int64_t))
|
||||
{
|
||||
len = sizeof(u_int64_t);
|
||||
memset(buffer, 0, size - len);
|
||||
}
|
||||
htoun64(iv, this->seq++);
|
||||
htoun64(iv, seq);
|
||||
memcpy(buffer + size - len, iv + sizeof(u_int64_t) - len, len);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(iv_gen_t, allocate_iv, bool,
|
||||
private_iv_gen_t *this, size_t size, chunk_t *chunk)
|
||||
private_iv_gen_t *this, u_int64_t seq, size_t size, chunk_t *chunk)
|
||||
{
|
||||
*chunk = chunk_alloc(size);
|
||||
if (!get_iv(this, chunk->len, chunk->ptr))
|
||||
if (!get_iv(this, seq, chunk->len, chunk->ptr))
|
||||
{
|
||||
chunk_free(chunk);
|
||||
return FALSE;
|
||||
|
||||
Reference in New Issue
Block a user