mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
hs-v3: Extract INTRO2 key computation to its own function.
Part of #32709 Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
parent
16a201e703
commit
f1498e75dd
@ -747,6 +747,61 @@ hs_cell_parse_intro_established(const uint8_t *payload, size_t payload_len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** For the encrypted INTRO2 cell in <b>encrypted_section</b>, use the crypto
|
||||
* material in <b>data</b> to compute the right ntor keys. Also validate the
|
||||
* INTRO2 MAC to ensure that the keys are the right ones.
|
||||
*
|
||||
* Return NULL on failure to either produce the key material or on MAC
|
||||
* valication. Else a newly allocated intro keys object. */
|
||||
static hs_ntor_intro_cell_keys_t *
|
||||
get_introduce2_keys_and_verify_mac(hs_cell_introduce2_data_t *data,
|
||||
const uint8_t *encrypted_section,
|
||||
size_t encrypted_section_len)
|
||||
{
|
||||
hs_ntor_intro_cell_keys_t *intro_keys = NULL;
|
||||
|
||||
/* Build the key material out of the key material found in the cell. */
|
||||
intro_keys = get_introduce2_key_material(data->auth_pk, data->enc_kp,
|
||||
data->subcredential,
|
||||
encrypted_section,
|
||||
&data->client_pk);
|
||||
if (intro_keys == NULL) {
|
||||
log_info(LD_REND, "Invalid INTRODUCE2 encrypted data. Unable to "
|
||||
"compute key material");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Validate MAC from the cell and our computed key material. The MAC field
|
||||
* in the cell is at the end of the encrypted section. */
|
||||
{
|
||||
uint8_t mac[DIGEST256_LEN];
|
||||
/* The MAC field is at the very end of the ENCRYPTED section. */
|
||||
size_t mac_offset = encrypted_section_len - sizeof(mac);
|
||||
/* Compute the MAC. Use the entire encoded payload with a length up to the
|
||||
* ENCRYPTED section. */
|
||||
compute_introduce_mac(data->payload,
|
||||
data->payload_len - encrypted_section_len,
|
||||
encrypted_section, encrypted_section_len,
|
||||
intro_keys->mac_key, sizeof(intro_keys->mac_key),
|
||||
mac, sizeof(mac));
|
||||
if (tor_memcmp(mac, encrypted_section + mac_offset, sizeof(mac))) {
|
||||
log_info(LD_REND, "Invalid MAC validation for INTRODUCE2 cell");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
goto done;
|
||||
|
||||
err:
|
||||
if (intro_keys) {
|
||||
memwipe(intro_keys, 0, sizeof(hs_ntor_intro_cell_keys_t));
|
||||
tor_free(intro_keys);
|
||||
}
|
||||
|
||||
done:
|
||||
return intro_keys;
|
||||
}
|
||||
|
||||
/** Parse the INTRODUCE2 cell using data which contains everything we need to
|
||||
* do so and contains the destination buffers of information we extract and
|
||||
* compute from the cell. Return 0 on success else a negative value. The
|
||||
@ -801,41 +856,16 @@ hs_cell_parse_introduce2(hs_cell_introduce2_data_t *data,
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Build the key material out of the key material found in the cell. */
|
||||
intro_keys = get_introduce2_key_material(data->auth_pk, data->enc_kp,
|
||||
data->subcredential,
|
||||
encrypted_section,
|
||||
&data->client_pk);
|
||||
if (intro_keys == NULL) {
|
||||
log_info(LD_REND, "Invalid INTRODUCE2 encrypted data. Unable to "
|
||||
"compute key material on circuit %u for service %s",
|
||||
TO_CIRCUIT(circ)->n_circ_id,
|
||||
/* Get the right INTRODUCE2 ntor keys and verify the cell MAC */
|
||||
intro_keys = get_introduce2_keys_and_verify_mac(data, encrypted_section,
|
||||
encrypted_section_len);
|
||||
if (!intro_keys) {
|
||||
log_info(LD_REND, "Could not get valid INTRO2 keys on circuit %u "
|
||||
"for service %s", TO_CIRCUIT(circ)->n_circ_id,
|
||||
safe_str_client(service->onion_address));
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Validate MAC from the cell and our computed key material. The MAC field
|
||||
* in the cell is at the end of the encrypted section. */
|
||||
{
|
||||
uint8_t mac[DIGEST256_LEN];
|
||||
/* The MAC field is at the very end of the ENCRYPTED section. */
|
||||
size_t mac_offset = encrypted_section_len - sizeof(mac);
|
||||
/* Compute the MAC. Use the entire encoded payload with a length up to the
|
||||
* ENCRYPTED section. */
|
||||
compute_introduce_mac(data->payload,
|
||||
data->payload_len - encrypted_section_len,
|
||||
encrypted_section, encrypted_section_len,
|
||||
intro_keys->mac_key, sizeof(intro_keys->mac_key),
|
||||
mac, sizeof(mac));
|
||||
if (tor_memcmp(mac, encrypted_section + mac_offset, sizeof(mac))) {
|
||||
log_info(LD_REND, "Invalid MAC validation for INTRODUCE2 cell on "
|
||||
"circuit %u for service %s",
|
||||
TO_CIRCUIT(circ)->n_circ_id,
|
||||
safe_str_client(service->onion_address));
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/* The ENCRYPTED_DATA section starts just after the CLIENT_PK. */
|
||||
const uint8_t *encrypted_data =
|
||||
|
Loading…
Reference in New Issue
Block a user