From d0ed1079103334680b1b775b5217709cd26d6ab6 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Fri, 17 Apr 2015 14:08:14 +0200 Subject: [PATCH] iv-gen: Ensure external sequential IVs are actually sequential We allow gaps in IVs, but ensure that an IV is never used more than once. --- src/libstrongswan/crypto/iv/iv_gen_seq.c | 20 ++++++++++++++++++++ src/libstrongswan/crypto/iv/iv_gen_seq.h | 3 +++ 2 files changed, 23 insertions(+) diff --git a/src/libstrongswan/crypto/iv/iv_gen_seq.c b/src/libstrongswan/crypto/iv/iv_gen_seq.c index 98d0c15a60..70f1fce389 100644 --- a/src/libstrongswan/crypto/iv/iv_gen_seq.c +++ b/src/libstrongswan/crypto/iv/iv_gen_seq.c @@ -15,6 +15,11 @@ #include "iv_gen_seq.h" +/** + * Magic value for the initial IV state + */ +#define SEQ_IV_INIT_STATE (~(u_int64_t)0) + typedef struct private_iv_gen_t private_iv_gen_t; /** @@ -27,6 +32,11 @@ struct private_iv_gen_t { */ iv_gen_t public; + /** + * Previously passed sequence number to enforce uniqueness + */ + u_int64_t prev; + /** * Salt to mask counter */ @@ -43,6 +53,15 @@ METHOD(iv_gen_t, get_iv, bool, { return FALSE; } + if (this->prev != SEQ_IV_INIT_STATE && seq <= this->prev) + { + return FALSE; + } + if (seq == SEQ_IV_INIT_STATE) + { + return FALSE; + } + this->prev = seq; if (len > sizeof(u_int64_t)) { len = sizeof(u_int64_t); @@ -84,6 +103,7 @@ iv_gen_t *iv_gen_seq_create() .allocate_iv = _allocate_iv, .destroy = _destroy, }, + .prev = SEQ_IV_INIT_STATE, ); rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG); diff --git a/src/libstrongswan/crypto/iv/iv_gen_seq.h b/src/libstrongswan/crypto/iv/iv_gen_seq.h index 329dcca05c..43ff4f65e0 100644 --- a/src/libstrongswan/crypto/iv/iv_gen_seq.h +++ b/src/libstrongswan/crypto/iv/iv_gen_seq.h @@ -25,6 +25,9 @@ /** * Create an IV generator that generates sequential IVs (counter). * + * The passed external IV must be larger than the one passed to any previous + * call. + * * @return IV generator */ iv_gen_t *iv_gen_seq_create(); -- 2.47.2