Data Structures | Macros | Functions | Variables
onion_ntor.c File Reference

Implementation for the ntor handshake. More...

#include "orconfig.h"
#include "lib/crypt_ops/crypto_cipher.h"
#include "lib/crypt_ops/crypto_digest.h"
#include "lib/crypt_ops/crypto_hkdf.h"
#include "lib/crypt_ops/crypto_util.h"
#include "lib/ctime/di_ops.h"
#include "lib/log/log.h"
#include "lib/log/util_bug.h"
#include "core/crypto/onion_ntor.h"
#include <string.h>

Go to the source code of this file.

Data Structures

struct  tweakset_t


#define PROTOID   "ntor-curve25519-sha256-1"
#define PROTOID_LEN   24
#define APPEND(ptr, inp, len)
#define SERVER_STR   "Server"
#define SERVER_STR_LEN   6


void ntor_handshake_state_free_ (ntor_handshake_state_t *state)
static void h_tweak (uint8_t *out, const uint8_t *inp, size_t inp_len, const char *tweak)
int onion_skin_ntor_create (const uint8_t *router_id, const curve25519_public_key_t *router_key, ntor_handshake_state_t **handshake_state_out, uint8_t *onion_skin_out)
int onion_skin_ntor_server_handshake (const uint8_t *onion_skin, const di_digest256_map_t *private_keys, const curve25519_keypair_t *junk_keys, const uint8_t *my_node_id, uint8_t *handshake_reply_out, uint8_t *key_out, size_t key_out_len)
int onion_skin_ntor_client_handshake (const ntor_handshake_state_t *handshake_state, const uint8_t *handshake_reply, uint8_t *key_out, size_t key_out_len, const char **msg_out)


static const tweakset_t proto1_tweaks

Detailed Description

Implementation for the ntor handshake.

The ntor circuit-extension handshake was developed as a replacement for the old TAP handshake. It uses Elliptic-curve Diffie-Hellman and a hash function in order to perform a one-way authenticated key exchange. The ntor handshake is meant to replace the old "TAP" handshake.

We instantiate ntor with curve25519, HMAC-SHA256, and HKDF.

This handshake, like the other circuit-extension handshakes, is invoked from onion.c.

Definition in file onion_ntor.c.

Macro Definition Documentation


#define APPEND (   ptr,
memcpy(ptr, (inp), (len)); \
ptr += len; \

Convenience macro: copy len bytes from inp to ptr, and advance ptr by the number of bytes copied.

Definition at line 79 of file onion_ntor.c.



Definition at line 133 of file onion_ntor.c.


CURVE25519_OUTPUT_LEN * 2 + \

Definition at line 130 of file onion_ntor.c.

Function Documentation

◆ h_tweak()

static void h_tweak ( uint8_t *  out,
const uint8_t *  inp,
size_t  inp_len,
const char *  tweak 

Convenience function to represent HMAC_SHA256 as our instantiation of ntor's "tweaked hash'. Hash the inp_len bytes at inp into a DIGEST256_LEN-byte digest at out, with the hash changing depending on the value of tweak.

Definition at line 51 of file onion_ntor.c.

◆ ntor_handshake_state_free_()

void ntor_handshake_state_free_ ( ntor_handshake_state_t state)

Free storage held in an ntor handshake state.

Definition at line 38 of file onion_ntor.c.

◆ onion_skin_ntor_client_handshake()

int onion_skin_ntor_client_handshake ( const ntor_handshake_state_t handshake_state,
const uint8_t *  handshake_reply,
uint8_t *  key_out,
size_t  key_out_len,
const char **  msg_out 

Perform the final client side of the ntor handshake, using the state in handshake_state and the server's NTOR_REPLY_LEN-byte reply in handshake_reply. Generate key_out_len bytes of key material in key_out. Return 0 on success, -1 on failure.

Definition at line 254 of file onion_ntor.c.

◆ onion_skin_ntor_create()

int onion_skin_ntor_create ( const uint8_t *  router_id,
const curve25519_public_key_t router_key,
ntor_handshake_state_t **  handshake_state_out,
uint8_t *  onion_skin_out 

Compute the first client-side step of the ntor handshake for communicating with a server whose DIGEST_LEN-byte server identity is router_id, and whose onion key is router_key. Store the NTOR_ONIONSKIN_LEN-byte message in onion_skin_out, and store the handshake state in *handshake_state_out. Return 0 on success, -1 on failure.

Definition at line 93 of file onion_ntor.c.

◆ onion_skin_ntor_server_handshake()

int onion_skin_ntor_server_handshake ( const uint8_t *  onion_skin,
const di_digest256_map_t private_keys,
const curve25519_keypair_t junk_keys,
const uint8_t *  my_node_id,
uint8_t *  handshake_reply_out,
uint8_t *  key_out,
size_t  key_out_len 

Perform the server side of an ntor handshake. Given an NTOR_ONIONSKIN_LEN-byte message in onion_skin, our own identity fingerprint as my_node_id, and an associative array mapping public onion keys to curve25519_keypair_t in private_keys, attempt to perform the handshake. Use junk_keys if present if the handshake indicates an unrecognized public key. Write an NTOR_REPLY_LEN-byte message to send back to the client into handshake_reply_out, and generate key_out_len bytes of key material in key_out. Return 0 on success, -1 on failure.

Definition at line 149 of file onion_ntor.c.

Variable Documentation

◆ proto1_tweaks

const tweakset_t proto1_tweaks
Initial value:
= {
#define PROTOID
PROTOID ":mac",
PROTOID ":key_extract",
PROTOID ":verify",
PROTOID ":key_expand"

The tweaks to be used with our handshake.

Definition at line 68 of file onion_ntor.c.

Referenced by onion_skin_ntor_client_handshake(), and onion_skin_ntor_server_handshake().

#define CURVE25519_PUBKEY_LEN
Definition: x25519_sizes.h:20
#define DIGEST_LEN
Definition: digest_sizes.h:20
#define DIGEST256_LEN
Definition: digest_sizes.h:23