diff options
Diffstat (limited to 'proposals/224-rend-spec-ng.txt')
-rw-r--r-- | proposals/224-rend-spec-ng.txt | 446 |
1 files changed, 384 insertions, 62 deletions
diff --git a/proposals/224-rend-spec-ng.txt b/proposals/224-rend-spec-ng.txt index 680e5bc..4f05638 100644 --- a/proposals/224-rend-spec-ng.txt +++ b/proposals/224-rend-spec-ng.txt @@ -23,6 +23,7 @@ Table of contents: 1.7. In more detail: Keeping crypto keys offline 1.8. In more detail: Encryption Keys And Replay Resistance 1.9. In more detail: A menagerie of keys + 1.9.1. In even more detail: Client authorization [CLIENT-AUTH] 2. Generating and publishing hidden service descriptors [HSDIR] 2.1. Deriving blinded keys and subcredentials [SUBCRED] 2.2. Locating, uploading, and downloading hidden service descriptors @@ -36,9 +37,17 @@ Table of contents: 2.3.1. Client behavior in the absense of shared random values 2.3.2. Hidden services and changing shared random values 2.4. Hidden service descriptors: outer wrapper [DESC-OUTER] - 2.5. Hidden service descriptors: encryption format [ENCRYPTED-DATA] - 2.5.1. Number of introduction points [NUM_INTRO_POINT] - 3. The introduction protocol + 2.5. Hidden service descriptors: encryption format [HS-DESC-ENC] + 2.5.1. First layer of encryption [HS-DESC-FIRST-LAYER] + 2.5.1.1. First layer encryption logic + 2.5.1.2. First layer plaintext format + 2.5.1.3. Client behavior + 2.5.1.4. Obfuscating the number of authorized clients + 2.5.2. Second layer of encryption [HS-DESC-SECOND-LAYER] + 2.5.2.1. Second layer encryption keys + 2.5.2.2. Second layer plaintext format + 2.5.3. Deriving hidden service descriptor encryption keys [HS-DESC-ENCRYPTION-KEYS] + 3. The introduction protocol [INTRO-PROTOCOL] 3.1. Registering an introduction point [REG_INTRO_POINT] 3.1.1. Extensible ESTABLISH_INTRO protocol. [EST_INTRO] 3.1.2. Registering an introduction point on a legacy Tor node [LEGACY_EST_INTRO] @@ -424,34 +433,36 @@ Table of contents: 1.3. In more detail: Access control [IMD:AC] - Access control for a hidden service is imposed at multiple points - through the process above. + Access control for a hidden service is imposed at multiple points through + the process above. Furthermore, there is also the option to impose + additional client authorization access control using pre-shared secrets + exchanged out-of-band between the hidden service and its clients. - 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". + The first stage of access control happens when downloading HS descriptors. + Specifically, 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.) - When the secret is in use, the hidden service gains protections - equivalent to the "stealth mode" in previous designs. + To learn the introduction points, clients must decrypt the body of the + hidden service descriptor. To do so, clients must know the _unblinded_ + public key of the service, which makes the descriptor unuseable by entities + without that knowledge (e.g. HSDirs that don't know the onion address). - To learn the introduction points, the clients must decrypt the body - of the hidden service descriptor. The encryption key for these is - derived from the service's credential. + Also, if optional client authorization is enabled, hidden service + descriptors are superencrypted using each authorized user's identity x25519 + key, to further ensure that unauthorized entities cannot decrypt it. In order to make the introduction point send a rendezvous request to the service, the client needs to use the per-introduction-point authentication key found in the hidden service descriptor. - The final level of access control happens at the server itself, which - may decide to respond or not respond to the client's request - depending on the contents of the request. The protocol is extensible - at this point: at a minimum, the server requires that the client - demonstrate knowledge of the contents of the encrypted portion of the - hidden service descriptor. The service may additionally require a - user- or group-specific access token before it responds to requests. + The final level of access control happens at the server itself, which may + decide to respond or not respond to the client's request depending on the + contents of the request. The protocol is extensible at this point: at a + minimum, the server requires that the client demonstrate knowledge of the + contents of the encrypted portion of the hidden service descriptor. If + optional client authorization is enabled, the service may additionally + require the client to prove knowledge of a pre-shared private key. 1.4. In more detail: Distributing hidden service descriptors. [IMD:DIST] @@ -511,7 +522,7 @@ Table of contents: In order to operate a hidden service, the operator can generate in advance a number of blinded signing keys and descriptor signing - keys (and their credentials; see [DESC-OUTER] and [ENCRYPTED-DATA] + keys (and their credentials; see [DESC-OUTER] and [HS-DESC-ENC] below), and their corresponding descriptor encryption keys, and export those to the hidden service hosts. @@ -597,6 +608,33 @@ Table of contents: part of the Tor circuit extension handshake, used to tie a request to a particular circuit. +1.9.1. In even more detail: Client authorization keys [CLIENT-AUTH] + + When client authorization is enabled, each authorized client of a hidden + service has two more assymetric keypairs which are shared with the hidden + service. An entity without those keys is not able to use the hidden + service. Throughout this document, we assume that these pre-shared keys are + exchanged between the hidden service and its clients in a secure out-of-band + fashion. + + Specifically, each authorized client possesses: + + - An x25519 keypair used to compute decryption keys that allow the client to + decrypt the hidden service descriptor. See [HS-DESC-ENC]. + + - An ed25519 keypair which allows the client to compute signatures which + prove to the hidden service that the client is authorized. These + signatures are inserted into the INTRODUCE1 cell, and without them the + introduction to the hidden service cannot be completed. See [INTRO-AUTH]. + + The right way to exchange these keys is to have the client generate keys and + send the corresponding public keys to the hidden service out-of-band. An + easier but less secure way of doing this exchange would be to have the + hidden service generate the keypairs and pass the corresponding private keys + to its clients. See section [CLIENT-AUTH-MGMT] for more details on how these + keys should be managed. + + [TODO: Also specify stealth client authorization.] 2. Generating and publishing hidden service descriptors [HSDIR] @@ -610,7 +648,7 @@ Table of contents: 2.1. Deriving blinded keys and subcredentials [SUBCRED] - In each time period (see [TIME-PERIOD] for a definition of time + In each time period (see [TIME-PERIODS] for a definition of time 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. @@ -633,12 +671,10 @@ Table of contents: In the above formula, credential corresponds to: - credential = H(public-identity-key | authorization-key) + credential = H("credential" | public-identity-key) where public-identity-key is the public identity master key of the hidden - service, and authorization-key is an optional secret used for client - authorization. If no client authorization is specified, authorization-key is - left blank. + service. 2.2. Locating, uploading, and downloading hidden service descriptors [HASHRING] @@ -932,13 +968,13 @@ Table of contents: prevents an attacker from replacing a newer descriptor signed by a given key with a copy of an older version.) - "encrypted" NL encrypted-string + "superencrypted" NL encrypted-string [Exactly once.] - An encrypted blob, whose format is discussed in [ENCRYPTED-DATA] - below. The blob is base-64 encoded and enclosed in -----BEGIN - MESSAGE---- and ----END MESSAGE---- wrappers. + An encrypted blob, whose format is discussed in [HS-DESC-ENC] below. The + blob is base64 encoded and enclosed in -----BEGIN MESSAGE---- and + ----END MESSAGE---- wrappers. "signature" SP signature NL @@ -950,37 +986,195 @@ Table of contents: the hidden service host does not need to have its private blinded key online. -2.5. Hidden service descriptors: encryption format [ENCRYPTED-DATA] + HSDirs accept hidden service descriptors of up to 50k bytes (a consensus + parameter should also be introduced to control this value). - The encrypted part of the hidden service descriptor is encrypted and - authenticated with symmetric keys generated as follows: +2.5. Hidden service descriptors: encryption format [HS-DESC-ENC] - SALT = 16 bytes from H(random), changes each time we rebuld the - descriptor even if the content of the descriptor hasn't changed. - (So that we don't leak whether the intro point list etc. changed) + Hidden service descriptors are protected by two layers of encryption. + Clients need to decrypt both layers to connect to the hidden service. - secret_input = blinded_public_key | subcredential | - INT_8(revision_counter) - keys = KDF(secret_input, salt, "hsdir-encrypted-data", - S_KEY_LEN + S_IV_LEN + MAC_KEY_LEN) + The first layer of encryption provides confidentiality against entities who + don't know the public key of the hidden service (e.g. HSDirs), while the + second layer of encryption is only useful when client authorization is enabled + and protects against entities that do not possess valid client credentials. - SECRET_KEY = first S_KEY_LEN bytes of keys - SECRET_IV = next S_IV_LEN bytes of keys - MAC_KEY = last MAC_KEY_LEN bytes of keys +2.5.1. First layer of encryption [HS-DESC-FIRST-LAYER] - The encrypted data has the format: + The first layer of HS descriptor encryption is designed to protect + descriptor confidentiality against entities who don't know the blinded + public key of the hidden service. - SALT hashed random bytes from above [16 bytes] - ENCRYPTED The plaintext encrypted with S [variable] - MAC MAC of both above fields [32 bytes] +2.5.1.1. First layer encryption logic + + The encryption keys and format for the first layer of encryption are + generated as specified in [HS-DESC-ENCRYPTION-KEYS] with customization + parameters: + + SECRET_DATA = blinded-public-key + STRING_CONSTANT = "hsdir-superencrypted-data" + + The ciphertext is placed on the "superencrypted" field of the descriptor. + + Before encryption the plaintext is padded with NUL bytes to the nearest + multiple of 10k bytes. + +2.5.1.2. First layer plaintext format + + After clients decrypt the first layer of encryption, they need to parse the + plaintext to get to the second layer ciphertext which is contained in the + "encrypted" field. + + If client auth is enabled, the hidden service generates a fresh + descriptor_cookie key (32 random bytes) and encrypts it using each + authorized client's identity x25519 key. Authorized clients can use the + descriptor cookie to decrypt the second layer of encryption. Our encryption + scheme requires the hidden service to also generate an ephemeral x25519 + keypair for each new descriptor. + + If client auth is disabled, fake data is placed in each of the fields below + to obfuscate whether client authorization is enabled. + + Here are all the supported fields: + + "desc-auth-type" SP type NL + + [Exactly once] + + This field contains the type of authorization used to protect the + descriptor. The only recognized type is "x25519" and specifies the + encryption scheme described in this section. + + If client authorization is disabled, the value here should be "x25519". + + "desc-auth-ephemeral-key" SP key NL + + [Exactly once] + + This field contains an ephemeral x25519 public key generated by the + hidden service and encoded in base64. The key is used by the encryption + scheme below. + + If client authorization is disabled, the value here should be a fresh + x25519 pubkey that will remain unused. + + "auth-client" SP client-id SP iv SP encrypted-cookie + + [Any number] + + When client authorization is enabled, the hidden service inserts an + "auth-client" line for each of its authorized clients. If client + authorization is disabled, the fields here can be populated with random + data of the right size (that's 8 bytes for 'client-id', 16 bytes for 'iv' + and 16 bytes for 'encrypted-cookie' all encoded with base64). + + When client authorization is enabled, each "auth-client" line contains + the descriptor cookie encrypted to each individual client. We assume that + each authorized client possesses a pre-shared x25519 keypair which is + used to decrypt the descriptor cookie. + + We now describe the descriptor cookie encryption scheme. Here are the + relevant keys: + + client_x = private x25519 key of authorized client + client_X = public x25519 key of authorized client + hs_y = private key of ephemeral x25519 keypair of hidden service + hs_Y = public key of ephemeral x25519 keypair of hidden service + descriptor_cookie = descriptor cookie used to encrypt the descriptor + + And here is what the hidden service computes: + + SECRET_SEED = x25519(hs_y, client_X) + KEYS = KDF(SECRET_SEED, 40) + CLIENT-ID = fist 8 bytes of KEYS + COOKIE-KEY = last 32 bytes of KEYS + + Here is a description of the fields in the "auth-client" line: + + - The "client-id" field is CLIENT-ID from above encoded in base64. + + - The "iv" field is 16 random bytes encoded in base64. + + - The "encrypted-cookie" field contains the descriptor cookie ciphertext + as follows and is encoded in base64: + encrypted-cookie = STREAM(iv, COOKIE-KEY) XOR descriptor_cookie + + See section [FIRST-LAYER-CLIENT-BEHAVIOR] for the client-side logic of + how to decrypt the descriptor cookie. + + "encrypted" NL encrypted-string + + [Exactly once] + + An encrypted blob containing the second layer ciphertext, whose format is + discussed in [HS-DESC-SECOND-LAYER] below. The blob is base64 encoded + and enclosed in -----BEGIN MESSAGE---- and ----END MESSAGE---- wrappers. + +2.5.1.3. Client behavior [FIRST-LAYER-CLIENT-BEHAVIOR] + + The goal of clients at this stage is to decrypt the "encrypted" field as + described in [HS-DESC-SECOND-LAYER]. + + If client authorization is enabled, authorized clients need to extract the + descriptor cookie to proceed with decryption of the second layer as + follows: + + An authorized client parsing the first layer of an encrypted descriptor, + extracts the ephemeral key from "desc-auth-ephemeral-key" and calculates + CLIENT-ID and COOKIE-KEY as described in the section above using their + x25519 private key. The client then uses CLIENT-ID to find the right + "auth-client" field which contains the ciphertext of the descriptor + cookie. The client then uses COOKIE-KEY and the iv to decrypt the + descriptor_cookie, which is used to decrypt the second layer of descriptor + encryption as described in [HS-DESC-SECOND-LAYER]. + +2.5.1.4. Hiding client authorization data + + Hidden services should avoid leaking whether client authorization is + enabled or how many authorized clients there are. + + Hence even when client authorization is disabled, the hidden service adds + fake "desc-auth-type", "desc-auth-ephemeral-key" and "auth-client" lines to + the descriptor, as described in [HS-DESC-FIRST-LAYER]. - The encryption format is ENCRYPTED = - STREAM(SECRET_IV,SECRET_KEY) XOR Plaintext + The hidden service also avoids leaking the number of authorized clients by + adding fake "auth-client" entries to its descriptor. Specifically, + descriptors always contain a number of authorized clients that is a + multiple of 16 by adding fake "auth-client" entries if needed. + [XXX consider randomization of the value 16] - Before encryption, the plaintext must be padded to a multiple of 4096 bytes - with NUL bytes. + Clients MUST accept descriptors with any number of "auth-client" lines as + long as the total descriptor size is within the max limit of 50k (also + controlled with a consensus parameter). - The plaintext format is: +2.5.2. Second layer of encryption [HS-DESC-SECOND-LAYER] + + The second layer of descriptor encryption is designed to protect descriptor + confidentiality against unauthorized clients. If client authorization is + enabled, it's encrypted using the descriptor_cookie, and contains needed + information for connecting to the hidden service, like the list of its + introduction points. + + If client authorization is disabled, then the second layer of HS encryption + does not offer any additional security, but is still used. + +2.5.2.1. Second layer encryption keys + + The encryption keys and format for the second layer of encryption are + generated as specified in [HS-DESC-ENCRYPTION-KEYS] with customization + parameters as follows: + + SECRET_DATA = blinded-public-key | descriptor_cookie + STRING_CONSTANT = "hsdir-encrypted-data" + + If client authorization is disabled the 'descriptor_cookie' field is left blank. + + The ciphertext is placed on the "encrypted" field of the descriptor. + +2.5.2.2. Second layer plaintext format + + After decrypting the second layer ciphertext, clients can finally learn the + list of intro points etc. The plaintext has the following format: "create2-formats" SP formats NL @@ -991,14 +1185,14 @@ Table of contents: tor-spec.txt. See tor-spec section 5.1 for a list of recognized handshake types. - "authentication-required" SP types NL + "intro-auth-required" SP types NL [At most once] - A space-separated list of authentication types. A client that does - not support at least one of these authentication types will not be - able to contact the host. Recognized types are: 'password' and - 'ed25519'. See [INTRO-AUTH] below. + A space-separated list of introduction-layer authentication types; see + section [INTRO-AUTH] for more info. A client that does not support at + least one of these authentication types will not be able to contact the + host. Recognized types are: 'password' and 'ed25519'. "single-onion-service" @@ -1069,7 +1263,43 @@ Table of contents: Other encryption and authentication key formats are allowed; clients should ignore ones they do not recognize. -2.5.1. Number of introduction points [NUM_INTRO_POINT] + Clients who manage to extract the introduction points of the hidden service + can prroceed with the introduction protocol as specified in [INTRO-PROTOCOL]. + +2.5.3. Deriving hidden service descriptor encryption keys [HS-DESC-ENCRYPTION-KEYS] + + In this section we present the generic encryption format for hidden service + descriptors. We use the same encryption format in both encryption layers, + hence we introduce two customization parameters SECRET_DATA and + STRING_CONSTANT which vary between the layers. + + The SECRET_DATA parameter specifies the secret data that are used during + encryption key generation, while STRING_CONSTANT is merely a string constant + that is used as part of the KDF. + + Here is the key generation logic: + + SALT = 16 bytes from H(random), changes each time we rebuld the + descriptor even if the content of the descriptor hasn't changed. + (So that we don't leak whether the intro point list etc. changed) + + secret_input = SECRET_DATA | subcredential | INT_8(revision_counter) + + keys = KDF(secret_input | salt | STRING_CONSTANT, S_KEY_LEN + S_IV_LEN + MAC_KEY_LEN) + + SECRET_KEY = first S_KEY_LEN bytes of keys + SECRET_IV = next S_IV_LEN bytes of keys + MAC_KEY = last MAC_KEY_LEN bytes of keys + + The encrypted data has the format: + + SALT hashed random bytes from above [16 bytes] + ENCRYPTED The ciphertext [variable] + MAC MAC of both above fields [32 bytes] + + The final encryption format is ENCRYPTED = STREAM(SECRET_IV,SECRET_KEY) XOR Plaintext + +2.5.4. Number of introduction points [NUM_INTRO_POINT] This section defines how many introduction points an hidden service descriptor can have at minimum, by default and the maximum: @@ -1085,7 +1315,7 @@ Table of contents: HSDirs) but also in order for the descriptor size to not overwhelmed hidden service directories with user defined values that could be gigantic. -3. The introduction protocol +3. The introduction protocol [INTRO-PROTOCOL] The introduction protocol proceeds in three steps. @@ -1858,3 +2088,95 @@ Appendix E. Reserved numbers Note: The value "0A" is skipped because it's reserved for the onion key cross-certifying ntor identity key from proposal 228. + +Appendix F. Managing authorized client data [CLIENT-AUTH-MGMT] + + Hidden services and clients can configure their authorized client data either + using the torrc, or using the control port. This section presents a suggested + scheme for configuring client authorization. + + F.1. Configuring client authorization using torrc + + F.1.1. Hidden Service side + + A hidden service that wants to perform client authorization, adds a new + option HiddenServiceAuthorizeClient to its torrc file: + + HiddenServiceAuthorizeClient auth-type client-name,client-name,... + + The only recognized auth-type value is "basic" which describes the scheme in + section [CLIENT-AUTH]. The rest of the line is a comma-separated list of + human-readable authorized client names. + + Let's consider that one of the listed client names is "alice". In this case, + Tor checks the directory at "DataDirectory/hidden_service/client_auth/" for + any files with filename alice.key or alice.pub . + + Files ending in .key contain private keys for authorized clients, whereas + .pub files contain public keys for authorized clients. In general, authorized + clients should send their public keys to the hidden service operator, and the + operator should place them in the filesystem as .pub files. Only .pub files + are useful to the hidden service, whereas .key files are there only if the + hidden service had to generate its client's keypairs as described below. + + If no alice.key or alice.pub files exist, Tor is tasked with generating + client keys for Alice. To do so, Tor generates x25519 and ed25519 keypairs + for Alice, then makes an alice.key file and writes the private keys inside; + it also makes an alice.pub file and writes the public keys inside. + [XXX what format? it should be convenient so that client can just copy-paste] + + In this case, the hidden service operator has the responsibility to pass the + .key file to Alice in a secure out-of-band way. After the file is passed to + Alice, it can be shredded from the filesystem, as only the public keys are + required for the hidden service to function. + + F.1.2. Client side + + A client who wants to register client authorization data for a hidden service + needs to add the following line to their torrc: + + HidServAuth onion-address x25519-private-key ed25519-private-key + + The keys above are either generated by Alice using a key generation utility, + or they are extracted from a .key file provided by the hidden service. + + In the former case, the client is also tasked with transfering the public + keys to the hidden service in a secure out-of-band way. + + F.2. Configuring client authorization using the control port + + F.2.1. Service side + + A hidden service also has the option to configure authorized clients + using the control port. The idea is that hidden service operators can use + controller utilities that manage their access control instead of using + the filesystem to register client keys. + + Specifically, we require a new control port command ADD_ONION_CLIENT_AUTH + which is able to register x25519/ed25519 public keys tied to a specific + authorized client. + [XXX figure out control port command format] + + Hidden services who use the control port interface for client auth need + to perform their own key management. + + F.2.2. Client side + + There should also be a control port interface for clients to register + authorization data for hidden services without having to use the + torrc. It should allow both generation of client authorization private + keys, and also to import client authorization data provided by a hidden + service + + This way, Tor Browser can present "Generate client auth keys" and "Import + client auth keys" dialogs to users when they try to visit a hidden service + that is protected by client authorization. + + Specifically, we require two new control port commands: + IMPORT_ONION_CLIENT_AUTH_DATA + GENERATE_ONION_CLIENT_AUTH_DATA + which import and generate client authorization data respectively. + + [XXX how does key management work here?] + [XXX what happens when people use both the control port interface and the + filesystem interface?] |