ivgen: Allow reusing the same message ID twice in sequential IV gen
We use the message ID and fragment number as IV generator. As IKEv2 uses
distinct message ID counters for actively and passively initiated exchanges,
each IV would be used twice. As we explicitly reject such message IDs since
d0ed1079, original-responder initiated exchanges fail with counter mode ciphers.
This commit separates IV space in two halves for sequential IVs, and
automatically assigns once reused sequence numbers to the second half.
Fixes #980.
This commit is contained in:
committed by
Tobias Brunner
parent
9bb7307825
commit
b756eea4f4
@@ -19,6 +19,7 @@
|
||||
* Magic value for the initial IV state
|
||||
*/
|
||||
#define SEQ_IV_INIT_STATE (~(u_int64_t)0)
|
||||
#define SEQ_IV_HIGH_MASK (1ULL << 63)
|
||||
|
||||
typedef struct private_iv_gen_t private_iv_gen_t;
|
||||
|
||||
@@ -33,9 +34,14 @@ struct private_iv_gen_t {
|
||||
iv_gen_t public;
|
||||
|
||||
/**
|
||||
* Previously passed sequence number to enforce uniqueness
|
||||
* Previously passed sequence number in lower space to enforce uniqueness
|
||||
*/
|
||||
u_int64_t prev;
|
||||
u_int64_t prevl;
|
||||
|
||||
/**
|
||||
* Previously passed sequence number in upper space to enforce uniqueness
|
||||
*/
|
||||
u_int64_t prevh;
|
||||
|
||||
/**
|
||||
* Salt to mask counter
|
||||
@@ -57,15 +63,26 @@ METHOD(iv_gen_t, get_iv, bool,
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (this->prev != SEQ_IV_INIT_STATE && seq <= this->prev)
|
||||
if (this->prevl != SEQ_IV_INIT_STATE && seq <= this->prevl)
|
||||
{
|
||||
seq |= SEQ_IV_HIGH_MASK;
|
||||
if (this->prevh != SEQ_IV_INIT_STATE && seq <= this->prevh)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ((seq | SEQ_IV_HIGH_MASK) == SEQ_IV_INIT_STATE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (seq == SEQ_IV_INIT_STATE)
|
||||
if (seq & SEQ_IV_HIGH_MASK)
|
||||
{
|
||||
return FALSE;
|
||||
this->prevh = seq;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->prevl = seq;
|
||||
}
|
||||
this->prev = seq;
|
||||
if (len > sizeof(u_int64_t))
|
||||
{
|
||||
len = sizeof(u_int64_t);
|
||||
@@ -107,7 +124,8 @@ iv_gen_t *iv_gen_seq_create()
|
||||
.allocate_iv = _allocate_iv,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.prev = SEQ_IV_INIT_STATE,
|
||||
.prevl = SEQ_IV_INIT_STATE,
|
||||
.prevh = SEQ_IV_INIT_STATE,
|
||||
);
|
||||
|
||||
rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
|
||||
|
||||
Reference in New Issue
Block a user