iv-gen: Ensure external sequential IVs are actually sequential
authorMartin Willi <martin@revosec.ch>
Fri, 17 Apr 2015 12:08:14 +0000 (14:08 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 1 Jun 2015 07:42:10 +0000 (09:42 +0200)
We allow gaps in IVs, but ensure that an IV is never used more than once.

src/libstrongswan/crypto/iv/iv_gen_seq.c
src/libstrongswan/crypto/iv/iv_gen_seq.h

index 98d0c15..70f1fce 100644 (file)
 
 #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;
 
 /**
@@ -28,6 +33,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
         */
        u_int8_t *salt;
@@ -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);
index 329dcca..43ff4f6 100644 (file)
@@ -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();