[tor-dev] Safe Alternative Uses of Onion Service Keys

Matthew Finkel sysrqb at torproject.org
Wed Jul 29 05:15:09 UTC 2020


Hello everyone,

Onion service version two (v2) key pairs were used for more purposes
than simply facilitating the establishment of rendezvous circuits, in
particular third-party applications used this key in numerous ways.
Similarly, version three (v3) onion service keys are being re-used in
similar (and new) ways. However, the (re)use of v3 long-term keys is not
obviously safe in all situations. How should (and should not) these
keys be used, such that the security of the onion service is preserved?

I'll briefly summarize v3 keys (for those who don't want to read through
the spec), and then I'll sketch two alternative use cases along with a
straw man proposal. The long-term v3 identity keys are ed25519 keys (see
[0] for a nice write up of ed25519, in general). The generated key
material is serialized externally (outside of tor) in two (similar)
formats: written on-disk [2] and from the control port [3].

The secret (private) key is the (64-byte) SHA-512 digest of a 32-byte
seed value. The 64-byte digest is the "expanded form". The seed is
thrown away. The public key is obtained by taking the first 32 bytes of
that SHA-512 hash, clamping some of the bits, and performing a scalar
multiplication with the (fixed) base point. This key is the onion
service long-term identity key.

Creating and verifying a signature using the above keys (respectively)
follow standard EdDSA. However, (at this time) Tor does not use these
keys directly for signing messages. All messages are signed using an
ephemeral ed25519 key, and that ephemeral key is certified by a blinded
ed25519 key derived from the long-term key pair. The blinded keys are
computed using a specified blinding scheme [4]. All messages signed
using the ephemeral key are prefixed with a context-specific string. In
summary, long-term keys are used for deriving a short-term blinded key,
and that short-term blinded key is used for certifying an ephemeral
signing key.

For computing the blinded key, the first 32 bytes of the long-term
secret key (LH) are multiplied with a blinding factor (h*a mod l), see
the specification for the value of **h** [4]. This becomes LH'
(LH-prime). The second 32 bytes of the secret key (RH) are concatenated
with a string prefix and then the SHA3-256 digest is computed of the
concatenated string. The first 32 bytes of the resulting digest become
RH' (RH-prime). LH' and RH' are used as regular ed25519 secret keys for
signing and verifying messages following EdDSA.

Tor's EdDSA signature is "R|S", R concatenated with S (the message is
not included in the signature).

The safest usage of the long-term keys for alternative purposes I see
appears to be by deriving a (fixed/deterministic) blinded key pair using
the same scheme that Tor uses, and signing/verification simply follow
the same process as Tor, except the derived keys need not rotate
periodically (is this true?). The derived key should be used for
certifying a freshly generated ed25519 key, which is used in the
application protocol. For example, if I want to use a key for code
signing such that it is bound to my onion service key, then I could
derive a certifying key by following Tor's derivation scheme, by
substituting:

  BLIND_STRING = "Derive temporary signing key" | INT_1(0)
  N = "key-blind" | INT_8(period-number) | INT_8(period_length)

with

  BLIND_STRING = "Derive code signing key" | INT_1(0)
  N = "code-sigining-key-blind" | "v0" | "YYYY-MM-DD" |  INT_8(validity_period)

for computing the blinding factor. Where "v0" is a version tag.
YYYY-MM-DD is an arbitrary date, but it can be used for rotating signing
keys in the future. INT_8(validity_period) may be used for specifying
the number of days after YYYY-MM-DD at which time previously unverified
signatures using this key should be considered invalid (where INT_8(0)
could indicate "never expire").

And substituting

  RH_BLIND_STRING = "Derive temporary signing key hash input"

with

  RH_BLIND_STRING = "Derive code signing key hash input"

for computing RH'.

A signature must include "v0" and the values used in "YYYY-MM-DD" and
INT_8(validity_period), such that the client can derive the correct
blinded public key for verification when starting from the long-term
identity key. The signature should be over a certification of an
independently generated ed25519 key pair. This new key pair (along with
the certification) can be used for providing message integrity within
the application's protocol. If, instead, the derived key is used
directly for signing, and the application needs the keys online for
signing messages, then this risks the security of the long-term key, as
well. The blinding scheme allows for (partially) recovering the
long-term secret key from the derived secret key.

Another example use case comes from Jeremy Rand where the onion service
key is used in a root CA certificate, and a leaf certificate (signed by
the CA cert) is used by the application.

Following from the previous example, (most likely) the CA certificate
should not be signed directly using the onion service's long-term secret
key. However, a derived key could be used in the CA certificate and the
leaf cert could contain an ephemeral key (in exactly the same way that
tor certifies ephemeral keys using the derived blinded signing key).
This idea appears to be a concrete design of how the above (abstract)
key certification could be implemented, and it could be a format that
tor natively supports.

The above process seems like a lot to ask from application developers.
Can we make it easier for them?

Open questions:

 1) Going back to the long-term secret key, can LH and RH be used
    directly in EdDSA without reducing the security and unlinkability of
    the blinded keys?

 2) Should other use cases of the long-term keys only derive distinct
    (blinded) keys, instead of using the long-term keys directly?

 3) If other use cases should only use derived keys, then is there an
    alternative derivation scheme for when unlinkability between derived
    keys is not needed (without reducing the security properties of the
    onion service blinded keys), and is allowing linkability
    useful/worthwhile?

 4) Is the above example derivation scheme safe if different
    applications tweak the above prefix strings in similar ways?

 5) Should Tor simply derive one blinded key that can be used by all
    alternative applications? Is that safe?

I'd like to thank Nick Mathewson and David Goulet for their comments on
an earlier version of this mail.

Thanks,
Matt


[0] https://blog.mozilla.org/warner/2011/11/29/ed25519-keys/
[1] https://gitweb.torproject.org/torspec.git/tree/rend-spec-v3.txt#n2267
[2] A tagged value: "== ed25519v1-secret: type0 =="\0\0\0 | (64-byte
SHA-512 hash of the seed)
[3] https://gitweb.torproject.org/torspec.git/tree/control-spec.txt#n1746
[4] https://gitweb.torproject.org/torspec.git/tree/rend-spec-v3.txt#n2267


More information about the tor-dev mailing list