Filename: 357-circ-key-exporters.md
Title: Circuit key exporters: A better way to use KH
Author: Nick Mathewson
Created: 27 March 2025
Status: Open

Introduction

Note: This proposal does not call for an immediate change in the Tor protocols. Rather, it describes a convention we should use for per-circuit key exporters in the future.

In the current Tor protocols, we derive a shared secret (called "KH" here and in the specs) as part of our circuit extension handshakes. This "KH" value is used for a single purpose:

As part of the hidden service introduction protocol, to prevent an attacker from replaying an ESTABLISH_INTRO message.

However, its character and usage are ad-hoc. If we want to use it anywhere else, we will risk exposing ourselves to cross-protocol attacks.

Here we specify a new convention for circuit binding. This convention should be used for any new cases where we need a shared secret shared by the client and a given hop on a circuit.

Also, if we ever define a new handshake to use in ESTABLISH_INTRO we should use this convention in place of our current use of KH.

Proposal

As part of our handshake, we should derive a KH value, now called a "circuit binding seed". For future handshakes, KH values should be 32 bytes long.

To derive an exported secret from KH, we will use cSHAKE128, with these parameters:

  • X (main input string) set to KH
  • N (function name) set to ""
  • S (customization string) as a customization string starting with "Tor:"
  • L (the output length) as desired.

We denote this exported secret as:

  CircExporter(Circuit[Hop], Custom, Len)
    = cSHAKE128(X=Circuit[Hop].KH, L=Len, N="", C=Custom)

Registry

We will add a registry of customization strings in our discussion of key derivation where we explain how KH is derived and used.

The only registered string for now is "Tor:ESTABLISH_INTRO MAC".

Migration

The hidden service introduction protocol is currently defined to use KH as-is as a MAC key in ESTABLISH_INTRO messages.

When we next define a new version of the introduction protocol, or when we next define a new circuit handshake, we will redefine the introduction protocol to use CircExporter(Circuit[Hop], "Tor:ESTABLISH_INTRO MAC", 32) as its MAC key.

In the mean time, it is probably not too bad to use raw KH as a MAC key for ESTABLISH_INTRO messages along with its new usage: cSHAKE128 is designed to avoid accidental hash collisions with SHA3-256.

Historical note

In the obsolete "TAP" format, the KH field was sent in the clear as part of the CREATED cell. This is not the case in the ntor handshake and beyond.