commit 8df8c0584392240aa8fecbcd2164a4489be7ae1a Author: teor (Tim Wilson-Brown) teor2345@gmail.com Date: Fri Nov 20 12:02:51 2015 +1100
prop224: avoid replicas with the same blinded key
Each replicas uses one of multiple blinded keys (and a different descriptor signing key) to avoid HSDirs being able to locate other replicas of the service.
In combination with the changes to the salt and revision-counter, this also makes it difficult to link descriptors from the same service at all.
If descriptors for different replicas cannot be linked, then it becomes much harder for a malicious HSDir to discover other replicas and attept to DoS them. --- proposals/224-rend-spec-ng.txt | 98 ++++++++++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 34 deletions(-)
diff --git a/proposals/224-rend-spec-ng.txt b/proposals/224-rend-spec-ng.txt index 612ca2c..8dd30b0 100644 --- a/proposals/224-rend-spec-ng.txt +++ b/proposals/224-rend-spec-ng.txt @@ -372,9 +372,10 @@ Status: Draft In order to download a descriptor, clients must know which blinded signing key was used to sign it. (See the next section for more info on key blinding.) This blinded signing key is derived from the - service's public key and, optionally, an additional secret that is - not part of the hidden service's onion address. The public key and - this secret together constitute the service's "credential". + service's public key, the descriptor replica number, and, optionally, + an additional secret that is not part of the hidden service's onion + address. The public key, replica number, and this secret together + constitute the service's "credential".
When the secret is in use, the hidden service gains protections equivalent to the "stealth mode" in previous designs. @@ -414,19 +415,19 @@ Status: Draft positions based on the key that was used to sign them. Note that hidden service descriptors are not signed with the services' public keys directly. Instead, we use a key-blinding system [KEYBLIND] to - create a new key-of-the-day for each hidden service. Any client that - knows the hidden service's credential can derive these blinded - signing keys for a given period. It should be impossible to derive - the blinded signing key lacking that credential. + create new keys-of-the-day for the descriptor replicas for each + hidden service. Any client that knows the hidden service's credential + can derive these blinded signing keys for a given period. It should be + impossible to derive the blinded signing keys lacking that credential.
The body of each descriptor is also encrypted with a key derived from the credential.
To avoid a "thundering herd" problem where every service generates and uploads a new descriptor at the start of each period, each - descriptor comes online at a time during the period that depends on - its blinded signing key. The keys for the last period remain valid - until the new keys come online. + descriptor replica comes online at a time during the period that + depends on its blinded signing key. The keys for the last period remain + valid until the new keys come online.
1.5. In more detail: Scaling to multiple hosts
@@ -483,9 +484,9 @@ Status: Draft in advance). [TODO: Define revocation mechanism?]
- It's important to not send the private part of the blinded signing + It's important to not send the private part of a blinded signing key to the Hidden Service since an attacker can derive from it the - secret master identity key. The secret blinded signing key should + secret master identity key. A secret blinded signing key should only be used to create credentials for the descriptor signing keys.
1.8. In more detail: Encryption Keys And Replay Resistance @@ -518,14 +519,16 @@ Status: Draft service's public identity key and an optional secret can derive the public blinded identity key for a service. This key is used as an index in the DHT-like structure of the directory system - (see [SUBCRED]). + (see [SUBCRED]). Each descriptor replica may use a different + blinded signing key, based on its replicanum.
Descriptor signing key -- A key used to sign hidden service descriptors. This is signed by blinded signing keys. Unlike blinded signing keys and master identity keys, the secret part of this key must be stored online by hidden service hosts. The public part of this key is included in the unencrypted section - of HS descriptors (see [DESC-OUTER]). + of HS descriptors (see [DESC-OUTER]). Each descriptor replica must + use a different descriptor signing key.
Introduction point authentication key -- A short-term signing keypair used to identify a hidden service to a given @@ -546,7 +549,8 @@ Status: Draft
Descriptor encryption keys -- A symmetric encryption key used to encrypt the body of hidden service descriptors. Derived from the - current period and the hidden service credential. + current period, the descriptor replica, the descriptor revision, + and the hidden service credential.
Public/private keypairs defined elsewhere:
@@ -577,6 +581,8 @@ Status: Draft periods), a hidden service host uses a different blinded private key to sign its directory information, and clients use a different blinded public key as the index for fetching that information. + Each descriptor replica for each service may use different blinded + keys.
For a candidate for a key derivation method, see Appendix [KEYBLIND].
@@ -593,7 +599,13 @@ Status: Draft The subcredential for a period is derived as: H("subcredential" | credential | - blinded-public-key). + blinded-public-key(replica-keynum)). + + Where replica-keynum = replicanum % hsdir_num_replica_keys. + (This ensures that each replica has a blinded key, even if + hsdir_num_replicas is higher than hsdir_num_replica_keys. This ensures + hidden services can't predict future values of hsdir_num_replicas at + key blinding time.)
2.2. Locating, uploading, and downloading hidden service descriptors [HASHRING] @@ -601,7 +613,9 @@ Status: Draft To avoid attacks where a hidden service's descriptor is easily targeted for censorship, we store them at different directories over time, and use shared random values to prevent those directories from - being predictable far in advance. + being predictable far in advance. Each descriptor replica may use a + different blinded signing key, which prevents directories in one + replica locating directories in other replica(s).
Which Tor servers hosts a hidden service depends on:
@@ -662,7 +676,8 @@ Status: Draft The time at which a key from the next interval becomes valid is determined by taking the first two bytes of
- OFFSET = H("interval-offset" | Key | INT_8(Next_Period_Num)) + OFFSET = H("interval-offset" | blinded-public-key(replica-keynum) | + INT_8(Next_Period_Num))
as a big-endian integer, dividing by 65536, and treating that as a fraction of the overlap interval. @@ -683,11 +698,21 @@ Status: Draft
2.2.3. Where to publish a service descriptor
+ The following constant controls how many blinded keys are created + per period for the different descriptor replicas: + + hsdir_num_replica_keys = an integer constant 2. + + (Since blinded keys can be generated ahead of time, a service can not + know the value of hsdir_n_replicas at the time the blinded keys will + be used. If hsdir_n_replicas is greater than hsdir_num_replica_keys, + some keys will be used for multiple replicas.) + The following consensus parameters control where a hidden service descriptor is stored;
hsdir_n_replicas = an integer in range [1,16] - with default value 2. + with default value hsdir_num_replica_keys.
hsdir_spread_fetch = an integer in range [1,128] with default value 3. @@ -699,12 +724,12 @@ Status: Draft with default value 12.
To determine where a given hidden service descriptor will be stored - in a given period, after the blinded public key for that period is - derived, the uploading or downloading party calculate + in a given period, after the blinded public key for that period and + replica is derived, the uploading or downloading party calculates:
for replicanum in 1...hsdir_n_replicas: hs_index(replicanum) = H("store-at-idx" | - blinded_public_key | + blinded_public_key(replica-keynum) | INT_8(replicanum) | INT_8(periodnum) )
@@ -712,7 +737,8 @@ Status: Draft periodnum is defined in section TIME-PERIODS.
where n_replicas is determined by the consensus parameter - "hsdir_n_replicas". + "hsdir_n_replicas", and replica-keynum is replicanum % + hsdir_num_replica_keys.
Then, for each node listed in the current consensus with the HSDir3 flag, we compute a directory index for that node as: @@ -761,7 +787,7 @@ Status: Draft /tor/rendezvous3/publish relative to the hidden service directory's root, and downloaded with an HTTP GET request for the URL /tor/rendezvous3/<z> where z is a base-64 encoding of the hidden - service's blinded public key. + service's blinded public key for the replica.
[TODO: raw base64 is not super-nice for URLs, since it can have slashes. We already use it for microdescriptor URLs, though. Do we @@ -819,8 +845,9 @@ Status: Draft
The 'certificate' field contains a certificate in the format from proposal 220, with the short-term ed25519 descriptor-signing key - signed by the blinded public key. It must contain a - ed25519-signing-key extension containing the blinded public key. + for the replica, signed by the blinded public key for the replica. + It must contain a ed25519-signing-key extension containing the + blinded public key for the replica.
"time-period" SP YYYY-MM-DD HH:MM:SS NUM NL
@@ -911,7 +938,7 @@ Status: Draft A signature of all previous fields, using the signing key in the hs-descriptor line. We use a separate key for signing, so that the hidden service host does not need to have its private blinded - key online. + keys online.
2.5. Hidden service descriptors: encryption format [ENCRYPTED-DATA] @@ -926,8 +953,8 @@ Status: Draft
[ XX/teor - is the extra load on the HSDirs worth it? ]
- secret_input = blinded_public_key | subcredential | - INT_4(revision_counter) + secret_input = blinded_public_key(replica-keynum) | + subcredential | INT_4(revision_counter) keys = KDF(secret_input, salt, "hsdir-encrypted-data", S_KEY_LEN + S_IV_LEN + MAC_KEY_LEN)
@@ -990,9 +1017,10 @@ Status: Draft
Base-64 encoded introduction point authentication key that was used to establish introduction point circuit, cross-certifying - the blinded public key. This uses the certificate format of - proposal 220 with type [09]. The signing-key extension is - mandatory here to tell you what the public key is. + the blinded public key for the replica. This uses the + certificate format of proposal 220 with type [09]. The + signing-key extension is mandatory here to tell you what the + public key is.
"enc-key" SP "ntor" SP key NL
@@ -1784,8 +1812,10 @@ Appendix A. Signature scheme with key blinding [KEYBLIND] possible alternatives. Also, see [KEYBLIND-PROOF] for a security proof of this scheme.
- (To use this with Tor, set N = "key-blind" | INT_8(period-number) | - INT_8(Start of period in seconds since epoch).) + (To use this with Tor, set N(replica-keynum) = "key-blind" | + INT_8(period-number) | INT_8(Start of period in seconds since epoch) | + INT_1(replica-keynum), where replica-keynum is from 1 to + hsdir_num_replica_keys.)
Appendix B. Selecting nodes [PICKNODES]
tor-commits@lists.torproject.org