aboutsummaryrefslogtreecommitdiff
path: root/src/core/crypto/hs_ntor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/crypto/hs_ntor.c')
-rw-r--r--src/core/crypto/hs_ntor.c60
1 files changed, 40 insertions, 20 deletions
diff --git a/src/core/crypto/hs_ntor.c b/src/core/crypto/hs_ntor.c
index c34073690e..07bcdc566c 100644
--- a/src/core/crypto/hs_ntor.c
+++ b/src/core/crypto/hs_ntor.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Tor Project, Inc. */
+/* Copyright (c) 2017-2020, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/** \file hs_ntor.c
@@ -170,19 +170,18 @@ get_rendezvous1_key_material(const uint8_t *rend_secret_hs_input,
* necessary key material, and return 0. */
static void
get_introduce1_key_material(const uint8_t *secret_input,
- const uint8_t *subcredential,
+ const hs_subcredential_t *subcredential,
hs_ntor_intro_cell_keys_t *hs_ntor_intro_cell_keys_out)
{
uint8_t keystream[CIPHER256_KEY_LEN + DIGEST256_LEN];
uint8_t info_blob[INFO_BLOB_LEN];
uint8_t kdf_input[KDF_INPUT_LEN];
- crypto_xof_t *xof;
uint8_t *ptr;
/* Let's build info */
ptr = info_blob;
APPEND(ptr, M_HSEXPAND, strlen(M_HSEXPAND));
- APPEND(ptr, subcredential, DIGEST256_LEN);
+ APPEND(ptr, subcredential->subcred, SUBCRED_LEN);
tor_assert(ptr == info_blob + sizeof(info_blob));
/* Let's build the input to the KDF */
@@ -193,10 +192,8 @@ get_introduce1_key_material(const uint8_t *secret_input,
tor_assert(ptr == kdf_input + sizeof(kdf_input));
/* Now we need to run kdf_input over SHAKE-256 */
- xof = crypto_xof_new();
- crypto_xof_add_bytes(xof, kdf_input, sizeof(kdf_input));
- crypto_xof_squeeze_bytes(xof, keystream, sizeof(keystream)) ;
- crypto_xof_free(xof);
+ crypto_xof(keystream, sizeof(keystream),
+ kdf_input, sizeof(kdf_input));
{ /* Get the keys */
memcpy(&hs_ntor_intro_cell_keys_out->enc_key, keystream,CIPHER256_KEY_LEN);
@@ -320,7 +317,7 @@ hs_ntor_client_get_introduce1_keys(
const ed25519_public_key_t *intro_auth_pubkey,
const curve25519_public_key_t *intro_enc_pubkey,
const curve25519_keypair_t *client_ephemeral_enc_keypair,
- const uint8_t *subcredential,
+ const hs_subcredential_t *subcredential,
hs_ntor_intro_cell_keys_t *hs_ntor_intro_cell_keys_out)
{
int bad = 0;
@@ -453,9 +450,31 @@ hs_ntor_service_get_introduce1_keys(
const ed25519_public_key_t *intro_auth_pubkey,
const curve25519_keypair_t *intro_enc_keypair,
const curve25519_public_key_t *client_ephemeral_enc_pubkey,
- const uint8_t *subcredential,
+ const hs_subcredential_t *subcredential,
hs_ntor_intro_cell_keys_t *hs_ntor_intro_cell_keys_out)
{
+ return hs_ntor_service_get_introduce1_keys_multi(
+ intro_auth_pubkey,
+ intro_enc_keypair,
+ client_ephemeral_enc_pubkey,
+ 1,
+ subcredential,
+ hs_ntor_intro_cell_keys_out);
+}
+
+/**
+ * As hs_ntor_service_get_introduce1_keys(), but take multiple subcredentials
+ * as input, and yield multiple sets of keys as output.
+ **/
+int
+hs_ntor_service_get_introduce1_keys_multi(
+ const struct ed25519_public_key_t *intro_auth_pubkey,
+ const struct curve25519_keypair_t *intro_enc_keypair,
+ const struct curve25519_public_key_t *client_ephemeral_enc_pubkey,
+ size_t n_subcredentials,
+ const hs_subcredential_t *subcredentials,
+ hs_ntor_intro_cell_keys_t *hs_ntor_intro_cell_keys_out)
+{
int bad = 0;
uint8_t secret_input[INTRO_SECRET_HS_INPUT_LEN];
uint8_t dh_result[CURVE25519_OUTPUT_LEN];
@@ -463,7 +482,8 @@ hs_ntor_service_get_introduce1_keys(
tor_assert(intro_auth_pubkey);
tor_assert(intro_enc_keypair);
tor_assert(client_ephemeral_enc_pubkey);
- tor_assert(subcredential);
+ tor_assert(n_subcredentials >= 1);
+ tor_assert(subcredentials);
tor_assert(hs_ntor_intro_cell_keys_out);
/* Compute EXP(X, b) */
@@ -479,13 +499,16 @@ hs_ntor_service_get_introduce1_keys(
secret_input);
bad |= safe_mem_is_zero(secret_input, CURVE25519_OUTPUT_LEN);
- /* Get ENC_KEY and MAC_KEY! */
- get_introduce1_key_material(secret_input, subcredential,
- hs_ntor_intro_cell_keys_out);
+ for (unsigned i = 0; i < n_subcredentials; ++i) {
+ /* Get ENC_KEY and MAC_KEY! */
+ get_introduce1_key_material(secret_input, &subcredentials[i],
+ &hs_ntor_intro_cell_keys_out[i]);
+ }
memwipe(secret_input, 0, sizeof(secret_input));
if (bad) {
- memwipe(hs_ntor_intro_cell_keys_out, 0, sizeof(hs_ntor_intro_cell_keys_t));
+ memwipe(hs_ntor_intro_cell_keys_out, 0,
+ sizeof(hs_ntor_intro_cell_keys_t) * n_subcredentials);
}
return bad ? -1 : 0;
@@ -594,7 +617,6 @@ hs_ntor_circuit_key_expansion(const uint8_t *ntor_key_seed, size_t seed_len,
{
uint8_t *ptr;
uint8_t kdf_input[NTOR_KEY_EXPANSION_KDF_INPUT_LEN];
- crypto_xof_t *xof;
/* Sanity checks on lengths to make sure we are good */
if (BUG(seed_len != DIGEST256_LEN)) {
@@ -611,10 +633,8 @@ hs_ntor_circuit_key_expansion(const uint8_t *ntor_key_seed, size_t seed_len,
tor_assert(ptr == kdf_input + sizeof(kdf_input));
/* Generate the keys */
- xof = crypto_xof_new();
- crypto_xof_add_bytes(xof, kdf_input, sizeof(kdf_input));
- crypto_xof_squeeze_bytes(xof, keys_out, HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN);
- crypto_xof_free(xof);
+ crypto_xof(keys_out, HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN,
+ kdf_input, sizeof(kdf_input));
return 0;
}