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:
George Kadianakis 2019-12-10 13:54:47 +02:00 committed by Nick Mathewson
parent 16a201e703
commit f1498e75dd

View File

@ -747,6 +747,61 @@ hs_cell_parse_intro_established(const uint8_t *payload, size_t payload_len)
return ret; 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 /** Parse the INTRODUCE2 cell using data which contains everything we need to
* do so and contains the destination buffers of information we extract and * 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 * 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; goto done;
} }
/* Build the key material out of the key material found in the cell. */ /* Get the right INTRODUCE2 ntor keys and verify the cell MAC */
intro_keys = get_introduce2_key_material(data->auth_pk, data->enc_kp, intro_keys = get_introduce2_keys_and_verify_mac(data, encrypted_section,
data->subcredential, encrypted_section_len);
encrypted_section, if (!intro_keys) {
&data->client_pk); log_info(LD_REND, "Could not get valid INTRO2 keys on circuit %u "
if (intro_keys == NULL) { "for service %s", TO_CIRCUIT(circ)->n_circ_id,
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,
safe_str_client(service->onion_address)); safe_str_client(service->onion_address));
goto done; 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. */ /* The ENCRYPTED_DATA section starts just after the CLIENT_PK. */
const uint8_t *encrypted_data = const uint8_t *encrypted_data =