Add a return value to keymat_v1_t.{get,update,confirm}_iv
This commit is contained in:
@@ -1568,7 +1568,11 @@ METHOD(message_t, generate, status_t,
|
||||
encryption->set_transform(encryption, aead);
|
||||
if (this->is_encrypted)
|
||||
{ /* for IKEv1 instead of associated data we provide the IV */
|
||||
chunk = keymat_v1->get_iv(keymat_v1, this->message_id);
|
||||
if (!keymat_v1->get_iv(keymat_v1, this->message_id, &chunk))
|
||||
{
|
||||
generator->destroy(generator);
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* build associated data (without header of encryption payload) */
|
||||
@@ -1579,9 +1583,17 @@ METHOD(message_t, generate, status_t,
|
||||
this->payloads->insert_last(this->payloads, encryption);
|
||||
if (!encryption->encrypt(encryption, chunk))
|
||||
{
|
||||
if (this->is_encrypted)
|
||||
{
|
||||
free(chunk.ptr);
|
||||
}
|
||||
generator->destroy(generator);
|
||||
return INVALID_STATE;
|
||||
}
|
||||
if (this->is_encrypted)
|
||||
{
|
||||
free(chunk.ptr);
|
||||
}
|
||||
generator->generate_payload(generator, &encryption->payload_interface);
|
||||
}
|
||||
chunk = generator->get_chunk(generator, &lenpos);
|
||||
@@ -1595,8 +1607,12 @@ METHOD(message_t, generate, status_t,
|
||||
|
||||
bs = aead->get_block_size(aead);
|
||||
last_block = chunk_create(chunk.ptr + chunk.len - bs, bs);
|
||||
keymat_v1->update_iv(keymat_v1, this->message_id, last_block);
|
||||
keymat_v1->confirm_iv(keymat_v1, this->message_id);
|
||||
if (!keymat_v1->update_iv(keymat_v1, this->message_id, last_block) ||
|
||||
!keymat_v1->confirm_iv(keymat_v1, this->message_id))
|
||||
{
|
||||
generator->destroy(generator);
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
generator->destroy(generator);
|
||||
*packet = this->packet->clone(this->packet);
|
||||
@@ -1846,17 +1862,25 @@ static status_t decrypt_payloads(private_message_t *this, keymat_t *keymat)
|
||||
{ /* instead of associated data we provide the IV, we also update
|
||||
* the IV with the last encrypted block */
|
||||
keymat_v1_t *keymat_v1 = (keymat_v1_t*)keymat;
|
||||
chunk_t last_block;
|
||||
chunk_t iv = chunk_empty;
|
||||
|
||||
last_block = chunk_create(chunk.ptr + chunk.len - bs, bs);
|
||||
chunk = keymat_v1->get_iv(keymat_v1, this->message_id);
|
||||
keymat_v1->update_iv(keymat_v1, this->message_id, last_block);
|
||||
if (keymat_v1->get_iv(keymat_v1, this->message_id, &iv) &&
|
||||
keymat_v1->update_iv(keymat_v1, this->message_id,
|
||||
chunk_create(chunk.ptr + chunk.len - bs, bs)))
|
||||
{
|
||||
status = encryption->decrypt(encryption, iv);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = FAILED;
|
||||
}
|
||||
free(chunk.ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
chunk.len -= encryption->get_length(encryption);
|
||||
status = encryption->decrypt(encryption, chunk);
|
||||
}
|
||||
status = encryption->decrypt(encryption, chunk);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
break;
|
||||
@@ -2035,7 +2059,10 @@ METHOD(message_t, parse_body, status_t,
|
||||
}
|
||||
if (this->is_encrypted)
|
||||
{ /* message verified, confirm IV */
|
||||
keymat_v1->confirm_iv(keymat_v1, this->message_id);
|
||||
if (!keymat_v1->confirm_iv(keymat_v1, this->message_id))
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
|
||||
@@ -525,8 +525,10 @@ static void process_ike_iv(private_ha_dispatcher_t *this, ha_message_t *message)
|
||||
keymat_v1_t *keymat;
|
||||
|
||||
keymat = (keymat_v1_t*)ike_sa->get_keymat(ike_sa);
|
||||
keymat->update_iv(keymat, 0, iv);
|
||||
keymat->confirm_iv(keymat, 0);
|
||||
if (keymat->update_iv(keymat, 0, iv))
|
||||
{
|
||||
keymat->confirm_iv(keymat, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
this->cache->cache(this->cache, ike_sa, message);
|
||||
|
||||
@@ -302,13 +302,15 @@ METHOD(listener_t, message_hook, bool,
|
||||
if (mid == 0)
|
||||
{
|
||||
keymat = (keymat_v1_t*)ike_sa->get_keymat(ike_sa);
|
||||
iv = keymat->get_iv(keymat, mid);
|
||||
m = ha_message_create(HA_IKE_IV);
|
||||
m->add_attribute(m, HA_IKE_ID, ike_sa->get_id(ike_sa));
|
||||
m->add_attribute(m, HA_IV, iv);
|
||||
free(iv.ptr);
|
||||
this->socket->push(this->socket, m);
|
||||
this->cache->cache(this->cache, ike_sa, m);
|
||||
if (keymat->get_iv(keymat, mid, &iv))
|
||||
{
|
||||
m = ha_message_create(HA_IKE_IV);
|
||||
m->add_attribute(m, HA_IKE_ID, ike_sa->get_id(ike_sa));
|
||||
m->add_attribute(m, HA_IV, iv);
|
||||
free(iv.ptr);
|
||||
this->socket->push(this->socket, m);
|
||||
this->cache->cache(this->cache, ike_sa, m);
|
||||
}
|
||||
}
|
||||
if (!incoming && message->get_exchange_type(message) == TRANSACTION)
|
||||
{
|
||||
|
||||
@@ -964,7 +964,7 @@ METHOD(keymat_v1_t, get_hash_phase2, bool,
|
||||
/**
|
||||
* Generate an IV
|
||||
*/
|
||||
static void generate_iv(private_keymat_v1_t *this, iv_data_t *iv)
|
||||
static bool generate_iv(private_keymat_v1_t *this, iv_data_t *iv)
|
||||
{
|
||||
if (iv->mid == 0 || iv->iv.ptr)
|
||||
{ /* use last block of previous encrypted message */
|
||||
@@ -985,6 +985,7 @@ static void generate_iv(private_keymat_v1_t *this, iv_data_t *iv)
|
||||
}
|
||||
}
|
||||
DBG4(DBG_IKE, "next IV for MID %u %B", iv->mid, &iv->iv);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1016,7 +1017,11 @@ static iv_data_t *lookup_iv(private_keymat_v1_t *this, u_int32_t mid)
|
||||
INIT(found,
|
||||
.mid = mid,
|
||||
);
|
||||
generate_iv(this, found);
|
||||
if (!generate_iv(this, found))
|
||||
{
|
||||
iv_data_destroy(found);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
this->ivs->insert_first(this->ivs, found);
|
||||
/* remove least recently used IV if maximum reached */
|
||||
@@ -1028,13 +1033,21 @@ static iv_data_t *lookup_iv(private_keymat_v1_t *this, u_int32_t mid)
|
||||
return found;
|
||||
}
|
||||
|
||||
METHOD(keymat_v1_t, get_iv, chunk_t,
|
||||
private_keymat_v1_t *this, u_int32_t mid)
|
||||
METHOD(keymat_v1_t, get_iv, bool,
|
||||
private_keymat_v1_t *this, u_int32_t mid, chunk_t *out)
|
||||
{
|
||||
return chunk_clone(lookup_iv(this, mid)->iv);
|
||||
iv_data_t *iv;
|
||||
|
||||
iv = lookup_iv(this, mid);
|
||||
if (iv)
|
||||
{
|
||||
*out = iv->iv;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(keymat_v1_t, update_iv, void,
|
||||
METHOD(keymat_v1_t, update_iv, bool,
|
||||
private_keymat_v1_t *this, u_int32_t mid, chunk_t last_block)
|
||||
{
|
||||
iv_data_t *iv = lookup_iv(this, mid);
|
||||
@@ -1042,17 +1055,20 @@ METHOD(keymat_v1_t, update_iv, void,
|
||||
{ /* update last block */
|
||||
chunk_free(&iv->last_block);
|
||||
iv->last_block = chunk_clone(last_block);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(keymat_v1_t, confirm_iv, void,
|
||||
METHOD(keymat_v1_t, confirm_iv, bool,
|
||||
private_keymat_v1_t *this, u_int32_t mid)
|
||||
{
|
||||
iv_data_t *iv = lookup_iv(this, mid);
|
||||
if (iv)
|
||||
{
|
||||
generate_iv(this, iv);
|
||||
return generate_iv(this, iv);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(keymat_t, get_version, ike_version_t,
|
||||
|
||||
@@ -121,9 +121,10 @@ struct keymat_v1_t {
|
||||
* Returns the IV for a message with the given message ID.
|
||||
*
|
||||
* @param mid message ID
|
||||
* @return IV (needs to be freed)
|
||||
* @param iv chunk receiving allocated IV
|
||||
* @return TRUE if IV allocated successfully
|
||||
*/
|
||||
chunk_t (*get_iv)(keymat_v1_t *this, u_int32_t mid);
|
||||
bool (*get_iv)(keymat_v1_t *this, u_int32_t mid, chunk_t *iv);
|
||||
|
||||
/**
|
||||
* Updates the IV for the next message with the given message ID.
|
||||
@@ -135,8 +136,9 @@ struct keymat_v1_t {
|
||||
*
|
||||
* @param mid message ID
|
||||
* @param last_block last block of encrypted message (gets cloned)
|
||||
* @return TRUE if IV updated successfully
|
||||
*/
|
||||
void (*update_iv)(keymat_v1_t *this, u_int32_t mid, chunk_t last_block);
|
||||
bool (*update_iv)(keymat_v1_t *this, u_int32_t mid, chunk_t last_block);
|
||||
|
||||
/**
|
||||
* Confirms the updated IV for the given message ID.
|
||||
@@ -145,9 +147,9 @@ struct keymat_v1_t {
|
||||
* be called after update_iv.
|
||||
*
|
||||
* @param mid message ID
|
||||
* @return TRUE if IV confirmed successfully
|
||||
*/
|
||||
void (*confirm_iv)(keymat_v1_t *this, u_int32_t mid);
|
||||
|
||||
bool (*confirm_iv)(keymat_v1_t *this, u_int32_t mid);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user