tls-crypto: Add method to update application traffic keys
This commit is contained in:
+45
-40
@@ -1978,51 +1978,26 @@ METHOD(tls_crypto_t, derive_secrets, bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Derive and configure the keys/IVs using the given labels.
|
* Derive and configure the client/server key/IV on an AEAD using a given label.
|
||||||
*/
|
*/
|
||||||
static bool derive_labeled_keys(private_tls_crypto_t *this,
|
static bool derive_labeled_key(private_tls_crypto_t *this, bool server,
|
||||||
tls_hkdf_label_t client_label,
|
tls_hkdf_label_t label, tls_aead_t *aead)
|
||||||
tls_hkdf_label_t server_label)
|
|
||||||
{
|
{
|
||||||
chunk_t c_key = chunk_empty, c_iv = chunk_empty;
|
chunk_t key = chunk_empty, iv = chunk_empty;
|
||||||
chunk_t s_key = chunk_empty, s_iv = chunk_empty;
|
|
||||||
tls_aead_t *aead_c = this->aead_out, *aead_s = this->aead_in;
|
|
||||||
bool success = FALSE;
|
bool success = FALSE;
|
||||||
|
|
||||||
if (this->tls->is_server(this->tls))
|
if (!this->hkdf->generate_secret(this->hkdf, label, this->handshake,
|
||||||
{
|
|
||||||
aead_c = this->aead_in;
|
|
||||||
aead_s = this->aead_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->hkdf->generate_secret(this->hkdf, client_label, this->handshake,
|
|
||||||
NULL) ||
|
NULL) ||
|
||||||
!this->hkdf->derive_key(this->hkdf, FALSE,
|
!this->hkdf->derive_key(this->hkdf, server,
|
||||||
this->aead_out->get_encr_key_size(this->aead_out),
|
aead->get_encr_key_size(aead), &key) ||
|
||||||
&c_key) ||
|
!this->hkdf->derive_iv(this->hkdf, server,
|
||||||
!this->hkdf->derive_iv(this->hkdf, FALSE,
|
aead->get_iv_size(aead), &iv))
|
||||||
this->aead_out->get_iv_size(this->aead_out),
|
|
||||||
&c_iv))
|
|
||||||
{
|
{
|
||||||
DBG1(DBG_TLS, "deriving client key material failed");
|
DBG1(DBG_TLS, "deriving key material failed");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->hkdf->generate_secret(this->hkdf, server_label, this->handshake,
|
if (!aead->set_keys(aead, chunk_empty, key, iv))
|
||||||
NULL) ||
|
|
||||||
!this->hkdf->derive_key(this->hkdf, TRUE,
|
|
||||||
this->aead_in->get_encr_key_size(this->aead_in),
|
|
||||||
&s_key) ||
|
|
||||||
!this->hkdf->derive_iv(this->hkdf, TRUE,
|
|
||||||
this->aead_in->get_iv_size(this->aead_in),
|
|
||||||
&s_iv))
|
|
||||||
{
|
|
||||||
DBG1(DBG_TLS, "deriving server key material failed");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!aead_c->set_keys(aead_c, chunk_empty, c_key, c_iv) ||
|
|
||||||
!aead_s->set_keys(aead_s, chunk_empty, s_key, s_iv))
|
|
||||||
{
|
{
|
||||||
DBG1(DBG_TLS, "setting AEAD key material failed");
|
DBG1(DBG_TLS, "setting AEAD key material failed");
|
||||||
goto out;
|
goto out;
|
||||||
@@ -2030,13 +2005,29 @@ static bool derive_labeled_keys(private_tls_crypto_t *this,
|
|||||||
success = TRUE;
|
success = TRUE;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
chunk_clear(&c_key);
|
chunk_clear(&key);
|
||||||
chunk_clear(&c_iv);
|
chunk_clear(&iv);
|
||||||
chunk_clear(&s_key);
|
|
||||||
chunk_clear(&s_iv);
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derive and configure the keys/IVs using the given labels.
|
||||||
|
*/
|
||||||
|
static bool derive_labeled_keys(private_tls_crypto_t *this,
|
||||||
|
tls_hkdf_label_t client_label,
|
||||||
|
tls_hkdf_label_t server_label)
|
||||||
|
{
|
||||||
|
tls_aead_t *aead_c = this->aead_out, *aead_s = this->aead_in;
|
||||||
|
|
||||||
|
if (this->tls->is_server(this->tls))
|
||||||
|
{
|
||||||
|
aead_c = this->aead_in;
|
||||||
|
aead_s = this->aead_out;
|
||||||
|
}
|
||||||
|
return derive_labeled_key(this, FALSE, client_label, aead_c) &&
|
||||||
|
derive_labeled_key(this, TRUE, server_label, aead_s);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(tls_crypto_t, derive_handshake_keys, bool,
|
METHOD(tls_crypto_t, derive_handshake_keys, bool,
|
||||||
private_tls_crypto_t *this, chunk_t shared_secret)
|
private_tls_crypto_t *this, chunk_t shared_secret)
|
||||||
{
|
{
|
||||||
@@ -2052,6 +2043,19 @@ METHOD(tls_crypto_t, derive_app_keys, bool,
|
|||||||
TLS_HKDF_S_AP_TRAFFIC);
|
TLS_HKDF_S_AP_TRAFFIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(tls_crypto_t, update_app_keys, bool,
|
||||||
|
private_tls_crypto_t *this, bool inbound)
|
||||||
|
{
|
||||||
|
tls_hkdf_label_t label = TLS_HKDF_UPD_C_TRAFFIC;
|
||||||
|
|
||||||
|
if (this->tls->is_server(this->tls) != inbound)
|
||||||
|
{
|
||||||
|
label = TLS_HKDF_UPD_S_TRAFFIC;
|
||||||
|
}
|
||||||
|
return derive_labeled_key(this, label == TLS_HKDF_UPD_S_TRAFFIC, label,
|
||||||
|
inbound ? this->aead_in : this->aead_out);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(tls_crypto_t, resume_session, tls_cipher_suite_t,
|
METHOD(tls_crypto_t, resume_session, tls_cipher_suite_t,
|
||||||
private_tls_crypto_t *this, chunk_t session, identification_t *id,
|
private_tls_crypto_t *this, chunk_t session, identification_t *id,
|
||||||
chunk_t client_random, chunk_t server_random)
|
chunk_t client_random, chunk_t server_random)
|
||||||
@@ -2152,6 +2156,7 @@ tls_crypto_t *tls_crypto_create(tls_t *tls, tls_cache_t *cache)
|
|||||||
.derive_secrets = _derive_secrets,
|
.derive_secrets = _derive_secrets,
|
||||||
.derive_handshake_keys = _derive_handshake_keys,
|
.derive_handshake_keys = _derive_handshake_keys,
|
||||||
.derive_app_keys = _derive_app_keys,
|
.derive_app_keys = _derive_app_keys,
|
||||||
|
.update_app_keys = _update_app_keys,
|
||||||
.resume_session = _resume_session,
|
.resume_session = _resume_session,
|
||||||
.get_session = _get_session,
|
.get_session = _get_session,
|
||||||
.change_cipher = _change_cipher,
|
.change_cipher = _change_cipher,
|
||||||
|
|||||||
@@ -574,6 +574,14 @@ struct tls_crypto_t {
|
|||||||
*/
|
*/
|
||||||
bool (*derive_app_keys)(tls_crypto_t *this);
|
bool (*derive_app_keys)(tls_crypto_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the application keys.
|
||||||
|
*
|
||||||
|
* @param inbound whether to update the in- or outbound keys
|
||||||
|
* @return TRUE if secret derived successfully
|
||||||
|
*/
|
||||||
|
bool (*update_app_keys)(tls_crypto_t *this, bool inbound);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to resume a TLS session, derive key material.
|
* Try to resume a TLS session, derive key material.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user