iv_gen: Mask sequential IVs with a random salt

This makes it harder to attack a HA setup, even if the sequence numbers were
not fully in sync.
This commit is contained in:
Tobias Brunner 2013-08-05 16:24:40 +02:00
parent e8229ad558
commit 0c6f6c4e34
1 changed files with 24 additions and 0 deletions

View File

@ -26,6 +26,11 @@ struct private_iv_gen_t {
* Public iv_gen_t interface.
*/
iv_gen_t public;
/**
* Salt to mask counter
*/
u_int8_t *salt;
};
METHOD(iv_gen_t, get_iv, bool,
@ -34,12 +39,17 @@ METHOD(iv_gen_t, get_iv, bool,
u_int8_t iv[sizeof(u_int64_t)];
size_t len = size;
if (!this->salt)
{
return FALSE;
}
if (len > sizeof(u_int64_t))
{
len = sizeof(u_int64_t);
memset(buffer, 0, size - len);
}
htoun64(iv, seq);
memxor(iv, this->salt, sizeof(u_int64_t));
memcpy(buffer + size - len, iv + sizeof(u_int64_t) - len, len);
return TRUE;
}
@ -59,12 +69,14 @@ METHOD(iv_gen_t, allocate_iv, bool,
METHOD(iv_gen_t, destroy, void,
private_iv_gen_t *this)
{
free(this->salt);
free(this);
}
iv_gen_t *iv_gen_seq_create()
{
private_iv_gen_t *this;
rng_t *rng;
INIT(this,
.public = {
@ -74,5 +86,17 @@ iv_gen_t *iv_gen_seq_create()
},
);
rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
if (rng)
{
this->salt = malloc(sizeof(u_int64_t));
if (!rng->get_bytes(rng, sizeof(u_int64_t), this->salt))
{
free(this->salt);
this->salt = NULL;
}
rng->destroy(rng);
}
return &this->public;
}