onion_tap.c File Reference
#include "core/or/or.h"
#include "app/config/config.h"
#include "lib/crypt_ops/crypto_dh.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
#include "core/crypto/onion_tap.h"
#include "feature/stats/rephist.h"

Go to the source code of this file.


int onion_skin_TAP_create (crypto_pk_t *dest_router_key, crypto_dh_t **handshake_state_out, char *onion_skin_out)
int onion_skin_TAP_server_handshake (const char *onion_skin, crypto_pk_t *private_key, crypto_pk_t *prev_private_key, char *handshake_reply_out, char *key_out, size_t key_out_len)
int onion_skin_TAP_client_handshake (crypto_dh_t *handshake_state, const char *handshake_reply, char *key_out, size_t key_out_len, const char **msg_out)

Detailed Description

Functions to implement the original Tor circuit extension handshake (a.k.a TAP).

The "TAP" handshake is the first one that was widely used in Tor: It combines RSA1024-OAEP and AES128-CTR to perform a hybrid encryption over the first message DH1024 key exchange. (The RSA-encrypted part of the encryption is authenticated; the AES-encrypted part isn't. This was not a smart choice.)

We didn't call it "TAP" ourselves – Ian Goldberg named it in "On the Security of the Tor Authentication Protocol". (Spoiler: it's secure, but its security is kind of fragile and implementation dependent. Never modify this implementation without reading and understanding that paper at least.)

We have deprecated TAP since the ntor handshake came into general use. It is still used for hidden service IP and RP connections, however.

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

Definition in file onion_tap.c.

Function Documentation

◆ onion_skin_TAP_client_handshake()

int onion_skin_TAP_client_handshake ( crypto_dh_t handshake_state,
const char *  handshake_reply,
char *  key_out,
size_t  key_out_len,
const char **  msg_out 

Finish the client side of the DH handshake. Given the 128 byte DH reply + 20 byte hash as generated by onion_skin_server_handshake and the handshake state generated by onion_skin_create, verify H(K) with the first 20 bytes of shared key material, then generate key_out_len more bytes of shared key material and store them in key_out.

After the invocation, call crypto_dh_free on handshake_state.

Definition at line 207 of file onion_tap.c.

References crypto_dh_get_bytes(), DH1024_KEY_LEN, DIGEST_LEN, and tor_assert().

◆ onion_skin_TAP_create()

int onion_skin_TAP_create ( crypto_pk_t dest_router_key,
crypto_dh_t **  handshake_state_out,
char *  onion_skin_out 

Given a router's 128 byte public key, stores the following in onion_skin_out:

  • [42 bytes] OAEP padding
  • [16 bytes] Symmetric key for encrypting blob past RSA
  • [70 bytes] g^x part 1 (inside the RSA)
  • [58 bytes] g^x part 2 (symmetrically encrypted)

Stores the DH private key into handshake_state_out for later completion of the handshake.

The meeting point/cookies and auth are zeroed out for now.

Definition at line 53 of file onion_tap.c.

References DH1024_KEY_LEN, and tor_assert().

◆ onion_skin_TAP_server_handshake()

int onion_skin_TAP_server_handshake ( const char *  onion_skin,
crypto_pk_t private_key,
crypto_pk_t prev_private_key,
char *  handshake_reply_out,
char *  key_out,
size_t  key_out_len 

Given an encrypted DH public key as generated by onion_skin_create, and the private key for this onion router, generate the reply (128-byte DH plus the first 20 bytes of shared key material), and store the next key_out_len bytes of key material in key_out.

Definition at line 105 of file onion_tap.c.