From c6d10a93489e817efd48498dc9cb2f03480d052b Mon Sep 17 00:00:00 2001 From: David Goulet Date: Wed, 11 Jan 2023 10:14:19 -0500 Subject: prop340: Move stream_id to body becoming a per command value Signed-off-by: David Goulet --- proposals/340-packed-and-fragmented.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/proposals/340-packed-and-fragmented.md b/proposals/340-packed-and-fragmented.md index e7f08f4..0d83f67 100644 --- a/proposals/340-packed-and-fragmented.md +++ b/proposals/340-packed-and-fragmented.md @@ -66,12 +66,16 @@ Relay _messages_ now follow the following format: Header command u8 length u16 - stream_id u16 Body data u8[length] We require that "command" is never 0. +One big change from the current tor protocol is the missing `stream_id` which +we propose to move into the body because most commands set it to 0 because +they don't need it. Meaning that the `stream_id` becomes a value specified +per-command. + Messages can be split across relay cells; multiple messages can occur in a single relay cell. We enforce the following rules: @@ -191,8 +195,8 @@ cell. Here it is a BEGIN message. message header: command BEGIN [1 byte] length 23 [2 bytes] - stream_id (...) [2 bytes] message body + stream_id (...) [2 bytes] "www.torproject.org:443\0" [23 bytes] end-of-messages marker 0 [1 byte] @@ -215,8 +219,8 @@ across two relay cells. message header: command EXTEND [1 byte] length 800 [2 bytes] - stream_id 0 [2 bytes] message body + stream_id 0 [2 bytes] (extend body, part 1) [488 bytes] Cell 2: @@ -249,14 +253,13 @@ message in the same cell. message header: command BEGIN_DIR [1 byte] length 0 [2 bytes] - stream_id 32 [2 bytes] message body: - (empty) --- [0 bytes] + stream_id 32 [2 bytes] message header: command DATA [1 byte] length 25 [2 bytes] - stream_id 32 [2 bytes] message body: + stream_id 32 [2 bytes] "HTTP/1.0 GET /tor/foo\r\n\r\n" [25 bytes] end-of-messages marker 0 [1 byte] @@ -281,8 +284,8 @@ above; this is only an example of what parties need to accept.) message header: command DATAGRAM [1 byte] length 1200 [2 bytes] - stream_id 99 [2 bytes] message body + stream_id 99 [2 bytes] (datagram body, part 1) [488 bytes] Cell 2: @@ -307,16 +310,16 @@ above; this is only an example of what parties need to accept.) message header: command SENDME [1 byte] length 23 [2 bytes] - stream_id 0 [2 bytes] message body: + stream_id 0 [2 bytes] version 1 [1 byte] datalen 20 [2 bytes] data (digest to ack) [20 bytes] message header: command XON [1 byte] length 1 [2 bytes] - stream_id 50 [2 bytes] message body: + stream_id 50 [2 bytes] version 1 [1 byte] end-of-messages marker 0 [1 byte] -- cgit v1.2.3-54-g00ecf From 0fc6d07d88f0af8d87b12df4cd9890eabc5e6547 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 3 Feb 2023 13:01:24 -0500 Subject: More verbage in prop340 about the stream_id transition. Specifically: * Mention this change in the introduction. * Add a section explaining how to change tor-spec and related proposals. --- proposals/340-packed-and-fragmented.md | 48 ++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/proposals/340-packed-and-fragmented.md b/proposals/340-packed-and-fragmented.md index 0d83f67..6fb1ca5 100644 --- a/proposals/340-packed-and-fragmented.md +++ b/proposals/340-packed-and-fragmented.md @@ -33,6 +33,9 @@ This proposal combines ideas from [ntor v3](./332-ntor-v3-with-extra-data.md) and prepares for [next-generation relay cryptography](./308-counter-galois-onion). +Additionally, this proposal has been revised to incorporate another +protocol change, and remove StreamId from the relay cell header. + ## A preliminary change: Relay encryption, version 1.5 We are fairly sure that, whatever we do for our next batch of relay @@ -71,10 +74,9 @@ Relay _messages_ now follow the following format: We require that "command" is never 0. -One big change from the current tor protocol is the missing `stream_id` which -we propose to move into the body because most commands set it to 0 because -they don't need it. Meaning that the `stream_id` becomes a value specified -per-command. +One big change from the current tor protocol is something that is _not_ +here: we have moved `stream_id` into the body of the relay message of +those commands that need it. Messages can be split across relay cells; multiple messages can occur in a single relay cell. We enforce the following rules: @@ -96,7 +98,7 @@ Receivers MUST validate that headers are well-formed and have valid lengths while handling the cell in which the header is encoded. If the header is invalid, the receiver must destroy the circuit. -### Some examples + ## Negotiation @@ -113,6 +115,42 @@ The `version` field is the `Relay` subprotocol version that the client wants to use. The relay must send back the same extension in its ntor3 handshake to acknowledge support. + +## Specifying the message format with moved stream ID. + +Here, we'll specify how to adjust tor-spec to describe the `stream_id` +move correctly. + +Below, suppose that `Relay=V` denotes whatever version of the relay +message subprotocol denotes support for this proposal. + +For all relay message types that include a stream ID, we insert +the following at the beginning of their fields: + +>``` +> STREAM_ID [2 bytes] (Present when Relay protocol version >= V). +>``` + +We add a note saying: + +> STREAM_ID is part of many message types, when using Relay protocol +> version V or later. Earlier versions of the Relay protocol put +> STREAM_ID in the RELAY header. In those versions, the field is +> STREAM_ID omitted from the message. +> +> Except when noted, STREAM_ID may not be zero. + +The following message types take required stream IDs: `BEGIN`, `DATA`, `END`, +`CONNECTED`, `RESOLVE`, `RESOLVED`, and `BEGIN_DIR`, `XON`, `XOFF`. + +The following message type takes an *optional* stream ID: `SENDME`. +(*Stream-level sendmes are not a thing anymore with proposal 324, but I +want to give implementations the freedom to implement prop324 and this +proposal in either order.*) + +The following message types from proposal 339 (UDP) take required stream +IDs: `CONNECT_UDP`, `CONNECTED_UDP` and `DATAGRAM`. + ## Migration We add a consensus parameter, "streamed-relay-messages", with default -- cgit v1.2.3-54-g00ecf From 5c6b282e57f866a1341eb705cb21507fcbfcc543 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 6 Feb 2023 12:25:55 +0000 Subject: Call the key in desc-auth-ephemeral-key, KP_hs_desc_ephem Proposed by @nickm in https://gitlab.torproject.org/tpo/core/arti/-/merge_requests/999/diffs#50f9790ab3f0a65f7ac3e4f413c84f51fae1f855_0_26 (I think the spec is not 100% clear that hs_y and hs_Y are *this* key, rather than some other possible ephemeral keypair the HS might have, so please would the reviewer check that this is actually true.) --- rend-spec-v3.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/rend-spec-v3.txt b/rend-spec-v3.txt index a8ac264..afc2a46 100644 --- a/rend-spec-v3.txt +++ b/rend-spec-v3.txt @@ -1208,7 +1208,7 @@ Table of contents: If client authorization is disabled, the value here should be "x25519". - "desc-auth-ephemeral-key" SP key NL + "desc-auth-ephemeral-key" SP KP_hs_desc_ephem NL [Exactly once] @@ -1239,13 +1239,11 @@ Table of contents: 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) + SECRET_SEED = x25519(KS_hs_desc_ephem, client_X) KEYS = KDF(N_hs_subcred | SECRET_SEED, 40) CLIENT-ID = fist 8 bytes of KEYS COOKIE-KEY = last 32 bytes of KEYS -- cgit v1.2.3-54-g00ecf From 7b3d7a40a0ac8f59b9f6d79205dfc53de4168f0c Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 6 Feb 2023 12:51:41 +0000 Subject: Use proper names for KP_hsc_desc_enc --- rend-spec-v3.txt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/rend-spec-v3.txt b/rend-spec-v3.txt index afc2a46..805e0d9 100644 --- a/rend-spec-v3.txt +++ b/rend-spec-v3.txt @@ -1231,19 +1231,17 @@ Table of contents: 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. + each authorized client possesses a pre-shared x25519 keypair + KS/KP_hsc_desc_enc 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 descriptor_cookie = descriptor cookie used to encrypt the descriptor And here is what the hidden service computes: - SECRET_SEED = x25519(KS_hs_desc_ephem, client_X) + SECRET_SEED = x25519(KS_hs_desc_ephem, KP_hsc_desc_enc) KEYS = KDF(N_hs_subcred | SECRET_SEED, 40) CLIENT-ID = fist 8 bytes of KEYS COOKIE-KEY = last 32 bytes of KEYS -- cgit v1.2.3-54-g00ecf From 431f6152cf24f337a737d0c215137e25f29436d9 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 6 Feb 2023 14:51:45 +0000 Subject: Fix terminology for handshake type The phrase "format number" is not defined anywhere. I think it means an HTYPE value. --- rend-spec-v3.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rend-spec-v3.txt b/rend-spec-v3.txt index a8ac264..12c1c43 100644 --- a/rend-spec-v3.txt +++ b/rend-spec-v3.txt @@ -1348,10 +1348,10 @@ Table of contents: [Exactly once] - A space-separated list of integers denoting CREATE2 cell format numbers - that the server recognizes. Must include at least ntor as described in - tor-spec.txt. See tor-spec section 5.1 for a list of recognized - handshake types. + A space-separated list of integers denoting CREATE2 cell HTYPEs + (handshake types) that the server recognizes. Must include at least + ntor as described in tor-spec.txt. See tor-spec section 5.1 for a list + of recognized handshake types. "intro-auth-required" SP types NL -- cgit v1.2.3-54-g00ecf From 39513369c7bc3c29a8514b2048ad08f42376b034 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 6 Feb 2023 14:52:47 +0000 Subject: Put HTYPE (the name for this thing) in the title for the table --- tor-spec.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tor-spec.txt b/tor-spec.txt index e522135..9aa4cc4 100644 --- a/tor-spec.txt +++ b/tor-spec.txt @@ -1022,7 +1022,7 @@ see tor-design.pdf. HLEN (Server Handshake Data Len) [2 bytes] HDATA (Server Handshake Data) [HLEN bytes] - Recognized handshake types are: + Recognized HTYPEs (handshake types) are: 0x0000 TAP -- the original Tor handshake; see 5.1.3 0x0001 reserved -- cgit v1.2.3-54-g00ecf From 71d7e7184dc11e599afb881c7e15674532338512 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 8 Feb 2023 14:49:30 +0000 Subject: Rename hs_index and hsdir_index to hs_{service,relay}_index These new names are the ones used in arti's hsdir_ring.rs and make a lot more sense than calling one of them the "directory" index and the other just the "index". In C Tor these are calculated by functions called hs_build_hs_index hs_build_hsdir_index That might be a reason *not* to accept this change. Or it might be a reason to change the C Tor code. If we don't change the names in the spec the Arti function names should change. --- rend-spec-v3.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rend-spec-v3.txt b/rend-spec-v3.txt index 51267ec..672248e 100644 --- a/rend-spec-v3.txt +++ b/rend-spec-v3.txt @@ -811,7 +811,7 @@ Table of contents: derived, the uploading or downloading party calculates: for replicanum in 1...hsdir_n_replicas: - hs_index(replicanum) = H("store-at-idx" | + hs_service_index(replicanum) = H("store-at-idx" | blinded_public_key | INT_8(replicanum) | INT_8(period_length) | @@ -825,7 +825,7 @@ Table of contents: Then, for each node listed in the current consensus with the HSDir flag, we compute a directory index for that node as: - hsdir_index(node) = H("node-idx" | node_identity | + hs_relay_index(node) = H("node-idx" | node_identity | shared_random_value | INT_8(period_num) | INT_8(period_length) ) @@ -836,7 +836,7 @@ Table of contents: Finally, for replicanum in 1...hsdir_n_replicas, the hidden service host uploads descriptors to the first hsdir_spread_store nodes whose - indices immediately follow hs_index(replicanum). If any of those + indices immediately follow hs_service_index(replicanum). If any of those nodes have already been selected for a lower-numbered replica of the service, any nodes already chosen are disregarded (i.e. skipped over) when choosing a replica's hsdir_spread_store nodes. -- cgit v1.2.3-54-g00ecf