Tor
0.4.7.0-alpha-dev
|
Implements the ntor variant used in Tor hidden services. More...
#include "core/or/or.h"
#include "lib/crypt_ops/crypto_util.h"
#include "lib/crypt_ops/crypto_curve25519.h"
#include "lib/crypt_ops/crypto_ed25519.h"
#include "core/crypto/hs_ntor.h"
Go to the source code of this file.
Macros | |
#define | PROTOID "tor-hs-ntor-curve25519-sha3-256-1" |
#define | PROTOID_LEN (sizeof(PROTOID) - 1) |
#define | SERVER_STR "Server" |
#define | SERVER_STR_LEN (sizeof(SERVER_STR) - 1) |
#define | T_HSENC PROTOID ":hs_key_extract" |
#define | T_HSENC_LEN (sizeof(T_HSENC) - 1) |
#define | T_HSVERIFY PROTOID ":hs_verify" |
#define | T_HSMAC PROTOID ":hs_mac" |
#define | M_HSEXPAND PROTOID ":hs_key_expand" |
#define | M_HSEXPAND_LEN (sizeof(M_HSEXPAND) - 1) |
#define | APPEND(ptr, inp, len) |
#define | REND_SECRET_HS_INPUT_LEN |
#define | REND_AUTH_INPUT_LEN |
#define | INTRO_SECRET_HS_INPUT_LEN |
#define | INFO_BLOB_LEN (M_HSEXPAND_LEN + DIGEST256_LEN) |
#define | KDF_INPUT_LEN (INTRO_SECRET_HS_INPUT_LEN + T_HSENC_LEN + INFO_BLOB_LEN) |
#define | NTOR_KEY_EXPANSION_KDF_INPUT_LEN (DIGEST256_LEN + M_HSEXPAND_LEN) |
Functions | |
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) |
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) |
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 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) |
int | 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 hs_subcredential_t *subcredential, hs_ntor_intro_cell_keys_t *hs_ntor_intro_cell_keys_out) |
int | hs_ntor_client_get_rendezvous1_keys (const ed25519_public_key_t *intro_auth_pubkey, const curve25519_keypair_t *client_ephemeral_enc_keypair, const curve25519_public_key_t *intro_enc_pubkey, const curve25519_public_key_t *service_ephemeral_rend_pubkey, hs_ntor_rend_cell_keys_t *hs_ntor_rend_cell_keys_out) |
int | 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 hs_subcredential_t *subcredential, hs_ntor_intro_cell_keys_t *hs_ntor_intro_cell_keys_out) |
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_service_get_rendezvous1_keys (const ed25519_public_key_t *intro_auth_pubkey, const curve25519_keypair_t *intro_enc_keypair, const curve25519_keypair_t *service_ephemeral_rend_keypair, const curve25519_public_key_t *client_ephemeral_enc_pubkey, hs_ntor_rend_cell_keys_t *hs_ntor_rend_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) |
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) |
Implements the ntor variant used in Tor hidden services.
This module handles the variant of the ntor handshake that is documented in section [NTOR-WITH-EXTRA-DATA] of rend-spec-ng.txt .
The functions in this file provide an API that should be used when sending or receiving INTRODUCE1/RENDEZVOUS1 cells to generate the various key material required to create and handle those cells.
In the case of INTRODUCE1 it provides encryption and MAC keys to encode/decode the encrypted blob (see hs_ntor_intro_cell_keys_t). The relevant pub functions are hs_ntor_{client,service}_get_introduce1_keys().
In the case of RENDEZVOUS1 it calculates the MAC required to authenticate the cell, and also provides the key seed that is used to derive the crypto material for rendezvous encryption (see hs_ntor_rend_cell_keys_t). The relevant pub functions are hs_ntor_{client,service}_get_rendezvous1_keys(). It also provides a function (hs_ntor_circuit_key_expansion()) that does the rendezvous key expansion to setup end-to-end rend circuit keys.
Definition in file hs_ntor.c.
#define APPEND | ( | ptr, | |
inp, | |||
len | |||
) |
Helper macro: copy len bytes from inp to ptr and advance ptr by the number of bytes copied. Stolen from onion_ntor.c
#define INTRO_SECRET_HS_INPUT_LEN |
Length of secret_input = EXP(B,x) | AUTH_KEY | X | B | PROTOID
#define REND_AUTH_INPUT_LEN |
#define REND_SECRET_HS_INPUT_LEN |
|
static |
Helper function: Calculate the 'intro_secret_hs_input' element used by the HS ntor handshake and place it in secret_input_out. This function is used by both client and service code.
For the client-side it looks like this:
intro_secret_hs_input = EXP(B,x) | AUTH_KEY | X | B | PROTOID
whereas for the service-side it looks like this:
intro_secret_hs_input = EXP(X,b) | AUTH_KEY | X | B | PROTOID
In this function, dh_result carries the EXP() result (and has size CURVE25519_OUTPUT_LEN) intro_auth_pubkey is AUTH_KEY, client_ephemeral_enc_pubkey is X, and intro_enc_pubkey is B.
Definition at line 225 of file hs_ntor.c.
Referenced by hs_ntor_service_get_introduce1_keys_multi().
|
static |
Helper function: Compute the part of the HS ntor handshake that generates key material for creating and handling INTRODUCE1 cells. Function used by both client and service. Specifically, calculate the following:
info = m_hsexpand | subcredential hs_keys = KDF(intro_secret_hs_input | t_hsenc | info, S_KEY_LEN+MAC_LEN) ENC_KEY = hs_keys[0:S_KEY_LEN] MAC_KEY = hs_keys[S_KEY_LEN:S_KEY_LEN+MAC_KEY_LEN]
where intro_secret_hs_input is secret_input (of size INTRO_SECRET_HS_INPUT_LEN), and subcredential is of size DIGEST256_LEN.
If everything went well, fill hs_ntor_intro_cell_keys_out with the necessary key material, and return 0.
Definition at line 172 of file hs_ntor.c.
Referenced by hs_ntor_service_get_introduce1_keys_multi().
|
static |
Calculate the 'rend_secret_hs_input' element used by the HS ntor handshake and place it in rend_secret_hs_input_out. This function is used by both client and service code.
The computation on the client side is: rend_secret_hs_input = EXP(X,y) | EXP(X,b) | AUTH_KEY | B | X | Y | PROTOID whereas on the service side it is: rend_secret_hs_input = EXP(Y,x) | EXP(B,x) | AUTH_KEY | B | X | Y | PROTOID
where: dh_result1 and dh_result2 carry the two EXP() results (of size CURVE25519_OUTPUT_LEN) intro_auth_pubkey is AUTH_KEY, intro_enc_pubkey is B, client_ephemeral_enc_pubkey is X, and service_ephemeral_rend_pubkey is Y.
|
static |
Helper function: Compute the last part of the HS ntor handshake which derives key material necessary to create and handle RENDEZVOUS1 cells. Function used by both client and service. The actual calculations is as follows:
NTOR_KEY_SEED = MAC(rend_secret_hs_input, t_hsenc) verify = MAC(rend_secret_hs_input, t_hsverify) auth_input = verify | AUTH_KEY | B | Y | X | PROTOID | "Server" auth_input_mac = MAC(auth_input, t_hsmac)
where in the above, AUTH_KEY is intro_auth_pubkey, B is intro_enc_pubkey, Y is service_ephemeral_rend_pubkey, and X is client_ephemeral_enc_pubkey. The provided rend_secret_hs_input is of size REND_SECRET_HS_INPUT_LEN.
The final results of NTOR_KEY_SEED and auth_input_mac are placed in hs_ntor_rend_cell_keys_out. Return 0 if everything went fine.
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 | ||
) |
Given the rendezvous key seed in ntor_key_seed (of size DIGEST256_LEN), do the circuit key expansion as specified by section '4.2.1. Key expansion' and place the keys in keys_out (which must be of size HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN).
Return 0 if things went well, else return -1.
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 | ||
) |
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 | ||
) |