Tor 0.4.9.1-alpha-dev
|
Implements the version 3 ntor handshake as first specified in proposal 332. More...
#include "orconfig.h"
#include "core/crypto/onion_ntor_v3.h"
#include "lib/arch/bytes.h"
#include "lib/crypt_ops/crypto_digest.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
#include "lib/ctime/di_ops.h"
#include "lib/log/util_bug.h"
#include <string.h>
Go to the source code of this file.
Macros | |
#define | ONION_NTOR_V3_PRIVATE |
#define | PROTOID "ntor3-curve25519-sha3_256-1" |
#define | TWEAK(A) (PROTOID ":" A) |
#define | T_MSGKDF TWEAK("kdf_phase1") |
#define | T_MSGMAC TWEAK("msg_mac") |
#define | T_KEY_SEED TWEAK("key_seed") |
#define | T_VERIFY TWEAK("verify") |
#define | T_FINAL TWEAK("kdf_final") |
#define | T_AUTH TWEAK("auth_final") |
#define | xof_add(xof, data, len) crypto_xof_add_bytes((xof), (data), (len)) |
#define | xof_add_tweak(d, s) xof_add_encap((d), (const uint8_t *)(s), strlen(s)) |
#define | d_add_tweak(d, s) d_add_encap((d), (const uint8_t *)(s), strlen(s)) |
#define | ADD2(s, len) |
#define | ADD2_ENCAP(s, len) |
Functions | |
static void | xof_add_encap (crypto_xof_t *xof, const uint8_t *data, size_t len) |
static void | d_add (crypto_digest_t *digest, const uint8_t *data, size_t len) |
static void | d_add_encap (crypto_digest_t *digest, const uint8_t *data, size_t len) |
static void | push (uint8_t **ptr, const uint8_t *endptr, const uint8_t *data, size_t len) |
void | ntor3_handshake_state_free_ (ntor3_handshake_state_t *state) |
int | onion_skin_ntor3_create (const ed25519_public_key_t *relay_id, const curve25519_public_key_t *relay_key, const uint8_t *verification, const size_t verification_len, const uint8_t *message, const size_t message_len, ntor3_handshake_state_t **handshake_state_out, uint8_t **onion_skin_out, size_t *onion_skin_len_out) |
STATIC int | onion_skin_ntor3_create_nokeygen (const curve25519_keypair_t *client_keypair, const ed25519_public_key_t *relay_id, const curve25519_public_key_t *relay_key, const uint8_t *verification, const size_t verification_len, const uint8_t *message, const size_t message_len, ntor3_handshake_state_t **handshake_state_out, uint8_t **onion_skin_out, size_t *onion_skin_len_out) |
int | onion_ntor3_client_handshake (const ntor3_handshake_state_t *handshake_state, const uint8_t *handshake_reply, size_t reply_len, const uint8_t *verification, size_t verification_len, uint8_t *keys_out, size_t keys_out_len, uint8_t **message_out, size_t *message_len_out) |
void | ntor3_server_handshake_state_free_ (ntor3_server_handshake_state_t *state) |
int | onion_skin_ntor3_server_handshake_part1 (const di_digest256_map_t *private_keys, const curve25519_keypair_t *junk_key, const ed25519_public_key_t *my_id, const uint8_t *client_handshake, size_t client_handshake_len, const uint8_t *verification, size_t verification_len, uint8_t **client_message_out, size_t *client_message_len_out, ntor3_server_handshake_state_t **state_out) |
int | onion_skin_ntor3_server_handshake_part2 (const ntor3_server_handshake_state_t *state, const uint8_t *verification, size_t verification_len, const uint8_t *server_message, size_t server_message_len, uint8_t **handshake_out, size_t *handshake_len_out, uint8_t *keys_out, size_t keys_out_len) |
STATIC int | onion_skin_ntor3_server_handshake_part2_nokeygen (const curve25519_keypair_t *relay_keypair_y, const ntor3_server_handshake_state_t *state, const uint8_t *verification, size_t verification_len, const uint8_t *server_message, size_t server_message_len, uint8_t **handshake_out, size_t *handshake_len_out, uint8_t *keys_out, size_t keys_out_len) |
Implements the version 3 ntor handshake as first specified in proposal 332.
The v3 ntor handshake differs from the earlier versions (ntor and hs-ntor) primarily in that it allows the client to send an authenticated encrypted message as part of its onion skin, and allows the relay to send and encrypted authenticated reply as part of its response.
It also takes a "verification string" – the handshake cannot succeed unless both parties use the same value for their verification stream.
Definition in file onion_ntor_v3.c.
#define ADD2 | ( | s, | |
len | |||
) |
#define ADD2_ENCAP | ( | s, | |
len | |||
) |
#define d_add_tweak | ( | d, | |
s | |||
) | d_add_encap((d), (const uint8_t *)(s), strlen(s)) |
Add an encapsulated tweak to the provided digest.
Definition at line 97 of file onion_ntor_v3.c.
#define ONION_NTOR_V3_PRIVATE |
Definition at line 21 of file onion_ntor_v3.c.
#define PROTOID "ntor3-curve25519-sha3_256-1" |
Definition at line 37 of file onion_ntor_v3.c.
#define T_AUTH TWEAK("auth_final") |
Definition at line 45 of file onion_ntor_v3.c.
#define T_FINAL TWEAK("kdf_final") |
Definition at line 44 of file onion_ntor_v3.c.
#define T_KEY_SEED TWEAK("key_seed") |
Definition at line 42 of file onion_ntor_v3.c.
#define T_MSGKDF TWEAK("kdf_phase1") |
Definition at line 40 of file onion_ntor_v3.c.
#define T_MSGMAC TWEAK("msg_mac") |
Definition at line 41 of file onion_ntor_v3.c.
#define T_VERIFY TWEAK("verify") |
Definition at line 43 of file onion_ntor_v3.c.
#define TWEAK | ( | A | ) | (PROTOID ":" A) |
Definition at line 38 of file onion_ntor_v3.c.
#define xof_add | ( | xof, | |
data, | |||
len | |||
) | crypto_xof_add_bytes((xof), (data), (len)) |
Add len bytes of data as input to the provided xof.
(This is provided just for abbreviation).
Definition at line 52 of file onion_ntor_v3.c.
#define xof_add_tweak | ( | d, | |
s | |||
) | xof_add_encap((d), (const uint8_t *)(s), strlen(s)) |
Add an encapsulated tweak to the provided xof.
Definition at line 69 of file onion_ntor_v3.c.
|
static |
Add len bytes of data to the provided digest.
This is provided as an abbreviation, and to get the types right.
Definition at line 77 of file onion_ntor_v3.c.
Referenced by d_add_encap().
|
static |
Add len bytes of data to the provided digest, prefixed with the encoded length.
This is equivalent to ENCAP(data) from the spec.
Definition at line 88 of file onion_ntor_v3.c.
void ntor3_handshake_state_free_ | ( | ntor3_handshake_state_t * | state | ) |
Helper: Drop storage held by state, after wiping it.
Definition at line 118 of file onion_ntor_v3.c.
void ntor3_server_handshake_state_free_ | ( | ntor3_server_handshake_state_t * | state | ) |
Wipe a server handshake state, and release the storage it holds.
Definition at line 434 of file onion_ntor_v3.c.
int onion_ntor3_client_handshake | ( | const ntor3_handshake_state_t * | handshake_state, |
const uint8_t * | handshake_reply, | ||
size_t | reply_len, | ||
const uint8_t * | verification, | ||
size_t | verification_len, | ||
uint8_t * | keys_out, | ||
size_t | keys_out_len, | ||
uint8_t ** | message_out, | ||
size_t * | message_len_out | ||
) |
Complete a client-side v3 ntor handshake.
Takes a handshake_state returned earlier by onion_skin_ntor3_create()
, and the relay's reply to that handshake (reply_len bytes at handshake_reply). Also takes a verification string (verification_len bytes at verification).
Returns 0 on success and -1 on failure. On success, generates key_len bytes of key material into the provided keys_out buffer, and sets message_out to the message that the relay sent in reply to our message (and sets message_out_len to that message's length).
Definition at line 298 of file onion_ntor_v3.c.
int onion_skin_ntor3_create | ( | const ed25519_public_key_t * | relay_id, |
const curve25519_public_key_t * | relay_key, | ||
const uint8_t * | verification, | ||
const size_t | verification_len, | ||
const uint8_t * | message, | ||
const size_t | message_len, | ||
ntor3_handshake_state_t ** | handshake_state_out, | ||
uint8_t ** | onion_skin_out, | ||
size_t * | onion_skin_len_out | ||
) |
Perform a client-side v3 ntor handshake with a given relay.
As inputs this function takes the relay's Ed25519 identity (relay_id), the relay's current ntor onion key (relay_key), a verification string (verification_len bytes at verification), and a message to send as part of the handshake (message_len bytes at message).
The message will be encrypted and authenticated to the relay, but will not receive the same forward secrecy as the rest of the handshake. We should not put any super-confidential data in it.
The handshake will only succeed if the relay uses the same verification string as we are using.
As outputs, this function returns 0 on success and -1 on failure. On success, it sets onion_skin_out and onion_skin_len_out to a newly allocated handshake message that the client can send as part of its CREATE2 or EXTEND2 cell. It also sets it sets handshake_state_out to a newly allocated handshake state object; the client needs to use this object to process the relay's eventual reply.
Definition at line 150 of file onion_ntor_v3.c.
STATIC int onion_skin_ntor3_create_nokeygen | ( | const curve25519_keypair_t * | client_keypair, |
const ed25519_public_key_t * | relay_id, | ||
const curve25519_public_key_t * | relay_key, | ||
const uint8_t * | verification, | ||
const size_t | verification_len, | ||
const uint8_t * | message, | ||
const size_t | message_len, | ||
ntor3_handshake_state_t ** | handshake_state_out, | ||
uint8_t ** | onion_skin_out, | ||
size_t * | onion_skin_len_out | ||
) |
Like onion_skin_ntor3_create, but do not generate a new ephemeral keypair. Instead, take the ephemeral keypair (x,X) from client_keypair.
(Having a separate function for this lets us test the code for correct behavior.)
Definition at line 187 of file onion_ntor_v3.c.
Referenced by onion_skin_ntor3_create().
int onion_skin_ntor3_server_handshake_part1 | ( | const di_digest256_map_t * | private_keys, |
const curve25519_keypair_t * | junk_key, | ||
const ed25519_public_key_t * | my_id, | ||
const uint8_t * | client_handshake, | ||
size_t | client_handshake_len, | ||
const uint8_t * | verification, | ||
size_t | verification_len, | ||
uint8_t ** | client_message_out, | ||
size_t * | client_message_len_out, | ||
ntor3_server_handshake_state_t ** | state_out | ||
) |
As a relay, start handling a client's v3 ntor handshake.
This function performs the first half of the handshake, up to the point where the client's message is decoded. After calling it, the relay should decide how and whether to reply to the client's message, compose its reply, and call onion_skin_ntor3_server_handshake_part2
.
It takes as input a map of the relay's known onion keys in private_keys, along with a fake junk_key to use if there is a complete mismatch. It takes the relay's ed25519 identity in my_id, along with the client's handshake message (client_handshake_len bytes in client_handshake), and a verification string (verification_len bytes in verification).
Return 0 on success, and -1 on failure. On success, sets client_message_out to a newly allocated string holding the plaintext of the message that the client sent as part of its handshake, and client_message_out_len to its length. Also sets state_out to a newly allocated state object holding the intermediate computation for this handshake.
Definition at line 465 of file onion_ntor_v3.c.
int onion_skin_ntor3_server_handshake_part2 | ( | const ntor3_server_handshake_state_t * | state, |
const uint8_t * | verification, | ||
size_t | verification_len, | ||
const uint8_t * | server_message, | ||
size_t | server_message_len, | ||
uint8_t ** | handshake_out, | ||
size_t * | handshake_len_out, | ||
uint8_t * | keys_out, | ||
size_t | keys_out_len | ||
) |
Finish the relay side of an ntor v3 handshake.
The relay calls this function after it has decided to respond to the client's original encrypted message. This function receives the relay's message in server_message and its length in server_message_len, and completes the handshake.
Returns 0 on success and -1 on failure. On success, stores the newly allocated handshake for the relay to send in handshake_out, and its length in handshake_len_out. Stores keys_out_len bytes of generated keys in the provided buffer at keys_out.
Definition at line 612 of file onion_ntor_v3.c.
STATIC int onion_skin_ntor3_server_handshake_part2_nokeygen | ( | const curve25519_keypair_t * | relay_keypair_y, |
const ntor3_server_handshake_state_t * | state, | ||
const uint8_t * | verification, | ||
size_t | verification_len, | ||
const uint8_t * | server_message, | ||
size_t | server_message_len, | ||
uint8_t ** | handshake_out, | ||
size_t * | handshake_len_out, | ||
uint8_t * | keys_out, | ||
size_t | keys_out_len | ||
) |
Like onion_skin_ntor3_server_handshake_part2
, but do not generate an ephemeral (y,Y) keypair.
Instead, this function takes that keypair as relay_keypair_y.
(Having a separate function for this lets us test the code for correct behavior.)
Definition at line 652 of file onion_ntor_v3.c.
Referenced by onion_skin_ntor3_server_handshake_part2().
|
static |
Helper: copy len bytes of data onto *ptr, and advance ptr forward by len bytes.
Asserts that ptr will not be advanced beyond endptr.
Definition at line 106 of file onion_ntor_v3.c.
|
static |
Add len bytes of data as input to the provided xof, prefixed with an encoding of the length.
This is equivalent to ENCAP(data) in the spec.
Definition at line 60 of file onion_ntor_v3.c.