iv_gen: Provide external sequence number (IKE, ESP)
This prevents duplicate sequential IVs in case of a HA failover.
This commit is contained in:
parent
d74c254dfd
commit
e8229ad558
|
@ -1622,7 +1622,7 @@ METHOD(message_t, generate, status_t,
|
||||||
htoun32(lenpos, chunk.len + encryption->get_length(encryption));
|
htoun32(lenpos, chunk.len + encryption->get_length(encryption));
|
||||||
}
|
}
|
||||||
this->payloads->insert_last(this->payloads, 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);
|
generator->destroy(generator);
|
||||||
return INVALID_STATE;
|
return INVALID_STATE;
|
||||||
|
|
|
@ -309,7 +309,7 @@ static chunk_t append_header(private_encryption_payload_t *this, chunk_t assoc)
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(encryption_payload_t, encrypt, status_t,
|
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;
|
chunk_t iv, plain, padding, icv, crypt;
|
||||||
generator_t *generator;
|
generator_t *generator;
|
||||||
|
@ -364,7 +364,7 @@ METHOD(encryption_payload_t, encrypt, status_t,
|
||||||
crypt = chunk_create(plain.ptr, plain.len + padding.len);
|
crypt = chunk_create(plain.ptr, plain.len + padding.len);
|
||||||
generator->destroy(generator);
|
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))
|
!rng->get_bytes(rng, padding.len - 1, padding.ptr))
|
||||||
{
|
{
|
||||||
DBG1(DBG_ENC, "encrypting encryption payload failed, no IV or padding");
|
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,
|
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;
|
generator_t *generator;
|
||||||
chunk_t plain, padding;
|
chunk_t plain, padding;
|
||||||
|
|
|
@ -71,13 +71,15 @@ struct encryption_payload_t {
|
||||||
/**
|
/**
|
||||||
* Generate, encrypt and sign contained payloads.
|
* Generate, encrypt and sign contained payloads.
|
||||||
*
|
*
|
||||||
|
* @param mid message ID
|
||||||
* @param assoc associated data
|
* @param assoc associated data
|
||||||
* @return
|
* @return
|
||||||
* - SUCCESS if encryption successful
|
* - SUCCESS if encryption successful
|
||||||
* - FAILED if encryption failed
|
* - FAILED if encryption failed
|
||||||
* - INVALID_STATE if aead not supplied, but needed
|
* - 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.
|
* Decrypt, verify and parse contained payloads.
|
||||||
|
|
|
@ -319,7 +319,7 @@ METHOD(esp_packet_t, encrypt, status_t,
|
||||||
writer->write_uint32(writer, next_seqno);
|
writer->write_uint32(writer, next_seqno);
|
||||||
|
|
||||||
iv = writer->skip(writer, iv.len);
|
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");
|
DBG1(DBG_ESP, "ESP encryption failed: could not generate IV");
|
||||||
writer->destroy(writer);
|
writer->destroy(writer);
|
||||||
|
|
|
@ -33,21 +33,23 @@ struct iv_gen_t {
|
||||||
/**
|
/**
|
||||||
* Generates an IV and writes it into the buffer.
|
* Generates an IV and writes it into the buffer.
|
||||||
*
|
*
|
||||||
|
* @param seq external sequence number
|
||||||
* @param size size of IV in bytes
|
* @param size size of IV in bytes
|
||||||
* @param buffer pointer where the generated IV will be written
|
* @param buffer pointer where the generated IV will be written
|
||||||
* @return TRUE if IV allocation was successful, FALSE otherwise
|
* @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));
|
u_int8_t *buffer) __attribute__((warn_unused_result));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates an IV and allocates space for it.
|
* Generates an IV and allocates space for it.
|
||||||
*
|
*
|
||||||
|
* @param seq external sequence number
|
||||||
* @param size size of IV in bytes
|
* @param size size of IV in bytes
|
||||||
* @param chunk chunk which will hold the generated IV
|
* @param chunk chunk which will hold the generated IV
|
||||||
* @return TRUE if IV allocation was successful, FALSE otherwise
|
* @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));
|
chunk_t *chunk) __attribute__((warn_unused_result));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -36,7 +36,7 @@ struct private_iv_gen_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
METHOD(iv_gen_t, get_iv, bool,
|
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)
|
if (!this->rng)
|
||||||
{
|
{
|
||||||
|
@ -46,7 +46,7 @@ METHOD(iv_gen_t, get_iv, bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(iv_gen_t, allocate_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)
|
if (!this->rng)
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,38 +26,29 @@ struct private_iv_gen_t {
|
||||||
* Public iv_gen_t interface.
|
* Public iv_gen_t interface.
|
||||||
*/
|
*/
|
||||||
iv_gen_t public;
|
iv_gen_t public;
|
||||||
|
|
||||||
/**
|
|
||||||
* sequence number
|
|
||||||
*/
|
|
||||||
u_int64_t seq;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
METHOD(iv_gen_t, get_iv, bool,
|
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)];
|
u_int8_t iv[sizeof(u_int64_t)];
|
||||||
size_t len = size;
|
size_t len = size;
|
||||||
|
|
||||||
if (this->seq == UINT64_MAX || len < sizeof(u_int64_t))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (len > sizeof(u_int64_t))
|
if (len > sizeof(u_int64_t))
|
||||||
{
|
{
|
||||||
len = sizeof(u_int64_t);
|
len = sizeof(u_int64_t);
|
||||||
memset(buffer, 0, size - len);
|
memset(buffer, 0, size - len);
|
||||||
}
|
}
|
||||||
htoun64(iv, this->seq++);
|
htoun64(iv, seq);
|
||||||
memcpy(buffer + size - len, iv + sizeof(u_int64_t) - len, len);
|
memcpy(buffer + size - len, iv + sizeof(u_int64_t) - len, len);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(iv_gen_t, allocate_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)
|
||||||
{
|
{
|
||||||
*chunk = chunk_alloc(size);
|
*chunk = chunk_alloc(size);
|
||||||
if (!get_iv(this, chunk->len, chunk->ptr))
|
if (!get_iv(this, seq, chunk->len, chunk->ptr))
|
||||||
{
|
{
|
||||||
chunk_free(chunk);
|
chunk_free(chunk);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
Loading…
Reference in New Issue