34 #define PROTOID "tor-hs-ntor-curve25519-sha3-256-1"
35 #define PROTOID_LEN (sizeof(PROTOID) - 1)
36 #define SERVER_STR "Server"
37 #define SERVER_STR_LEN (sizeof(SERVER_STR) - 1)
40 #define T_HSENC PROTOID ":hs_key_extract"
41 #define T_HSENC_LEN (sizeof(T_HSENC) - 1)
42 #define T_HSVERIFY PROTOID ":hs_verify"
43 #define T_HSMAC PROTOID ":hs_mac"
44 #define M_HSEXPAND PROTOID ":hs_key_expand"
45 #define M_HSEXPAND_LEN (sizeof(M_HSEXPAND) - 1)
51 #define APPEND(ptr, inp, len) \
53 memcpy(ptr, (inp), (len)); \
58 #define REND_SECRET_HS_INPUT_LEN (CURVE25519_OUTPUT_LEN * 2 + \
59 ED25519_PUBKEY_LEN + CURVE25519_PUBKEY_LEN * 3 + PROTOID_LEN)
61 #define REND_AUTH_INPUT_LEN (DIGEST256_LEN + ED25519_PUBKEY_LEN + \
62 CURVE25519_PUBKEY_LEN * 3 + PROTOID_LEN + SERVER_STR_LEN)
92 uint8_t rend_auth_input[REND_AUTH_INPUT_LEN];
98 rend_secret_hs_input, REND_SECRET_HS_INPUT_LEN,
99 (
const uint8_t *)T_HSENC, strlen(T_HSENC));
104 rend_secret_hs_input, REND_SECRET_HS_INPUT_LEN,
105 (
const uint8_t *)T_HSVERIFY, strlen(T_HSVERIFY));
109 ptr = rend_auth_input;
111 APPEND(ptr, ntor_verify,
sizeof(ntor_verify));
123 APPEND(ptr, PROTOID, strlen(PROTOID));
125 APPEND(ptr, SERVER_STR, strlen(SERVER_STR));
126 tor_assert(ptr == rend_auth_input +
sizeof(rend_auth_input));
130 rend_auth_input,
sizeof(rend_auth_input),
131 (
const uint8_t *)T_HSMAC, strlen(T_HSMAC));
135 memcpy(&hs_ntor_rend_cell_keys_out->rend_cell_auth_mac,
137 memcpy(&hs_ntor_rend_cell_keys_out->ntor_key_seed,
141 memwipe(rend_cell_auth, 0,
sizeof(rend_cell_auth));
142 memwipe(rend_auth_input, 0,
sizeof(rend_auth_input));
143 memwipe(ntor_key_seed, 0,
sizeof(ntor_key_seed));
149 #define INTRO_SECRET_HS_INPUT_LEN (CURVE25519_OUTPUT_LEN +ED25519_PUBKEY_LEN +\
150 CURVE25519_PUBKEY_LEN + CURVE25519_PUBKEY_LEN + PROTOID_LEN)
152 #define INFO_BLOB_LEN (M_HSEXPAND_LEN + DIGEST256_LEN)
154 #define KDF_INPUT_LEN (INTRO_SECRET_HS_INPUT_LEN + T_HSENC_LEN + INFO_BLOB_LEN)
177 uint8_t info_blob[INFO_BLOB_LEN];
178 uint8_t kdf_input[KDF_INPUT_LEN];
183 APPEND(ptr, M_HSEXPAND, strlen(M_HSEXPAND));
184 APPEND(ptr, subcredential->subcred, SUBCRED_LEN);
185 tor_assert(ptr == info_blob +
sizeof(info_blob));
190 APPEND(ptr, T_HSENC, strlen(T_HSENC));
191 APPEND(ptr, info_blob,
sizeof(info_blob));
192 tor_assert(ptr == kdf_input +
sizeof(kdf_input));
196 kdf_input,
sizeof(kdf_input));
200 memcpy(&hs_ntor_intro_cell_keys_out->mac_key,
204 memwipe(keystream, 0,
sizeof(keystream));
205 memwipe(kdf_input, 0,
sizeof(kdf_input));
229 uint8_t *secret_input_out)
234 ptr = secret_input_out;
243 APPEND(ptr, PROTOID, strlen(PROTOID));
270 uint8_t *rend_secret_hs_input_out)
274 ptr = rend_secret_hs_input_out;
290 APPEND(ptr, PROTOID, strlen(PROTOID));
291 tor_assert(ptr == rend_secret_hs_input_out + REND_SECRET_HS_INPUT_LEN);
316 hs_ntor_client_get_introduce1_keys(
335 &client_ephemeral_enc_keypair->seckey,
341 &client_ephemeral_enc_keypair->pubkey,
342 intro_enc_pubkey, secret_input);
347 hs_ntor_intro_cell_keys_out);
350 memwipe(secret_input, 0,
sizeof(secret_input));
377 hs_ntor_client_get_rendezvous1_keys(
385 uint8_t rend_secret_hs_input[REND_SECRET_HS_INPUT_LEN];
397 &client_ephemeral_enc_keypair->seckey,
398 service_ephemeral_rend_pubkey);
403 &client_ephemeral_enc_keypair->seckey,
409 intro_auth_pubkey, intro_enc_pubkey,
410 &client_ephemeral_enc_keypair->pubkey,
411 service_ephemeral_rend_pubkey,
412 rend_secret_hs_input);
418 service_ephemeral_rend_pubkey,
419 &client_ephemeral_enc_keypair->pubkey,
420 hs_ntor_rend_cell_keys_out);
422 memwipe(rend_secret_hs_input, 0,
sizeof(rend_secret_hs_input));
449 hs_ntor_service_get_introduce1_keys(
459 client_ephemeral_enc_pubkey,
462 hs_ntor_intro_cell_keys_out);
474 size_t n_subcredentials,
491 &intro_enc_keypair->seckey,
492 client_ephemeral_enc_pubkey);
497 client_ephemeral_enc_pubkey,
498 &intro_enc_keypair->pubkey,
502 for (
unsigned i = 0; i < n_subcredentials; ++i) {
505 &hs_ntor_intro_cell_keys_out[i]);
508 memwipe(secret_input, 0,
sizeof(secret_input));
510 memwipe(hs_ntor_intro_cell_keys_out, 0,
536 hs_ntor_service_get_rendezvous1_keys(
544 uint8_t rend_secret_hs_input[REND_SECRET_HS_INPUT_LEN];
556 &service_ephemeral_rend_keypair->seckey,
557 client_ephemeral_enc_pubkey);
562 &intro_enc_keypair->seckey,
563 client_ephemeral_enc_pubkey);
569 &intro_enc_keypair->pubkey,
570 client_ephemeral_enc_pubkey,
571 &service_ephemeral_rend_keypair->pubkey,
572 rend_secret_hs_input);
577 &intro_enc_keypair->pubkey,
578 &service_ephemeral_rend_keypair->pubkey,
579 client_ephemeral_enc_pubkey,
580 hs_ntor_rend_cell_keys_out);
582 memwipe(rend_secret_hs_input, 0,
sizeof(rend_secret_hs_input));
596 const uint8_t *rcvd_mac)
601 return tor_memeq(hs_ntor_rend_cell_keys->rend_cell_auth_mac,
606 #define NTOR_KEY_EXPANSION_KDF_INPUT_LEN (DIGEST256_LEN + M_HSEXPAND_LEN)
616 uint8_t *keys_out,
size_t keys_out_len)
619 uint8_t kdf_input[NTOR_KEY_EXPANSION_KDF_INPUT_LEN];
625 if (BUG(keys_out_len != HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN)) {
632 APPEND(ptr, M_HSEXPAND, strlen(M_HSEXPAND));
633 tor_assert(ptr == kdf_input +
sizeof(kdf_input));
636 crypto_xof(keys_out, HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN,
637 kdf_input,
sizeof(kdf_input));
#define CIPHER256_KEY_LEN
void curve25519_handshake(uint8_t *output, const curve25519_secret_key_t *skey, const curve25519_public_key_t *pkey)
Header for crypto_curve25519.c.
void crypto_mac_sha3_256(uint8_t *mac_out, size_t len_out, const uint8_t *key, size_t key_len, const uint8_t *msg, size_t msg_len)
void crypto_xof(uint8_t *output, size_t output_len, const uint8_t *input, size_t input_len)
Header for crypto_ed25519.c.
void memwipe(void *mem, uint8_t byte, size_t sz)
Common functions for cryptographic routines.
int tor_memeq(const void *a, const void *b, size_t sz)
int safe_mem_is_zero(const void *mem, size_t sz)
int hs_ntor_circuit_key_expansion(const uint8_t *ntor_key_seed, size_t seed_len, uint8_t *keys_out, size_t keys_out_len)
#define INTRO_SECRET_HS_INPUT_LEN
static void get_rend_secret_hs_input(const uint8_t *dh_result1, const uint8_t *dh_result2, const ed25519_public_key_t *intro_auth_pubkey, const curve25519_public_key_t *intro_enc_pubkey, const curve25519_public_key_t *client_ephemeral_enc_pubkey, const curve25519_public_key_t *service_ephemeral_rend_pubkey, uint8_t *rend_secret_hs_input_out)
static void get_introduce1_key_material(const uint8_t *secret_input, const hs_subcredential_t *subcredential, hs_ntor_intro_cell_keys_t *hs_ntor_intro_cell_keys_out)
#define APPEND(ptr, inp, len)
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 hs_ntor_client_rendezvous2_mac_is_good(const hs_ntor_rend_cell_keys_t *hs_ntor_rend_cell_keys, const uint8_t *rcvd_mac)
static void get_intro_secret_hs_input(const uint8_t *dh_result, const ed25519_public_key_t *intro_auth_pubkey, const curve25519_public_key_t *client_ephemeral_enc_pubkey, const curve25519_public_key_t *intro_enc_pubkey, uint8_t *secret_input_out)
static int get_rendezvous1_key_material(const uint8_t *rend_secret_hs_input, const ed25519_public_key_t *intro_auth_pubkey, const curve25519_public_key_t *intro_enc_pubkey, const curve25519_public_key_t *service_ephemeral_rend_pubkey, const curve25519_public_key_t *client_ephemeral_enc_pubkey, hs_ntor_rend_cell_keys_t *hs_ntor_rend_cell_keys_out)
Master header file for Tor-specific functionality.
#define CURVE25519_OUTPUT_LEN
#define ED25519_PUBKEY_LEN
#define CURVE25519_PUBKEY_LEN