diff options
Diffstat (limited to 'src/core/crypto/hs_ntor.c')
-rw-r--r-- | src/core/crypto/hs_ntor.c | 60 |
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; } |