aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2013-08-05 15:41:45 +0200
committerTobias Brunner <tobias@strongswan.org>2013-10-11 15:55:40 +0200
commite8229ad558efcb7b07c6ef0f77269120d49500f9 (patch)
tree381b9b0c797ba4642775b9aa0f933dbb89239a47
parentd74c254dfd88b497a5262a3d8ce2dc7a684c74a8 (diff)
downloadstrongswan-e8229ad558efcb7b07c6ef0f77269120d49500f9.tar.bz2
strongswan-e8229ad558efcb7b07c6ef0f77269120d49500f9.tar.xz
iv_gen: Provide external sequence number (IKE, ESP)
This prevents duplicate sequential IVs in case of a HA failover.
-rw-r--r--src/libcharon/encoding/message.c2
-rw-r--r--src/libcharon/encoding/payloads/encryption_payload.c6
-rw-r--r--src/libcharon/encoding/payloads/encryption_payload.h4
-rw-r--r--src/libipsec/esp_packet.c2
-rw-r--r--src/libstrongswan/crypto/iv/iv_gen.h6
-rw-r--r--src/libstrongswan/crypto/iv/iv_gen_rand.c4
-rw-r--r--src/libstrongswan/crypto/iv/iv_gen_seq.c17
7 files changed, 18 insertions, 23 deletions
diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c
index 9fc108b40..11e735a37 100644
--- a/src/libcharon/encoding/message.c
+++ b/src/libcharon/encoding/message.c
@@ -1622,7 +1622,7 @@ METHOD(message_t, generate, status_t,
htoun32(lenpos, chunk.len + encryption->get_length(encryption));
}
this->payloads->insert_last(this->payloads, encryption);
- if (encryption->encrypt(encryption, chunk) != SUCCESS)
+ if (encryption->encrypt(encryption, this->message_id, chunk) != SUCCESS)
{
generator->destroy(generator);
return INVALID_STATE;
diff --git a/src/libcharon/encoding/payloads/encryption_payload.c b/src/libcharon/encoding/payloads/encryption_payload.c
index 302c4a45a..6a9f9c3bd 100644
--- a/src/libcharon/encoding/payloads/encryption_payload.c
+++ b/src/libcharon/encoding/payloads/encryption_payload.c
@@ -309,7 +309,7 @@ static chunk_t append_header(private_encryption_payload_t *this, chunk_t assoc)
}
METHOD(encryption_payload_t, encrypt, status_t,
- private_encryption_payload_t *this, chunk_t assoc)
+ private_encryption_payload_t *this, u_int64_t mid, chunk_t assoc)
{
chunk_t iv, plain, padding, icv, crypt;
generator_t *generator;
@@ -364,7 +364,7 @@ METHOD(encryption_payload_t, encrypt, status_t,
crypt = chunk_create(plain.ptr, plain.len + padding.len);
generator->destroy(generator);
- if (!iv_gen->get_iv(iv_gen, iv.len, iv.ptr) ||
+ if (!iv_gen->get_iv(iv_gen, mid, iv.len, iv.ptr) ||
!rng->get_bytes(rng, padding.len - 1, padding.ptr))
{
DBG1(DBG_ENC, "encrypting encryption payload failed, no IV or padding");
@@ -396,7 +396,7 @@ METHOD(encryption_payload_t, encrypt, status_t,
}
METHOD(encryption_payload_t, encrypt_v1, status_t,
- private_encryption_payload_t *this, chunk_t iv)
+ private_encryption_payload_t *this, u_int64_t mid, chunk_t iv)
{
generator_t *generator;
chunk_t plain, padding;
diff --git a/src/libcharon/encoding/payloads/encryption_payload.h b/src/libcharon/encoding/payloads/encryption_payload.h
index 5c6069339..f4fc7d667 100644
--- a/src/libcharon/encoding/payloads/encryption_payload.h
+++ b/src/libcharon/encoding/payloads/encryption_payload.h
@@ -71,13 +71,15 @@ struct encryption_payload_t {
/**
* Generate, encrypt and sign contained payloads.
*
+ * @param mid message ID
* @param assoc associated data
* @return
* - SUCCESS if encryption successful
* - FAILED if encryption failed
* - INVALID_STATE if aead not supplied, but needed
*/
- status_t (*encrypt) (encryption_payload_t *this, chunk_t assoc);
+ status_t (*encrypt) (encryption_payload_t *this, u_int64_t mid,
+ chunk_t assoc);
/**
* Decrypt, verify and parse contained payloads.
diff --git a/src/libipsec/esp_packet.c b/src/libipsec/esp_packet.c
index 1b8625ca7..db5ef3685 100644
--- a/src/libipsec/esp_packet.c
+++ b/src/libipsec/esp_packet.c
@@ -319,7 +319,7 @@ METHOD(esp_packet_t, encrypt, status_t,
writer->write_uint32(writer, next_seqno);
iv = writer->skip(writer, iv.len);
- if (!iv_gen->get_iv(iv_gen, iv.len, iv.ptr))
+ if (!iv_gen->get_iv(iv_gen, next_seqno, iv.len, iv.ptr))
{
DBG1(DBG_ESP, "ESP encryption failed: could not generate IV");
writer->destroy(writer);
diff --git a/src/libstrongswan/crypto/iv/iv_gen.h b/src/libstrongswan/crypto/iv/iv_gen.h
index 641c1f133..f6bc6471f 100644
--- a/src/libstrongswan/crypto/iv/iv_gen.h
+++ b/src/libstrongswan/crypto/iv/iv_gen.h
@@ -33,21 +33,23 @@ struct iv_gen_t {
/**
* Generates an IV and writes it into the buffer.
*
+ * @param seq external sequence number
* @param size size of IV in bytes
* @param buffer pointer where the generated IV will be written
* @return TRUE if IV allocation was successful, FALSE otherwise
*/
- bool (*get_iv)(iv_gen_t *this, size_t size,
+ bool (*get_iv)(iv_gen_t *this, u_int64_t seq, size_t size,
u_int8_t *buffer) __attribute__((warn_unused_result));
/**
* Generates an IV and allocates space for it.
*
+ * @param seq external sequence number
* @param size size of IV in bytes
* @param chunk chunk which will hold the generated IV
* @return TRUE if IV allocation was successful, FALSE otherwise
*/
- bool (*allocate_iv)(iv_gen_t *this, size_t size,
+ bool (*allocate_iv)(iv_gen_t *this, u_int64_t seq, size_t size,
chunk_t *chunk) __attribute__((warn_unused_result));
/**
diff --git a/src/libstrongswan/crypto/iv/iv_gen_rand.c b/src/libstrongswan/crypto/iv/iv_gen_rand.c
index 3448ee041..2bed63fcc 100644
--- a/src/libstrongswan/crypto/iv/iv_gen_rand.c
+++ b/src/libstrongswan/crypto/iv/iv_gen_rand.c
@@ -36,7 +36,7 @@ struct private_iv_gen_t {
};
METHOD(iv_gen_t, get_iv, bool,
- private_iv_gen_t *this, size_t size, u_int8_t *buffer)
+ private_iv_gen_t *this, u_int64_t seq, size_t size, u_int8_t *buffer)
{
if (!this->rng)
{
@@ -46,7 +46,7 @@ METHOD(iv_gen_t, get_iv, bool,
}
METHOD(iv_gen_t, allocate_iv, bool,
- private_iv_gen_t *this, size_t size, chunk_t *chunk)
+ private_iv_gen_t *this, u_int64_t seq, size_t size, chunk_t *chunk)
{
if (!this->rng)
{
diff --git a/src/libstrongswan/crypto/iv/iv_gen_seq.c b/src/libstrongswan/crypto/iv/iv_gen_seq.c
index d8a5a2909..cbbc2dc7e 100644
--- a/src/libstrongswan/crypto/iv/iv_gen_seq.c
+++ b/src/libstrongswan/crypto/iv/iv_gen_seq.c
@@ -26,38 +26,29 @@ struct private_iv_gen_t {
* Public iv_gen_t interface.
*/
iv_gen_t public;
-
- /**
- * sequence number
- */
- u_int64_t seq;
};
METHOD(iv_gen_t, get_iv, bool,
- private_iv_gen_t *this, size_t size, u_int8_t *buffer)
+ private_iv_gen_t *this, u_int64_t seq, size_t size, u_int8_t *buffer)
{
u_int8_t iv[sizeof(u_int64_t)];
size_t len = size;
- if (this->seq == UINT64_MAX || len < sizeof(u_int64_t))
- {
- return FALSE;
- }
if (len > sizeof(u_int64_t))
{
len = sizeof(u_int64_t);
memset(buffer, 0, size - len);
}
- htoun64(iv, this->seq++);
+ htoun64(iv, seq);
memcpy(buffer + size - len, iv + sizeof(u_int64_t) - len, len);
return TRUE;
}
METHOD(iv_gen_t, allocate_iv, bool,
- private_iv_gen_t *this, size_t size, chunk_t *chunk)
+ private_iv_gen_t *this, u_int64_t seq, size_t size, chunk_t *chunk)
{
*chunk = chunk_alloc(size);
- if (!get_iv(this, chunk->len, chunk->ptr))
+ if (!get_iv(this, seq, chunk->len, chunk->ptr))
{
chunk_free(chunk);
return FALSE;