summaryrefslogtreecommitdiff
path: root/src/libstrongswan/crypto/iv/iv_gen_seq.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/crypto/iv/iv_gen_seq.c')
-rw-r--r--src/libstrongswan/crypto/iv/iv_gen_seq.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/libstrongswan/crypto/iv/iv_gen_seq.c b/src/libstrongswan/crypto/iv/iv_gen_seq.c
index 98d0c15a6..4de13744d 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;
/**
@@ -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,19 @@ METHOD(iv_gen_t, get_iv, bool,
{
return FALSE;
}
+ if (size < sizeof(u_int64_t))
+ {
+ 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 +107,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);