iv_gen: Mask sequential IVs with a random salt
authorTobias Brunner <tobias@strongswan.org>
Mon, 5 Aug 2013 14:24:40 +0000 (16:24 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 11 Oct 2013 13:55:40 +0000 (15:55 +0200)
This makes it harder to attack a HA setup, even if the sequence numbers were
not fully in sync.

src/libstrongswan/crypto/iv/iv_gen_seq.c

index cbbc2dc..98d0c15 100644 (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;
 }