123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526 |
- Tor Rendezvous Specification - Version 3
- This document specifies how the hidden service version 3 protocol works. This
- text used to be proposal 224-rend-spec-ng.txt.
- Table of contents:
- 0. Hidden services: overview and preliminaries.
- 0.1. Improvements over previous versions.
- 0.2. Notation and vocabulary
- 0.3. Cryptographic building blocks
- 0.4. Protocol building blocks [BUILDING-BLOCKS]
- 0.5. Assigned relay cell types
- 0.6. Acknowledgments
- 1. Protocol overview
- 1.1. View from 10,000 feet
- 1.2. In more detail: naming hidden services [NAMING]
- 1.3. In more detail: Access control [IMD:AC]
- 1.4. In more detail: Distributing hidden service descriptors. [IMD:DIST]
- 1.5. In more detail: Scaling to multiple hosts
- 1.6. In more detail: Backward compatibility with older hidden service
- 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
- 2.2.1. Dividing time into periods [TIME-PERIODS]
- 2.2.2. When to publish a hidden service descriptor [WHEN-HSDESC]
- 2.2.3. Where to publish a hidden service descriptor [WHERE-HSDESC]
- 2.2.4. Using time periods and SRVs to fetch/upload HS descriptors
- 2.2.5. Expiring hidden service descriptors [EXPIRE-DESC]
- 2.2.6. URLs for anonymous uploading and downloading
- 2.3. Publishing shared random values [PUB-SHAREDRANDOM]
- 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 [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]
- 3.1.3. Acknowledging establishment of introduction point [INTRO_ESTABLISHED]
- 3.2. Sending an INTRODUCE1 cell to the introduction point. [SEND_INTRO1]
- 3.2.1. INTRODUCE1 cell format [FMT_INTRO1]
- 3.2.2. INTRODUCE_ACK cell format. [INTRO_ACK]
- 3.3. Processing an INTRODUCE2 cell at the hidden service. [PROCESS_INTRO2]
- 3.3.1. Introduction handshake encryption requirements [INTRO-HANDSHAKE-REQS]
- 3.3.2. Example encryption handshake: ntor with extra data [NTOR-WITH-EXTRA-DATA]
- 3.4. Authentication during the introduction phase. [INTRO-AUTH]
- 3.4.1. Ed25519-based authentication.
- 4. The rendezvous protocol
- 4.1. Establishing a rendezvous point [EST_REND_POINT]
- 4.2. Joining to a rendezvous point [JOIN_REND]
- 4.2.1. Key expansion
- 4.3. Using legacy hosts as rendezvous points
- 5. Encrypting data between client and host
- 6. Encoding onion addresses [ONIONADDRESS]
- 7. Open Questions:
- -1. Draft notes
- This document describes a proposed design and specification for
- hidden services in Tor version 0.2.5.x or later. It's a replacement
- for the current rend-spec.txt, rewritten for clarity and for improved
- design.
- Look for the string "TODO" below: it describes gaps or uncertainties
- in the design.
- Change history:
- 2013-11-29: Proposal first numbered. Some TODO and XXX items remain.
- 2014-01-04: Clarify some unclear sections.
- 2014-01-21: Fix a typo.
- 2014-02-20: Move more things to the revised certificate format in the
- new updated proposal 220.
- 2015-05-26: Fix two typos.
- 0. Hidden services: overview and preliminaries.
- Hidden services aim to provide responder anonymity for bidirectional
- stream-based communication on the Tor network. Unlike regular Tor
- connections, where the connection initiator receives anonymity but
- the responder does not, hidden services attempt to provide
- bidirectional anonymity.
- Participants:
- Operator -- A person running a hidden service
- Host, "Server" -- The Tor software run by the operator to provide
- a hidden service.
- User -- A person contacting a hidden service.
- Client -- The Tor software running on the User's computer
- Hidden Service Directory (HSDir) -- A Tor node that hosts signed
- statements from hidden service hosts so that users can make
- contact with them.
- Introduction Point -- A Tor node that accepts connection requests
- for hidden services and anonymously relays those requests to the
- hidden service.
- Rendezvous Point -- A Tor node to which clients and servers
- connect and which relays traffic between them.
- 0.1. Improvements over previous versions.
- Here is a list of improvements of this proposal over the legacy hidden
- services:
- a) Better crypto (replaced SHA1/DH/RSA1024 with SHA3/ed25519/curve25519)
- b) Improved directory protocol leaking less to directory servers.
- c) Improved directory protocol with smaller surface for targeted attacks.
- d) Better onion address security against impersonation.
- e) More extensible introduction/rendezvous protocol.
- f) Offline keys for onion services
- g) Advanced client authorization
- 0.2. Notation and vocabulary
- Unless specified otherwise, all multi-octet integers are big-endian.
- We write sequences of bytes in two ways:
- 1. A sequence of two-digit hexadecimal values in square brackets,
- as in [AB AD 1D EA].
- 2. A string of characters enclosed in quotes, as in "Hello". The
- characters in these strings are encoded in their ascii
- representations; strings are NOT nul-terminated unless
- explicitly described as NUL terminated.
- We use the words "byte" and "octet" interchangeably.
- We use the vertical bar | to denote concatenation.
- We use INT_N(val) to denote the network (big-endian) encoding of the
- unsigned integer "val" in N bytes. For example, INT_4(1337) is [00 00
- 05 39]. Values are truncated like so: val % (2 ^ (N * 8)). For example,
- INT_4(42) is 42 % 4294967296 (32 bit).
- 0.3. Cryptographic building blocks
- This specification uses the following cryptographic building blocks:
- * A pseudorandom number generator backed by a strong entropy source.
- The output of the PRNG should always be hashed before being posted on
- the network to avoid leaking raw PRNG bytes to the network
- (see [PRNG-REFS]).
- * A stream cipher STREAM(iv, k) where iv is a nonce of length
- S_IV_LEN bytes and k is a key of length S_KEY_LEN bytes.
- * A public key signature system SIGN_KEYGEN()->seckey, pubkey;
- SIGN_SIGN(seckey,msg)->sig; and SIGN_CHECK(pubkey, sig, msg) ->
- { "OK", "BAD" }; where secret keys are of length SIGN_SECKEY_LEN
- bytes, public keys are of length SIGN_PUBKEY_LEN bytes, and
- signatures are of length SIGN_SIG_LEN bytes.
- This signature system must also support key blinding operations
- as discussed in appendix [KEYBLIND] and in section [SUBCRED]:
- SIGN_BLIND_SECKEY(seckey, blind)->seckey2 and
- SIGN_BLIND_PUBKEY(pubkey, blind)->pubkey2 .
- * A public key agreement system "PK", providing
- PK_KEYGEN()->seckey, pubkey; PK_VALID(pubkey) -> {"OK", "BAD"};
- and PK_HANDSHAKE(seckey, pubkey)->output; where secret keys are
- of length PK_SECKEY_LEN bytes, public keys are of length
- PK_PUBKEY_LEN bytes, and the handshake produces outputs of
- length PK_OUTPUT_LEN bytes.
- * A cryptographic hash function H(d), which should be preimage and
- collision resistant. It produces hashes of length HASH_LEN
- bytes.
- * A cryptographic message authentication code MAC(key,msg) that
- produces outputs of length MAC_LEN bytes.
- * A key derivation function KDF(message, n) that outputs n bytes.
- As a first pass, I suggest:
- * Instantiate STREAM with AES256-CTR.
- * Instantiate SIGN with Ed25519 and the blinding protocol in
- [KEYBLIND].
- * Instantiate PK with Curve25519.
- * Instantiate H with SHA3-256.
- * Instantiate KDF with SHAKE-256.
- * Instantiate MAC(key=k, message=m) with H(k_len | k | m),
- where k_len is htonll(len(k)).
- For legacy purposes, we specify compatibility with older versions of
- the Tor introduction point and rendezvous point protocols. These used
- RSA1024, DH1024, AES128, and SHA1, as discussed in
- rend-spec.txt.
- As in [proposal 220], all signatures are generated not over strings
- themselves, but over those strings prefixed with a distinguishing
- value.
- 0.4. Protocol building blocks [BUILDING-BLOCKS]
- In sections below, we need to transmit the locations and identities
- of Tor nodes. We do so in the link identification format used by
- EXTEND2 cells in the Tor protocol.
- NSPEC (Number of link specifiers) [1 byte]
- NSPEC times:
- LSTYPE (Link specifier type) [1 byte]
- LSLEN (Link specifier length) [1 byte]
- LSPEC (Link specifier) [LSLEN bytes]
- Link specifier types are as described in tor-spec.txt. Every set of
- link specifiers MUST include at minimum specifiers of type [00]
- (TLS-over-TCP, IPv4), [02] (legacy node identity) and [03] (ed25519
- identity key).
- As of 0.4.1.1-alpha, Tor includes both IPv4 and IPv6 link specifiers
- in v3 onion service protocol link specifier lists. All available
- addresses SHOULD be included as link specifiers, regardless of the
- address that Tor actually used to connect/extend to the remote relay.
- We also incorporate Tor's circuit extension handshakes, as used in
- the CREATE2 and CREATED2 cells described in tor-spec.txt. In these
- handshakes, a client who knows a public key for a server sends a
- message and receives a message from that server. Once the exchange is
- done, the two parties have a shared set of forward-secure key
- material, and the client knows that nobody else shares that key
- material unless they control the secret key corresponding to the
- server's public key.
- 0.5. Assigned relay cell types
- These relay cell types are reserved for use in the hidden service
- protocol.
- 32 -- RELAY_COMMAND_ESTABLISH_INTRO
- Sent from hidden service host to introduction point;
- establishes introduction point. Discussed in
- [REG_INTRO_POINT].
- 33 -- RELAY_COMMAND_ESTABLISH_RENDEZVOUS
- Sent from client to rendezvous point; creates rendezvous
- point. Discussed in [EST_REND_POINT].
- 34 -- RELAY_COMMAND_INTRODUCE1
- Sent from client to introduction point; requests
- introduction. Discussed in [SEND_INTRO1]
- 35 -- RELAY_COMMAND_INTRODUCE2
- Sent from introduction point to hidden service host; requests
- introduction. Same format as INTRODUCE1. Discussed in
- [FMT_INTRO1] and [PROCESS_INTRO2]
- 36 -- RELAY_COMMAND_RENDEZVOUS1
- Sent from hidden service host to rendezvous point;
- attempts to join host's circuit to
- client's circuit. Discussed in [JOIN_REND]
- 37 -- RELAY_COMMAND_RENDEZVOUS2
- Sent from rendezvous point to client;
- reports join of host's circuit to
- client's circuit. Discussed in [JOIN_REND]
- 38 -- RELAY_COMMAND_INTRO_ESTABLISHED
- Sent from introduction point to hidden service host;
- reports status of attempt to establish introduction
- point. Discussed in [INTRO_ESTABLISHED]
- 39 -- RELAY_COMMAND_RENDEZVOUS_ESTABLISHED
- Sent from rendezvous point to client; acknowledges
- receipt of ESTABLISH_RENDEZVOUS cell. Discussed in
- [EST_REND_POINT]
- 40 -- RELAY_COMMAND_INTRODUCE_ACK
- Sent from introduction point to client; acknowledges
- receipt of INTRODUCE1 cell and reports success/failure.
- Discussed in [INTRO_ACK]
- 0.6. Acknowledgments
- This design includes ideas from many people, including
- Christopher Baines,
- Daniel J. Bernstein,
- Matthew Finkel,
- Ian Goldberg,
- George Kadianakis,
- Aniket Kate,
- Tanja Lange,
- Robert Ransom,
- Roger Dingledine,
- Aaron Johnson,
- Tim Wilson-Brown ("teor"),
- special (John Brooks),
- s7r
- It's based on Tor's original hidden service design by Roger
- Dingledine, Nick Mathewson, and Paul Syverson, and on improvements to
- that design over the years by people including
- Tobias Kamm,
- Thomas Lauterbach,
- Karsten Loesing,
- Alessandro Preite Martinez,
- Robert Ransom,
- Ferdinand Rieger,
- Christoph Weingarten,
- Christian Wilms,
- We wouldn't be able to do any of this work without good attack
- designs from researchers including
- Alex Biryukov,
- Lasse Øverlier,
- Ivan Pustogarov,
- Paul Syverson
- Ralf-Philipp Weinmann,
- See [ATTACK-REFS] for their papers.
- Several of these ideas have come from conversations with
- Christian Grothoff,
- Brian Warner,
- Zooko Wilcox-O'Hearn,
- And if this document makes any sense at all, it's thanks to
- editing help from
- Matthew Finkel
- George Kadianakis,
- Peter Palfrader,
- Tim Wilson-Brown ("teor"),
- [XXX Acknowledge the huge bunch of people working on 8106.]
- [XXX Acknowledge the huge bunch of people working on 8244.]
- Please forgive me if I've missed you; please forgive me if I've
- misunderstood your best ideas here too.
- 1. Protocol overview
- In this section, we outline the hidden service protocol. This section
- omits some details in the name of simplicity; those are given more
- fully below, when we specify the protocol in more detail.
- 1.1. View from 10,000 feet
- A hidden service host prepares to offer a hidden service by choosing
- several Tor nodes to serve as its introduction points. It builds
- circuits to those nodes, and tells them to forward introduction
- requests to it using those circuits.
- Once introduction points have been picked, the host builds a set of
- documents called "hidden service descriptors" (or just "descriptors"
- for short) and uploads them to a set of HSDir nodes. These documents
- list the hidden service's current introduction points and describe
- how to make contact with the hidden service.
- When a client wants to connect to a hidden service, it first chooses
- a Tor node at random to be its "rendezvous point" and builds a
- circuit to that rendezvous point. If the client does not have an
- up-to-date descriptor for the service, it contacts an appropriate
- HSDir and requests such a descriptor.
- The client then builds an anonymous circuit to one of the hidden
- service's introduction points listed in its descriptor, and gives the
- introduction point an introduction request to pass to the hidden
- service. This introduction request includes the target rendezvous
- point and the first part of a cryptographic handshake.
- Upon receiving the introduction request, the hidden service host
- makes an anonymous circuit to the rendezvous point and completes the
- cryptographic handshake. The rendezvous point connects the two
- circuits, and the cryptographic handshake gives the two parties a
- shared key and proves to the client that it is indeed talking to the
- hidden service.
- Once the two circuits are joined, the client can send Tor RELAY cells
- to the server. RELAY_BEGIN cells open streams to an external process
- or processes configured by the server; RELAY_DATA cells are used to
- communicate data on those streams, and so forth.
- 1.2. In more detail: naming hidden services [NAMING]
- A hidden service's name is its long term master identity key. This is
- encoded as a hostname by encoding the entire key in Base 32, including a
- version byte and a checksum, and then appending the string ".onion" at the
- end. The result is a 56-character domain name.
- (This is a change from older versions of the hidden service protocol,
- where we used an 80-bit truncated SHA1 hash of a 1024 bit RSA key.)
- The names in this format are distinct from earlier names because of
- their length. An older name might look like:
- unlikelynamefora.onion
- yyhws9optuwiwsns.onion
- And a new name following this specification might look like:
- l5satjgud6gucryazcyvyvhuxhr74u6ygigiuyixe3a6ysis67ororad.onion
- Please see section [ONIONADDRESS] for the encoding specification.
- 1.3. In more detail: Access control [IMD:AC]
- 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.
- 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.)
- 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).
- 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. If
- optional client authorization is enabled, the service may additionally
- require the client to prove knowledge of a pre-shared private key.
- (NOTE: client authorization is not implemented as of 0.3.2.1-alpha.)
- 1.4. In more detail: Distributing hidden service descriptors. [IMD:DIST]
- Periodically, hidden service descriptors become stored at different
- locations to prevent a single directory or small set of directories
- from becoming a good DoS target for removing a hidden service.
- For each period, the Tor directory authorities agree upon a
- collaboratively generated random value. (See section 2.3 for a
- description of how to incorporate this value into the voting
- practice; generating the value is described in other proposals,
- including [SHAREDRANDOM-REFS].) That value, combined with hidden service
- directories' public identity keys, determines each HSDir's position
- in the hash ring for descriptors made in that period.
- Each hidden service's descriptors are placed into the ring in
- 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.
- 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.
- 1.5. In more detail: Scaling to multiple hosts
- This design is compatible with our current approaches for scaling hidden
- services. Specifically, hidden service operators can use onionbalance to
- achieve high availability between multiple nodes on the HSDir
- layer. Furthermore, operators can use proposal 255 to load balance their
- hidden services on the introduction layer. See [SCALING-REFS] for further
- discussions on this topic and alternative designs.
- 1.6. In more detail: Backward compatibility with older hidden service
- protocols
- This design is incompatible with the clients, server, and hsdir node
- protocols from older versions of the hidden service protocol as
- described in rend-spec.txt. On the other hand, it is designed to
- enable the use of older Tor nodes as rendezvous points and
- introduction points.
- 1.7. In more detail: Keeping crypto keys offline
- In this design, a hidden service's secret identity key may be
- stored offline. It's used only to generate blinded signing keys,
- which are used to sign descriptor signing keys.
- 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 [HS-DESC-ENC]
- below), and their corresponding descriptor encryption keys, and
- export those to the hidden service hosts.
- As a result, in the scenario where the Hidden Service gets
- compromised, the adversary can only impersonate it for a limited
- period of time (depending on how many signing keys were generated
- in advance).
- It's important to not send the private part of the 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
- only be used to create credentials for the descriptor signing keys.
- (NOTE: although the protocol allows them, offline keys are not
- implemented as of 0.3.2.1-alpha.)
- 1.8. In more detail: Encryption Keys And Replay Resistance
- To avoid replays of an introduction request by an introduction point,
- a hidden service host must never accept the same request
- twice. Earlier versions of the hidden service design used an
- authenticated timestamp here, but including a view of the current
- time can create a problematic fingerprint. (See proposal 222 for more
- discussion.)
- 1.9. In more detail: A menagerie of keys
- [In the text below, an "encryption keypair" is roughly "a keypair you
- can do Diffie-Hellman with" and a "signing keypair" is roughly "a
- keypair you can do ECDSA with."]
- Public/private keypairs defined in this document:
- Master (hidden service) identity key -- A master signing keypair
- used as the identity for a hidden service. This key is long
- term and not used on its own to sign anything; it is only used
- to generate blinded signing keys as described in [KEYBLIND]
- and [SUBCRED]. The public key is encoded in the ".onion"
- address according to [NAMING].
- Blinded signing key -- A keypair derived from the identity key,
- used to sign descriptor signing keys. It changes periodically for
- each service. Clients who know a 'credential' consisting of the
- 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]).
- 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]).
- Introduction point authentication key -- A short-term signing
- keypair used to identify a hidden service to a given
- introduction point. A fresh keypair is made for each
- introduction point; these are used to sign the request that a
- hidden service host makes when establishing an introduction
- point, so that clients who know the public component of this key
- can get their introduction requests sent to the right
- service. No keypair is ever used with more than one introduction
- point. (previously called a "service key" in rend-spec.txt)
- Introduction point encryption key -- A short-term encryption
- keypair used when establishing connections via an introduction
- point. Plays a role analogous to Tor nodes' onion keys. A fresh
- keypair is made for each introduction point.
- Symmetric keys defined in this document:
- 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.
- Public/private keypairs defined elsewhere:
- Onion key -- Short-term encryption keypair
- (Node) identity key
- Symmetric key-like things defined elsewhere:
- KH from circuit handshake -- An unpredictable value derived as
- 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.]
- (NOTE: client authorization is not implemented as of 0.3.2.1-alpha.)
- 2. Generating and publishing hidden service descriptors [HSDIR]
- Hidden service descriptors follow the same metaformat as other Tor
- directory objects. They are published anonymously to Tor servers with the
- HSDir flag, HSDir=2 protocol version and tor version >= 0.3.0.8 (because a
- bug was fixed in this version).
- 2.1. Deriving blinded keys and subcredentials [SUBCRED]
- 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.
- For a candidate for a key derivation method, see Appendix [KEYBLIND].
- Additionally, clients and hosts derive a subcredential for each
- period. Knowledge of the subcredential is needed to decrypt hidden
- service descriptors for each period and to authenticate with the
- hidden service host in the introduction process. Unlike the
- credential, it changes each period. Knowing the subcredential, even
- in combination with the blinded private key, does not enable the
- hidden service host to derive the main credential--therefore, it is
- safe to put the subcredential on the hidden service host while
- leaving the hidden service's private key offline.
- The subcredential for a period is derived as:
- subcredential = H("subcredential" | credential | blinded-public-key).
- In the above formula, credential corresponds to:
- credential = H("credential" | public-identity-key)
- where public-identity-key is the public identity master key of the hidden
- service.
- 2.2. Locating, uploading, and downloading hidden service descriptors
- [HASHRING]
- 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.
- Which Tor servers hosts a hidden service depends on:
- * the current time period,
- * the daily subcredential,
- * the hidden service directories' public keys,
- * a shared random value that changes in each time period,
- * a set of network-wide networkstatus consensus parameters.
- (Consensus parameters are integer values voted on by authorities
- and published in the consensus documents, described in
- dir-spec.txt, section 3.3.)
- Below we explain in more detail.
- 2.2.1. Dividing time into periods [TIME-PERIODS]
- To prevent a single set of hidden service directory from becoming a
- target by adversaries looking to permanently censor a hidden service,
- hidden service descriptors are uploaded to different locations that
- change over time.
- The length of a "time period" is controlled by the consensus
- parameter 'hsdir-interval', and is a number of minutes between 30 and
- 14400 (10 days). The default time period length is 1440 (one day).
- Time periods start at the Unix epoch (Jan 1, 1970), and are computed by
- taking the number of minutes since the epoch and dividing by the time
- period. However, we want our time periods to start at 12:00UTC every day, so
- we subtract a "rotation time offset" of 12*60 minutes from the number of
- minutes since the epoch, before dividing by the time period (effectively
- making "our" epoch start at Jan 1, 1970 12:00UTC).
- Example: If the current time is 2016-04-13 11:15:01 UTC, making the seconds
- since the epoch 1460546101, and the number of minutes since the epoch
- 24342435. We then subtract the "rotation time offset" of 12*60 minutes from
- the minutes since the epoch, to get 24341715. If the current time period
- length is 1440 minutes, by doing the division we see that we are currently
- in time period number 16903.
- Specifically, time period #16903 began 16903*1440*60 + (12*60*60) seconds
- after the epoch, at 2016-04-12 12:00 UTC, and ended at 16904*1440*60 +
- (12*60*60) seconds after the epoch, at 2016-04-13 12:00 UTC.
- 2.2.2. When to publish a hidden service descriptor [WHEN-HSDESC]
- Hidden services periodically publish their descriptor to the responsible
- HSDirs. The set of responsible HSDirs is determined as specified in
- [WHERE-HSDESC].
- Specifically, everytime a hidden service publishes its descriptor, it also
- sets up a timer for a random time between 60 minutes and 120 minutes in the
- future. When the timer triggers, the hidden service needs to publish its
- descriptor again to the responsible HSDirs for that time period.
- [TODO: Control republish period using a consensus parameter?]
- 2.2.2.1. Overlapping descriptors
- Hidden services need to upload multiple descriptors so that they can be
- reachable to clients with older or newer consensuses than them. Services
- need to upload their descriptors to the HSDirs _before_ the beginning of
- each upcoming time period, so that they are readily available for clients to
- fetch them. Furthermore, services should keep uploading their old descriptor
- even after the end of a time period, so that they can be reachable by
- clients that still have consensuses from the previous time period.
- Hence, services maintain two active descriptors at every point. Clients on
- the other hand, don't have a notion of overlapping descriptors, and instead
- always download the descriptor for the current time period and shared random
- value. It's the job of the service to ensure that descriptors will be
- available for all clients. See section [FETCHUPLOADDESC] for how this is
- achieved.
- [TODO: What to do when we run multiple hidden services in a single host?]
- 2.2.3. Where to publish a hidden service descriptor [WHERE-HSDESC]
- This section specifies how the HSDir hash ring is formed at any given
- time. Whenever a time value is needed (e.g. to get the current time period
- number), we assume that clients and services use the valid-after time from
- their latest live consensus.
- 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.
- hsdir_spread_fetch = an integer in range [1,128] with default value 3.
- hsdir_spread_store = an integer in range [1,128] with default value 4.
- (Until 0.3.2.8-rc, the default was 3.)
- 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 calculates:
- for replicanum in 1...hsdir_n_replicas:
- hs_index(replicanum) = H("store-at-idx" |
- blinded_public_key |
- INT_8(replicanum) |
- INT_8(period_length) |
- INT_8(period_num) )
- where blinded_public_key is specified in section [KEYBLIND], period_length
- is the length of the time period in minutes, and period_num is calculated
- using the current consensus "valid-after" as specified in section
- [TIME-PERIODS].
- Then, for each node listed in the current consensus with the HSDirV3 flag,
- we compute a directory index for that node as:
- hsdir_index(node) = H("node-idx" | node_identity |
- shared_random_value |
- INT_8(period_num) |
- INT_8(period_length) )
- where shared_random_value is the shared value generated by the authorities
- in section [PUB-SHAREDRANDOM], and node_identity is the ed25519 identity
- key of the node.
- 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
- 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.
- When choosing an HSDir to download from, clients choose randomly from
- among the first hsdir_spread_fetch nodes after the indices. (Note
- that, in order to make the system better tolerate disappearing
- HSDirs, hsdir_spread_fetch may be less than hsdir_spread_store.)
- Again, nodes from lower-numbered replicas are disregarded when
- choosing the spread for a replica.
- 2.2.4. Using time periods and SRVs to fetch/upload HS descriptors [FETCHUPLOADDESC]
- Hidden services and clients need to make correct use of time periods (TP)
- and shared random values (SRVs) to successfuly fetch and upload
- descriptors. Furthermore, to avoid problems with skewed clocks, both clients
- and services use the 'valid-after' time of a live consensus as a way to take
- decisions with regards to uploading and fetching descriptors. By using the
- consensus times as the ground truth here, we minimize the desynchronization
- of clients and services due to system clock. Whenever time-based decisions
- are taken in this section, assume that they are consensus times and not
- system times.
- As [PUB-SHAREDRANDOM] specifies, consensuses contain two shared random
- values (the current one and the previous one). Hidden services and clients
- are asked to match these shared random values with descriptor time periods
- and use the right SRV when fetching/uploading descriptors. This section
- attempts to precisely specify how this works.
- Let's start with an illustration of the system:
- +------------------------------------------------------------------+
- | |
- | 00:00 12:00 00:00 12:00 00:00 12:00 |
- | SRV#1 TP#1 SRV#2 TP#2 SRV#3 TP#3 |
- | |
- | $==========|-----------$===========|-----------$===========| |
- | |
- | |
- +------------------------------------------------------------------+
- Legend: [TP#1 = Time Period #1]
- [SRV#1 = Shared Random Value #1]
- ["$" = descriptor rotation moment]
- 2.2.4.1. Client behavior for fetching descriptors [CLIENTFETCH]
- And here is how clients use TPs and SRVs to fetch descriptors:
- Clients always aim to synchronize their TP with SRV, so they always want to
- use TP#N with SRV#N: To achieve this wrt time periods, clients always use
- the current time period when fetching descriptors. Now wrt SRVs, if a client
- is in the time segment between a new time period and a new SRV (i.e. the
- segments drawn with "-") it uses the current SRV, else if the client is in a
- time segment between a new SRV and a new time period (i.e. the segments
- drawn with "="), it uses the previous SRV.
- Example:
- +------------------------------------------------------------------+
- | |
- | 00:00 12:00 00:00 12:00 00:00 12:00 |
- | SRV#1 TP#1 SRV#2 TP#2 SRV#3 TP#3 |
- | |
- | $==========|-----------$===========|-----------$===========| |
- | ^ ^ |
- | C1 C2 |
- +------------------------------------------------------------------+
- If a client (C1) is at 13:00 right after TP#1, then it will use TP#1 and
- SRV#1 for fetching descriptors. Also, if a client (C2) is at 01:00 right
- after SRV#2, it will still use TP#1 and SRV#1.
- 2.2.4.2. Service behavior for uploading descriptors [SERVICEUPLOAD]
- As discussed above, services maintain two active descriptors at any time. We
- call these the "first" and "second" service descriptors. Services rotate
- their descriptor everytime they receive a consensus with a valid_after time
- past the next SRV calculation time. They rotate their descriptors by
- discarding their first descriptor, pushing the second descriptor to the
- first, and rebuilding their second descriptor with the latest data.
- Services like clients also employ a different logic for picking SRV and TP
- values based on their position in the graph above. Here is the logic:
- 2.2.4.2.1. First descriptor upload logic [FIRSTDESCUPLOAD]
- Here is the service logic for uploading its first descriptor:
- When a service is in the time segment between a new time period a new SRV
- (i.e. the segments drawn with "-"), it uses the previous time period and
- previous SRV for uploading its first descriptor: that's meant to cover
- for clients that have a consensus that is still in the previous time period.
- Example: Consider in the above illustration that the service is at 13:00
- right after TP#1. It will upload its first descriptor using TP#0 and SRV#0.
- So if a client still has a 11:00 consensus it will be able to access it
- based on the client logic above.
- Now if a service is in the time segment between a new SRV and a new time
- period (i.e. the segments drawn with "=") it uses the current time period
- and the previous SRV for its first descriptor: that's meant to cover clients
- with an up-to-date consensus in the same time period as the service.
- Example:
- +------------------------------------------------------------------+
- | |
- | 00:00 12:00 00:00 12:00 00:00 12:00 |
- | SRV#1 TP#1 SRV#2 TP#2 SRV#3 TP#3 |
- | |
- | $==========|-----------$===========|-----------$===========| |
- | ^ |
- | S |
- +------------------------------------------------------------------+
- Consider that the service is at 01:00 right after SRV#2: it will upload its
- first descriptor using TP#1 and SRV#1.
- 2.2.4.2.2. Second descriptor upload logic [SECONDDESCUPLOAD]
- Here is the service logic for uploading its second descriptor:
- When a service is in the time segment between a new time period a new SRV
- (i.e. the segments drawn with "-"), it uses the current time period and
- current SRV for uploading its second descriptor: that's meant to cover for
- clients that have an up-to-date consensus on the same TP as the service.
- Example: Consider in the above illustration that the service is at 13:00
- right after TP#1: it will upload its second descriptor using TP#1 and SRV#1.
- Now if a service is in the time segment between a new SRV and a new time
- period (i.e. the segments drawn with "=") it uses the next time period and
- the current SRV for its second descriptor: that's meant to cover clients
- with a newer consensus than the service (in the next time period).
- Example:
- +------------------------------------------------------------------+
- | |
- | 00:00 12:00 00:00 12:00 00:00 12:00 |
- | SRV#1 TP#1 SRV#2 TP#2 SRV#3 TP#3 |
- | |
- | $==========|-----------$===========|-----------$===========| |
- | ^ |
- | S |
- +------------------------------------------------------------------+
- Consider that the service is at 01:00 right after SRV#2: it will upload its
- second descriptor using TP#2 and SRV#2.
- 2.2.5. Expiring hidden service descriptors [EXPIRE-DESC]
- Hidden services set their descriptor's "descriptor-lifetime" field to 180
- minutes (3 hours). Hidden services ensure that their descriptor will remain
- valid in the HSDir caches, by republishing their descriptors periodically as
- specified in [WHEN-HSDESC].
- Hidden services MUST also keep their introduction circuits alive for as long
- as descriptors including those intro points are valid (even if that's after
- the time period has changed).
- 2.2.6. URLs for anonymous uploading and downloading
- Hidden service descriptors conforming to this specification are uploaded
- with an HTTP POST request to the URL /tor/hs/<version>/publish relative to
- the hidden service directory's root, and downloaded with an HTTP GET
- request for the URL /tor/hs/<version>/<z> where <z> is a base64 encoding of
- the hidden service's blinded public key and <version> is the protocol
- version which is "3" in this case.
- These requests must be made anonymously, on circuits not used for
- anything else.
- 2.2.7. Client-side validation of onion addresses
- When a Tor client receives a prop224 onion address from the user, it
- MUST first validate the onion address before attempting to connect or
- fetch its descriptor. If the validation fails, the client MUST
- refuse to connect.
- As part of the address validation, Tor clients should check that the
- underlying ed25519 key does not have a torsion component. If Tor accepted
- ed25519 keys with torsion components, attackers could create multiple
- equivalent onion addresses for a single ed25519 key, which would map to the
- same service. We want to avoid that because it could lead to phishing
- attacks and surprising behaviors (e.g. imagine a browser plugin that blocks
- onion addresses, but could be bypassed using an equivalent onion address
- with a torsion component).
- The right way for clients to detect such fraudulent addresses (which should
- only occur malevolently and never natutally) is to extract the ed25519
- public key from the onion address and multiply it by the ed25519 group order
- and ensure that the result is the ed25519 identity element. For more
- details, please see [TORSION-REFS].
- 2.3. Publishing shared random values [PUB-SHAREDRANDOM]
- Our design for limiting the predictability of HSDir upload locations
- relies on a shared random value (SRV) that isn't predictable in advance or
- too influenceable by an attacker. The authorities must run a protocol
- to generate such a value at least once per hsdir period. Here we
- describe how they publish these values; the procedure they use to
- generate them can change independently of the rest of this
- specification. For more information see [SHAREDRANDOM-REFS].
- According to proposal 250, we add two new lines in consensuses:
- "shared-rand-previous-value" SP NUM_REVEALS SP VALUE NL
- "shared-rand-current-value" SP NUM_REVEALS SP VALUE NL
- 2.3.1. Client behavior in the absense of shared random values
- If the previous or current shared random value cannot be found in a
- consensus, then Tor clients and services need to generate their own random
- value for use when choosing HSDirs.
- To do so, Tor clients and services use:
- SRV = H("shared-random-disaster" | INT_8(period_length) | INT_8(period_num))
- where period_length is the length of a time period in minutes, period_num is
- calculated as specified in [TIME-PERIODS] for the wanted shared random value
- that could not be found originally.
- 2.3.2. Hidden services and changing shared random values
- It's theoretically possible that the consensus shared random values will
- change or disappear in the middle of a time period because of directory
- authorities dropping offline or misbehaving.
- To avoid client reachability issues in this rare event, hidden services
- should use the new shared random values to find the new responsible HSDirs
- and upload their descriptors there.
- XXX How long should they upload descriptors there for?
- 2.4. Hidden service descriptors: outer wrapper [DESC-OUTER]
- The format for a hidden service descriptor is as follows, using the
- meta-format from dir-spec.txt.
- "hs-descriptor" SP version-number NL
- [At start, exactly once.]
- The version-number is a 32 bit unsigned integer indicating the version
- of the descriptor. Current version is "3".
- "descriptor-lifetime" SP LifetimeMinutes NL
- [Exactly once]
- The lifetime of a descriptor in minutes. An HSDir SHOULD expire the
- hidden service descriptor at least LifetimeMinutes after it was
- uploaded.
- The LifetimeMinutes field can take values between 30 and 720 (12
- hours).
- "descriptor-signing-key-cert" NL certificate NL
- [Exactly once.]
- The 'certificate' field contains a certificate in the format from
- proposal 220, wrapped with "-----BEGIN ED25519 CERT-----". The
- certificate cross-certifies the short-term descriptor signing key with
- the blinded public key. The certificate type must be [08], and the
- blinded public key must be present as the signing-key extension.
- "revision-counter" SP Integer NL
- [Exactly once.]
- The revision number of the descriptor. If an HSDir receives a
- second descriptor for a key that it already has a descriptor for,
- it should retain and serve the descriptor with the higher
- revision-counter.
- (Checking for monotonically increasing revision-counter values
- prevents an attacker from replacing a newer descriptor signed by
- a given key with a copy of an older version.)
- "superencrypted" NL encrypted-string
- [Exactly once.]
- 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. (The resulting document does not end with
- a newline character.)
- "signature" SP signature NL
- [exactly once, at end.]
- A signature of all previous fields, using the signing key in the
- descriptor-signing-key-cert line, prefixed by the string "Tor onion
- service descriptor sig v3". We use a separate key for signing, so that
- the hidden service host does not need to have its private blinded key
- online.
- HSDirs accept hidden service descriptors of up to 50k bytes (a consensus
- parameter should also be introduced to control this value).
- 2.5. Hidden service descriptors: encryption format [HS-DESC-ENC]
- Hidden service descriptors are protected by two layers of encryption.
- Clients need to decrypt both layers to connect to the hidden service.
- 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.
- 2.5.1. First layer of encryption [HS-DESC-FIRST-LAYER]
- The first layer of HS descriptor encryption is designed to protect
- descriptor confidentiality against entities who don't know the public
- identity key of the hidden service.
- 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 encryption scheme in [HS-DESC-ENCRYPTION-KEYS] uses the service
- credential which is derived from the public identity key (see [SUBCRED]) to
- ensure that only entities who know the public identity key can decrypt the
- first descriptor layer.
- 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]
- (NOTE: client authorization is not implemented as of 0.3.2.1-alpha.)
- 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(subcredential | 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 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]
- 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).
- 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
- [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.
- "intro-auth-required" SP types NL
- [At most once]
- 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"
- [None or at most once]
- If present, this line indicates that the service is a Single Onion
- Service (see prop260 for more details about that type of service). This
- field has been introduced in 0.3.0 meaning 0.2.9 service don't include
- this.
- Followed by zero or more introduction points as follows (see section
- [NUM_INTRO_POINT] below for accepted values):
- "introduction-point" SP link-specifiers NL
- [Exactly once per introduction point at start of introduction
- point section]
- The link-specifiers is a base64 encoding of a link specifier
- block in the format described in BUILDING-BLOCKS.
- As of 0.4.1.1-alpha, services include both IPv4 and IPv6 link
- specifiers in descriptors. All available addresses SHOULD be
- included in the descriptor, regardless of the address that the
- onion service actually used to connect/extend to the intro
- point.
- The client SHOULD NOT reject any LSTYPE fields which it doesn't
- recognize; instead, it should use them verbatim in its EXTEND
- request to the introduction point.
- The client MAY perform basic validity checks on the link
- specifiers in the descriptor. These checks SHOULD NOT leak
- detailed information about the client's version, configuration,
- or consensus. (See 3.3 for service link specifier handling.)
- "onion-key" SP "ntor" SP key NL
- [Exactly once per introduction point]
- The key is a base64 encoded curve25519 public key which is the onion
- key of the introduction point Tor node used for the ntor handshake
- when a client extends to it.
- "auth-key" NL certificate NL
- [Exactly once per introduction point]
- The certificate is a proposal 220 certificate wrapped in
- "-----BEGIN ED25519 CERT-----", cross-certifying the descriptor
- signing key with the introduction point authentication key, which
- is included in the mandatory signing-key extension. The certificate
- type must be [09].
- "enc-key" SP "ntor" SP key NL
- [Exactly once per introduction point]
- The key is a base64 encoded curve25519 public key used to encrypt
- the introduction request to service.
- "enc-key-cert" NL certificate NL
- [Exactly once per introduction point]
- Cross-certification of the descriptor signing key by the encryption
- key.
- For "ntor" keys, certificate is a proposal 220 certificate wrapped
- in "-----BEGIN ED25519 CERT-----" armor, cross-certifying the
- descriptor signing key with the ed25519 equivalent of a curve25519
- public encryption key derived using the process in proposal 228
- appendix A. The certificate type must be [0B], and the signing-key
- extension is mandatory.
- "legacy-key" NL key NL
- [None or at most once per introduction point]
- The key is an ASN.1 encoded RSA public key in PEM format used for a
- legacy introduction point as described in [LEGACY_EST_INTRO].
- This field is only present if the introduction point only supports
- legacy protocol (v2) that is <= 0.2.9 or the protocol version value
- "HSIntro 3".
- "legacy-key-cert" NL certificate NL
- [None or at most once per introduction point]
- MUST be present if "legacy-key" is present.
- The certificate is a proposal 220 RSA->Ed cross-certificate wrapped
- in "-----BEGIN CROSSCERT-----" armor, cross-certifying the
- descriptor signing key with the RSA public key found in
- "legacy-key".
- To remain compatible with future revisions to the descriptor format,
- clients should ignore unrecognized lines in the descriptor.
- Other encryption and authentication key formats are allowed; clients
- should ignore ones they do not recognize.
- 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:
- Minimum: 0 - Default: 3 - Maximum: 20
- A value of 0 would means that the service is still alive but doesn't want
- to be reached by any client at the moment. Note that the descriptor size
- increases considerably as more introduction points are added.
- The reason for a maximum value of 20 is to give enough scalability to tools
- like OnionBalance to be able to load balance up to 120 servers (20 x 6
- 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 [INTRO-PROTOCOL]
- The introduction protocol proceeds in three steps.
- First, a hidden service host builds an anonymous circuit to a Tor
- node and registers that circuit as an introduction point.
- Single Onion Services attempt to build a non-anonymous single-hop circuit,
- but use an anonymous 3-hop circuit if:
- * the intro point is on an address that is configured as unreachable via
- a direct connection, or
- * the initial attempt to connect to the intro point over a single-hop
- circuit fails, and they are retrying the intro point connection.
- [After 'First' and before 'Second', the hidden service publishes its
- introduction points and associated keys, and the client fetches
- them as described in section [HSDIR] above.]
- Second, a client builds an anonymous circuit to the introduction
- point, and sends an introduction request.
- Third, the introduction point relays the introduction request along
- the introduction circuit to the hidden service host, and acknowledges
- the introduction request to the client.
- 3.1. Registering an introduction point [REG_INTRO_POINT]
- 3.1.1. Extensible ESTABLISH_INTRO protocol. [EST_INTRO]
- When a hidden service is establishing a new introduction point, it
- sends an ESTABLISH_INTRO cell with the following contents:
- AUTH_KEY_TYPE [1 byte]
- AUTH_KEY_LEN [2 bytes]
- AUTH_KEY [AUTH_KEY_LEN bytes]
- N_EXTENSIONS [1 byte]
- N_EXTENSIONS times:
- EXT_FIELD_TYPE [1 byte]
- EXT_FIELD_LEN [1 byte]
- EXT_FIELD [EXT_FIELD_LEN bytes]
- HANDSHAKE_AUTH [MAC_LEN bytes]
- SIG_LEN [2 bytes]
- SIG [SIG_LEN bytes]
- The AUTH_KEY_TYPE field indicates the type of the introduction point
- authentication key and the type of the MAC to use in
- HANDSHAKE_AUTH. Recognized types are:
- [00, 01] -- Reserved for legacy introduction cells; see
- [LEGACY_EST_INTRO below]
- [02] -- Ed25519; SHA3-256.
- The AUTH_KEY_LEN field determines the length of the AUTH_KEY
- field. The AUTH_KEY field contains the public introduction point
- authentication key.
- The EXT_FIELD_TYPE, EXT_FIELD_LEN, EXT_FIELD entries are reserved for
- future extensions to the introduction protocol. Extensions with
- unrecognized EXT_FIELD_TYPE values must be ignored.
- The HANDSHAKE_AUTH field contains the MAC of all earlier fields in
- the cell using as its key the shared per-circuit material ("KH")
- generated during the circuit extension protocol; see tor-spec.txt
- section 5.2, "Setting circuit keys". It prevents replays of
- ESTABLISH_INTRO cells.
- SIG_LEN is the length of the signature.
- SIG is a signature, using AUTH_KEY, of all contents of the cell, up
- to but not including SIG. These contents are prefixed with the string
- "Tor establish-intro cell v1".
- Upon receiving an ESTABLISH_INTRO cell, a Tor node first decodes the
- key and the signature, and checks the signature. The node must reject
- the ESTABLISH_INTRO cell and destroy the circuit in these cases:
- * If the key type is unrecognized
- * If the key is ill-formatted
- * If the signature is incorrect
- * If the HANDSHAKE_AUTH value is incorrect
- * If the circuit is already a rendezvous circuit.
- * If the circuit is already an introduction circuit.
- [TODO: some scalability designs fail there.]
- * If the key is already in use by another circuit.
- Otherwise, the node must associate the key with the circuit, for use
- later in INTRODUCE1 cells.
- 3.1.2. Registering an introduction point on a legacy Tor node
- [LEGACY_EST_INTRO]
- Tor nodes should also support an older version of the ESTABLISH_INTRO
- cell, first documented in rend-spec.txt. New hidden service hosts
- must use this format when establishing introduction points at older
- Tor nodes that do not support the format above in [EST_INTRO].
- In this older protocol, an ESTABLISH_INTRO cell contains:
- KEY_LEN [2 bytes]
- KEY [KEY_LEN bytes]
- HANDSHAKE_AUTH [20 bytes]
- SIG [variable, up to end of relay payload]
- The KEY_LEN variable determines the length of the KEY field.
- The KEY field is the ASN1-encoded legacy RSA public key that was also
- included in the hidden service descriptor.
- The HANDSHAKE_AUTH field contains the SHA1 digest of (KH | "INTRODUCE").
- The SIG field contains an RSA signature, using PKCS1 padding, of all
- earlier fields.
- Older versions of Tor always use a 1024-bit RSA key for these introduction
- authentication keys.
- 3.1.3. Acknowledging establishment of introduction point [INTRO_ESTABLISHED]
- After setting up an introduction circuit, the introduction point reports its
- status back to the hidden service host with an INTRO_ESTABLISHED cell.
- The INTRO_ESTABLISHED cell has the following contents:
- N_EXTENSIONS [1 byte]
- N_EXTENSIONS times:
- EXT_FIELD_TYPE [1 byte]
- EXT_FIELD_LEN [1 byte]
- EXT_FIELD [EXT_FIELD_LEN bytes]
- Older versions of Tor send back an empty INTRO_ESTABLISHED cell instead.
- Services must accept an empty INTRO_ESTABLISHED cell from a legacy relay.
- 3.2. Sending an INTRODUCE1 cell to the introduction point. [SEND_INTRO1]
- In order to participate in the introduction protocol, a client must
- know the following:
- * An introduction point for a service.
- * The introduction authentication key for that introduction point.
- * The introduction encryption key for that introduction point.
- The client sends an INTRODUCE1 cell to the introduction point,
- containing an identifier for the service, an identifier for the
- encryption key that the client intends to use, and an opaque blob to
- be relayed to the hidden service host.
- In reply, the introduction point sends an INTRODUCE_ACK cell back to
- the client, either informing it that its request has been delivered,
- or that its request will not succeed.
- [TODO: specify what tor should do when receiving a malformed cell. Drop it?
- Kill circuit? This goes for all possible cells.]
- 3.2.1. INTRODUCE1 cell format [FMT_INTRO1]
- When a client is connecting to an introduction point, INTRODUCE1 cells
- should be of the form:
- LEGACY_KEY_ID [20 bytes]
- AUTH_KEY_TYPE [1 byte]
- AUTH_KEY_LEN [2 bytes]
- AUTH_KEY [AUTH_KEY_LEN bytes]
- N_EXTENSIONS [1 byte]
- N_EXTENSIONS times:
- EXT_FIELD_TYPE [1 byte]
- EXT_FIELD_LEN [1 byte]
- EXT_FIELD [EXT_FIELD_LEN bytes]
- ENCRYPTED [Up to end of relay payload]
- AUTH_KEY_TYPE is defined as in [EST_INTRO]. Currently, the only value of
- AUTH_KEY_TYPE for this cell is an Ed25519 public key [02].
- The LEGACY_KEY_ID field is used to distinguish between legacy and new style
- INTRODUCE1 cells. In new style INTRODUCE1 cells, LEGACY_KEY_ID is 20 zero
- bytes. Upon receiving an INTRODUCE1 cell, the introduction point checks the
- LEGACY_KEY_ID field. If LEGACY_KEY_ID is non-zero, the INTRODUCE1 cell
- should be handled as a legacy INTRODUCE1 cell by the intro point.
- Upon receiving a INTRODUCE1 cell, the introduction point checks
- whether AUTH_KEY matches the introduction point authentication key for an
- active introduction circuit. If so, the introduction point sends an
- INTRODUCE2 cell with exactly the same contents to the service, and sends an
- INTRODUCE_ACK response to the client.
- 3.2.2. INTRODUCE_ACK cell format. [INTRO_ACK]
- An INTRODUCE_ACK cell has the following fields:
- STATUS [2 bytes]
- N_EXTENSIONS [1 bytes]
- N_EXTENSIONS times:
- EXT_FIELD_TYPE [1 byte]
- EXT_FIELD_LEN [1 byte]
- EXT_FIELD [EXT_FIELD_LEN bytes]
- Recognized status values are:
- [00 00] -- Success: cell relayed to hidden service host.
- [00 01] -- Failure: service ID not recognized
- [00 02] -- Bad message format
- [00 03] -- Can't relay cell to service
- 3.3. Processing an INTRODUCE2 cell at the hidden service. [PROCESS_INTRO2]
- Upon receiving an INTRODUCE2 cell, the hidden service host checks whether
- the AUTH_KEY or LEGACY_KEY_ID field matches the keys for this
- introduction circuit.
- The service host then checks whether it has received a cell with these
- contents or rendezvous cookie before. If it has, it silently drops it as a
- replay. (It must maintain a replay cache for as long as it accepts cells
- with the same encryption key. Note that the encryption format below should
- be non-malleable.)
- If the cell is not a replay, it decrypts the ENCRYPTED field,
- establishes a shared key with the client, and authenticates the whole
- contents of the cell as having been unmodified since they left the
- client. There may be multiple ways of decrypting the ENCRYPTED field,
- depending on the chosen type of the encryption key. Requirements for
- an introduction handshake protocol are described in
- [INTRO-HANDSHAKE-REQS]. We specify one below in section
- [NTOR-WITH-EXTRA-DATA].
- The decrypted plaintext must have the form:
- RENDEZVOUS_COOKIE [20 bytes]
- N_EXTENSIONS [1 byte]
- N_EXTENSIONS times:
- EXT_FIELD_TYPE [1 byte]
- EXT_FIELD_LEN [1 byte]
- EXT_FIELD [EXT_FIELD_LEN bytes]
- ONION_KEY_TYPE [1 bytes]
- ONION_KEY_LEN [2 bytes]
- ONION_KEY [ONION_KEY_LEN bytes]
- NSPEC (Number of link specifiers) [1 byte]
- NSPEC times:
- LSTYPE (Link specifier type) [1 byte]
- LSLEN (Link specifier length) [1 byte]
- LSPEC (Link specifier) [LSLEN bytes]
- PAD (optional padding) [up to end of plaintext]
- Upon processing this plaintext, the hidden service makes sure that
- any required authentication is present in the extension fields, and
- then extends a rendezvous circuit to the node described in the LSPEC
- fields, using the ONION_KEY to complete the extension. As mentioned
- in [BUILDING-BLOCKS], the "TLS-over-TCP, IPv4" and "Legacy node
- identity" specifiers must be present.
- As of 0.4.1.1-alpha, clients include both IPv4 and IPv6 link specifiers
- in INTRODUCE1 cells. All available addresses SHOULD be included in the
- cell, regardless of the address that the client actually used to extend
- to the rendezvous point.
- The hidden service should handle invalid or unrecognised link specifiers
- the same way as clients do in section 2.5.2.2. In particular, services
- MAY perform basic validity checks on link specifiers, and SHOULD NOT
- reject unrecognised link specifiers, to avoid information leaks.
- The ONION_KEY_TYPE field is:
- [01] NTOR: ONION_KEY is 32 bytes long.
- The ONION_KEY field describes the onion key that must be used when
- extending to the rendezvous point. It must be of a type listed as
- supported in the hidden service descriptor.
- When using a legacy introduction point, the INTRODUCE cells must be padded
- to a certain length using the PAD field in the encrypted portion.
- Upon receiving a well-formed INTRODUCE2 cell, the hidden service host
- will have:
- * The information needed to connect to the client's chosen
- rendezvous point.
- * The second half of a handshake to authenticate and establish a
- shared key with the hidden service client.
- * A set of shared keys to use for end-to-end encryption.
- 3.3.1. Introduction handshake encryption requirements [INTRO-HANDSHAKE-REQS]
- When decoding the encrypted information in an INTRODUCE2 cell, a
- hidden service host must be able to:
- * Decrypt additional information included in the INTRODUCE2 cell,
- to include the rendezvous token and the information needed to
- extend to the rendezvous point.
- * Establish a set of shared keys for use with the client.
- * Authenticate that the cell has not been modified since the client
- generated it.
- Note that the old TAP-derived protocol of the previous hidden service
- design achieved the first two requirements, but not the third.
- 3.3.2. Example encryption handshake: ntor with extra data
- [NTOR-WITH-EXTRA-DATA]
- [TODO: relocate this]
- This is a variant of the ntor handshake (see tor-spec.txt, section
- 5.1.4; see proposal 216; and see "Anonymity and one-way
- authentication in key-exchange protocols" by Goldberg, Stebila, and
- Ustaoglu).
- It behaves the same as the ntor handshake, except that, in addition
- to negotiating forward secure keys, it also provides a means for
- encrypting non-forward-secure data to the server (in this case, to
- the hidden service host) as part of the handshake.
- Notation here is as in section 5.1.4 of tor-spec.txt, which defines
- the ntor handshake.
- The PROTOID for this variant is "tor-hs-ntor-curve25519-sha3-256-1".
- We also use the following tweak values:
- t_hsenc = PROTOID | ":hs_key_extract"
- t_hsverify = PROTOID | ":hs_verify"
- t_hsmac = PROTOID | ":hs_mac"
- m_hsexpand = PROTOID | ":hs_key_expand"
- To make an INTRODUCE1 cell, the client must know a public encryption
- key B for the hidden service on this introduction circuit. The client
- generates a single-use keypair:
- x,X = KEYGEN()
- and computes:
- intro_secret_hs_input = EXP(B,x) | AUTH_KEY | X | B | PROTOID
- info = m_hsexpand | subcredential
- hs_keys = KDF(intro_secret_hs_input | t_hsenc | info, S_KEY_LEN+MAC_LEN)
- ENC_KEY = hs_keys[0:S_KEY_LEN]
- MAC_KEY = hs_keys[S_KEY_LEN:S_KEY_LEN+MAC_KEY_LEN]
- and sends, as the ENCRYPTED part of the INTRODUCE1 cell:
- CLIENT_PK [PK_PUBKEY_LEN bytes]
- ENCRYPTED_DATA [Padded to length of plaintext]
- MAC [MAC_LEN bytes]
- Substituting those fields into the INTRODUCE1 cell body format
- described in [FMT_INTRO1] above, we have
- LEGACY_KEY_ID [20 bytes]
- AUTH_KEY_TYPE [1 byte]
- AUTH_KEY_LEN [2 bytes]
- AUTH_KEY [AUTH_KEY_LEN bytes]
- N_EXTENSIONS [1 bytes]
- N_EXTENSIONS times:
- EXT_FIELD_TYPE [1 byte]
- EXT_FIELD_LEN [1 byte]
- EXT_FIELD [EXT_FIELD_LEN bytes]
- ENCRYPTED:
- CLIENT_PK [PK_PUBKEY_LEN bytes]
- ENCRYPTED_DATA [Padded to length of plaintext]
- MAC [MAC_LEN bytes]
- (This format is as documented in [FMT_INTRO1] above, except that here
- we describe how to build the ENCRYPTED portion.)
- Here, the encryption key plays the role of B in the regular ntor
- handshake, and the AUTH_KEY field plays the role of the node ID.
- The CLIENT_PK field is the public key X. The ENCRYPTED_DATA field is
- the message plaintext, encrypted with the symmetric key ENC_KEY. The
- MAC field is a MAC of all of the cell from the AUTH_KEY through the
- end of ENCRYPTED_DATA, using the MAC_KEY value as its key.
- To process this format, the hidden service checks PK_VALID(CLIENT_PK)
- as necessary, and then computes ENC_KEY and MAC_KEY as the client did
- above, except using EXP(CLIENT_PK,b) in the calculation of
- intro_secret_hs_input. The service host then checks whether the MAC is
- correct. If it is invalid, it drops the cell. Otherwise, it computes
- the plaintext by decrypting ENCRYPTED_DATA.
- The hidden service host now completes the service side of the
- extended ntor handshake, as described in tor-spec.txt section 5.1.4,
- with the modified PROTOID as given above. To be explicit, the hidden
- service host generates a keypair of y,Y = KEYGEN(), and uses its
- introduction point encryption key 'b' to computes:
- intro_secret_hs_input = EXP(X,b) | AUTH_KEY | X | B | PROTOID
- info = m_hsexpand | subcredential
- hs_keys = KDF(intro_secret_hs_input | t_hsenc | info, S_KEY_LEN+MAC_LEN)
- HS_DEC_KEY = hs_keys[0:S_KEY_LEN]
- HS_MAC_KEY = hs_keys[S_KEY_LEN:S_KEY_LEN+MAC_KEY_LEN]
- (The above are used to check the MAC and then decrypt the
- encrypted data.)
- rend_secret_hs_input = EXP(X,y) | EXP(X,b) | AUTH_KEY | B | X | Y | PROTOID
- NTOR_KEY_SEED = MAC(rend_secret_hs_input, t_hsenc)
- verify = MAC(rend_secret_hs_input, t_hsverify)
- auth_input = verify | AUTH_KEY | B | Y | X | PROTOID | "Server"
- AUTH_INPUT_MAC = MAC(auth_input, t_hsmac)
- (The above are used to finish the ntor handshake.)
- The server's handshake reply is:
- SERVER_PK Y [PK_PUBKEY_LEN bytes]
- AUTH AUTH_INPUT_MAC [MAC_LEN bytes]
- These fields will be sent to the client in a RENDEZVOUS1 cell using the
- HANDSHAKE_INFO element (see [JOIN_REND]).
- The hidden service host now also knows the keys generated by the
- handshake, which it will use to encrypt and authenticate data
- end-to-end between the client and the server. These keys are as
- computed in tor-spec.txt section 5.1.4.
- 3.4. Authentication during the introduction phase. [INTRO-AUTH]
- Hidden services may restrict access only to authorized users.
- One mechanism to do so is the credential mechanism, where only users who
- know the credential for a hidden service may connect at all.
- 3.4.1. Ed25519-based authentication.
- To authenticate with an Ed25519 private key, the user must include an
- extension field in the encrypted part of the INTRODUCE1 cell with an
- EXT_FIELD_TYPE type of [02] and the contents:
- Nonce [16 bytes]
- Pubkey [32 bytes]
- Signature [64 bytes]
- Nonce is a random value. Pubkey is the public key that will be used
- to authenticate. [TODO: should this be an identifier for the public
- key instead?] Signature is the signature, using Ed25519, of:
- "hidserv-userauth-ed25519"
- Nonce (same as above)
- Pubkey (same as above)
- AUTH_KEY (As in the INTRODUCE1 cell)
- The hidden service host checks this by seeing whether it recognizes
- and would accept a signature from the provided public key. If it
- would, then it checks whether the signature is correct. If it is,
- then the correct user has authenticated.
- Replay prevention on the whole cell is sufficient to prevent replays
- on the authentication.
- Users SHOULD NOT use the same public key with multiple hidden
- services.
- 4. The rendezvous protocol
- Before connecting to a hidden service, the client first builds a
- circuit to an arbitrarily chosen Tor node (known as the rendezvous
- point), and sends an ESTABLISH_RENDEZVOUS cell. The hidden service
- later connects to the same node and sends a RENDEZVOUS cell. Once
- this has occurred, the relay forwards the contents of the RENDEZVOUS
- cell to the client, and joins the two circuits together.
- Single Onion Services attempt to build a non-anonymous single-hop circuit,
- but use an anonymous 3-hop circuit if:
- * the rend point is on an address that is configured as unreachable via
- a direct connection, or
- * the initial attempt to connect to the rend point over a single-hop
- circuit fails, and they are retrying the rend point connection.
- 4.1. Establishing a rendezvous point [EST_REND_POINT]
- The client sends the rendezvous point a RELAY_COMMAND_ESTABLISH_RENDEZVOUS
- cell containing a 20-byte value.
- RENDEZVOUS_COOKIE [20 bytes]
- Rendezvous points MUST ignore any extra bytes in an
- ESTABLISH_RENDEZVOUS cell. (Older versions of Tor did not.)
- The rendezvous cookie is an arbitrary 20-byte value, chosen randomly
- by the client. The client SHOULD choose a new rendezvous cookie for
- each new connection attempt. If the rendezvous cookie is already in
- use on an existing circuit, the rendezvous point should reject it and
- destroy the circuit.
- Upon receiving an ESTABLISH_RENDEZVOUS cell, the rendezvous point associates
- the cookie with the circuit on which it was sent. It replies to the client
- with an empty RENDEZVOUS_ESTABLISHED cell to indicate success. Clients MUST
- ignore any extra bytes in a RENDEZVOUS_ESTABLISHED cell.
- The client MUST NOT use the circuit which sent the cell for any
- purpose other than rendezvous with the given location-hidden service.
- The client should establish a rendezvous point BEFORE trying to
- connect to a hidden service.
- 4.2. Joining to a rendezvous point [JOIN_REND]
- To complete a rendezvous, the hidden service host builds a circuit to
- the rendezvous point and sends a RENDEZVOUS1 cell containing:
- RENDEZVOUS_COOKIE [20 bytes]
- HANDSHAKE_INFO [variable; depends on handshake type
- used.]
- where RENDEZVOUS_COOKIE is the cookie suggested by the client during the
- introduction (see [PROCESS_INTRO2]) and HANDSHAKE_INFO is defined in
- [NTOR-WITH-EXTRA-DATA].
- If the cookie matches the rendezvous cookie set on any
- not-yet-connected circuit on the rendezvous point, the rendezvous
- point connects the two circuits, and sends a RENDEZVOUS2 cell to the
- client containing the HANDSHAKE_INFO field of the RENDEZVOUS1 cell.
- Upon receiving the RENDEZVOUS2 cell, the client verifies that HANDSHAKE_INFO
- correctly completes a handshake. To do so, the client parses SERVER_PK from
- HANDSHAKE_INFO and reverses the final operations of section
- [NTOR-WITH-EXTRA-DATA] as shown here:
- rend_secret_hs_input = EXP(Y,x) | EXP(B,x) | AUTH_KEY | B | X | Y | PROTOID
- NTOR_KEY_SEED = MAC(ntor_secret_input, t_hsenc)
- verify = MAC(ntor_secret_input, t_hsverify)
- auth_input = verify | AUTH_KEY | B | Y | X | PROTOID | "Server"
- AUTH_INPUT_MAC = MAC(auth_input, t_hsmac)
- Finally the client verifies that the received AUTH field of HANDSHAKE_INFO
- is equal to the computed AUTH_INPUT_MAC.
- Now both parties use the handshake output to derive shared keys for use on
- the circuit as specified in the section below:
- 4.2.1. Key expansion
- The hidden service and its client need to derive crypto keys from the
- NTOR_KEY_SEED part of the handshake output. To do so, they use the KDF
- construction as follows:
- K = KDF(NTOR_KEY_SEED | m_hsexpand, HASH_LEN * 2 + S_KEY_LEN * 2)
- The first HASH_LEN bytes of K form the forward digest Df; the next HASH_LEN
- bytes form the backward digest Db; the next S_KEY_LEN bytes form Kf, and the
- final S_KEY_LEN bytes form Kb. Excess bytes from K are discarded.
- Subsequently, the rendezvous point passes relay cells, unchanged, from each
- of the two circuits to the other. When Alice's OP sends RELAY cells along
- the circuit, it authenticates with Df, and encrypts them with the Kf, then
- with all of the keys for the ORs in Alice's side of the circuit; and when
- Alice's OP receives RELAY cells from the circuit, it decrypts them with the
- keys for the ORs in Alice's side of the circuit, then decrypts them with Kb,
- and checks integrity with Db. Bob's OP does the same, with Kf and Kb
- interchanged.
- [TODO: Should we encrypt HANDSHAKE_INFO as we did INTRODUCE2
- contents? It's not necessary, but it could be wise. Similarly, we
- should make it extensible.]
- 4.3. Using legacy hosts as rendezvous points
- The behavior of ESTABLISH_RENDEZVOUS is unchanged from older versions
- of this protocol, except that relays should now ignore unexpected
- bytes at the end.
- Old versions of Tor required that RENDEZVOUS cell payloads be exactly
- 168 bytes long. All shorter rendezvous payloads should be padded to
- this length with random bytes, to make them difficult to distinguish from
- older protocols at the rendezvous point.
- Relays older than 0.2.9.1 should not be used for rendezvous points by next
- generation onion services because they enforce too-strict length checks to
- rendezvous cells. Hence the "HSRend" protocol from proposal#264 should be
- used to select relays for rendezvous points.
- 5. Encrypting data between client and host
- A successfully completed handshake, as embedded in the
- INTRODUCE/RENDEZVOUS cells, gives the client and hidden service host
- a shared set of keys Kf, Kb, Df, Db, which they use for sending
- end-to-end traffic encryption and authentication as in the regular
- Tor relay encryption protocol, applying encryption with these keys
- before other encryption, and decrypting with these keys before other
- decryption. The client encrypts with Kf and decrypts with Kb; the
- service host does the opposite.
- 6. Encoding onion addresses [ONIONADDRESS]
- The onion address of a hidden service includes its identity public key, a
- version field and a basic checksum. All this information is then base32
- encoded as shown below:
- onion_address = base32(PUBKEY | CHECKSUM | VERSION) + ".onion"
- CHECKSUM = H(".onion checksum" | PUBKEY | VERSION)[:2]
- where:
- - PUBKEY is the 32 bytes ed25519 master pubkey of the hidden service.
- - VERSION is an one byte version field (default value '\x03')
- - ".onion checksum" is a constant string
- - CHECKSUM is truncated to two bytes before inserting it in onion_address
- Here are a few example addresses:
- pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion
- sp3k262uwy4r2k3ycr5awluarykdpag6a7y33jxop4cs2lu5uz5sseqd.onion
- xa4r2iadxm55fbnqgwwi5mymqdcofiu3w6rpbtqn7b2dyn7mgwj64jyd.onion
- For more information about this encoding, please see our discussion thread
- at [ONIONADDRESS-REFS].
- 7. Open Questions:
- Scaling hidden services is hard. There are on-going discussions that
- you might be able to help with. See [SCALING-REFS].
- How can we improve the HSDir unpredictability design proposed in
- [SHAREDRANDOM]? See [SHAREDRANDOM-REFS] for discussion.
- How can hidden service addresses become memorable while retaining
- their self-authenticating and decentralized nature? See
- [HUMANE-HSADDRESSES-REFS] for some proposals; many more are possible.
- Hidden Services are pretty slow. Both because of the lengthy setup
- procedure and because the final circuit has 6 hops. How can we make
- the Hidden Service protocol faster? See [PERFORMANCE-REFS] for some
- suggestions.
- References:
- [KEYBLIND-REFS]:
- https://trac.torproject.org/projects/tor/ticket/8106
- https://lists.torproject.org/pipermail/tor-dev/2012-September/004026.html
- [KEYBLIND-PROOF]:
- https://lists.torproject.org/pipermail/tor-dev/2013-December/005943.html
- [SHAREDRANDOM-REFS]:
- https://gitweb.torproject.org/torspec.git/tree/proposals/250-commit-reveal-consensus.txt
- https://trac.torproject.org/projects/tor/ticket/8244
- [SCALING-REFS]:
- https://lists.torproject.org/pipermail/tor-dev/2013-October/005556.html
- [HUMANE-HSADDRESSES-REFS]:
- https://gitweb.torproject.org/torspec.git/blob/HEAD:/proposals/ideas/xxx-onion-nyms.txt
- http://archives.seul.org/or/dev/Dec-2011/msg00034.html
- [PERFORMANCE-REFS]:
- "Improving Efficiency and Simplicity of Tor circuit
- establishment and hidden services" by Overlier, L., and
- P. Syverson
- [TODO: Need more here! Do we have any? :( ]
- [ATTACK-REFS]:
- "Trawling for Tor Hidden Services: Detection, Measurement,
- Deanonymization" by Alex Biryukov, Ivan Pustogarov,
- Ralf-Philipp Weinmann
- "Locating Hidden Servers" by Lasse Øverlier and Paul
- Syverson
- [ED25519-REFS]:
- "High-speed high-security signatures" by Daniel
- J. Bernstein, Niels Duif, Tanja Lange, Peter Schwabe, and
- Bo-Yin Yang. http://cr.yp.to/papers.html#ed25519
- [ED25519-B-REF]:
- https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-5:
- [PRNG-REFS]:
- http://projectbullrun.org/dual-ec/ext-rand.html
- https://lists.torproject.org/pipermail/tor-dev/2015-November/009954.html
- [SRV-TP-REFS]:
- https://lists.torproject.org/pipermail/tor-dev/2016-April/010759.html
- [VANITY-REFS]:
- https://github.com/Yawning/horse25519
- [ONIONADDRESS-REFS]:
- https://lists.torproject.org/pipermail/tor-dev/2017-January/011816.html
- [TORSION-REFS]:
- https://lists.torproject.org/pipermail/tor-dev/2017-April/012164.html
- https://getmonero.org/2017/05/17/disclosure-of-a-major-bug-in-cryptonote-based-currencies.html
- Appendix A. Signature scheme with key blinding [KEYBLIND]
- A.1. Key derivation overview
- As described in [IMD:DIST] and [SUBCRED] above, we require a "key
- blinding" system that works (roughly) as follows:
- There is a master keypair (sk, pk).
- Given the keypair and a nonce n, there is a derivation function
- that gives a new blinded keypair (sk_n, pk_n). This keypair can
- be used for signing.
- Given only the public key and the nonce, there is a function
- that gives pk_n.
- Without knowing pk, it is not possible to derive pk_n; without
- knowing sk, it is not possible to derive sk_n.
- It's possible to check that a signature was made with sk_n while
- knowing only pk_n.
- Someone who sees a large number of blinded public keys and
- signatures made using those public keys can't tell which
- signatures and which blinded keys were derived from the same
- master keypair.
- You can't forge signatures.
- [TODO: Insert a more rigorous definition and better references.]
- A.2. Tor's key derivation scheme
- We propose the following scheme for key blinding, based on Ed25519.
- (This is an ECC group, so remember that scalar multiplication is the
- trapdoor function, and it's defined in terms of iterated point
- addition. See the Ed25519 paper [Reference ED25519-REFS] for a fairly
- clear writeup.)
- Let B be the ed25519 basepoint as found in section 5 of [ED25519-B-REF]:
- B = (15112221349535400772501151409588531511454012693041857206046113283949847762202,
- 46316835694926478169428394003475163141307993866256225615783033603165251855960)
- Assume B has prime order l, so lB=0. Let a master keypair be written as
- (a,A), where a is the private key and A is the public key (A=aB).
- To derive the key for a nonce N and an optional secret s, compute the
- blinding factor like this:
- h = H(BLIND_STRING | A | s | B | N)
- BLIND_STRING = "Derive temporary signing key" | INT_1(0)
- N = "key-blind" | INT_8(period-number) | INT_8(period_length)
- B = "(1511[...]2202, 4631[...]5960)"
- then clamp the blinding factor 'h' according to the ed25519 spec:
- h[0] &= 248;
- h[31] &= 63;
- h[31] |= 64;
- and do the key derivation as follows:
- private key for the period:
- a' = h a mod l
- RH' = SHA-512(RH_BLIND_STRING | RH)[:32]
- RH_BLIND_STRING = "Derive temporary signing key hash input"
- public key for the period:
- A' = h A = (ha)B
- Generating a signature of M: given a deterministic random-looking r
- (see EdDSA paper), take R=rB, S=r+hash(R,A',M)ah mod l. Send signature
- (R,S) and public key A'.
- Verifying the signature: Check whether SB = R+hash(R,A',M)A'.
- (If the signature is valid,
- SB = (r + hash(R,A',M)ah)B
- = rB + (hash(R,A',M)ah)B
- = R + hash(R,A',M)A' )
- This boils down to regular Ed25519 with key pair (a', A').
- See [KEYBLIND-REFS] for an extensive discussion on this scheme and
- possible alternatives. Also, see [KEYBLIND-PROOF] for a security
- proof of this scheme.
- Appendix B. Selecting nodes [PICKNODES]
- Picking introduction points
- Picking rendezvous points
- Building paths
- Reusing circuits
- (TODO: This needs a writeup)
- Appendix C. Recommendations for searching for vanity .onions [VANITY]
- EDITORIAL NOTE: The author thinks that it's silly to brute-force the
- keyspace for a key that, when base-32 encoded, spells out the name of
- your website. It also feels a bit dangerous to me. If you train your
- users to connect to
- llamanymityx4fi3l6x2gyzmtmgxjyqyorj9qsb5r543izcwymle.onion
- I worry that you're making it easier for somebody to trick them into
- connecting to
- llamanymityb4sqi0ta0tsw6uovyhwlezkcrmczeuzdvfauuemle.onion
- Nevertheless, people are probably going to try to do this, so here's a
- decent algorithm to use.
- To search for a public key with some criterion X:
- Generate a random (sk,pk) pair.
- While pk does not satisfy X:
- Add the number 8 to sk
- Add the point 8*B to pk
- Return sk, pk.
- We add 8 and 8*B, rather than 1 and B, so that sk is always a valid
- Curve25519 private key, with the lowest 3 bits equal to 0.
- This algorithm is safe [source: djb, personal communication] [TODO:
- Make sure I understood correctly!] so long as only the final (sk,pk)
- pair is used, and all previous values are discarded.
- To parallelize this algorithm, start with an independent (sk,pk) pair
- generated for each independent thread, and let each search proceed
- independently.
- See [VANITY-REFS] for a reference implementation of this vanity .onion
- search scheme.
- Appendix D. Numeric values reserved in this document
- [TODO: collect all the lists of commands and values mentioned above]
- Appendix E. Reserved numbers
- We reserve these certificate type values for Ed25519 certificates:
- [08] short-term descriptor signing key, signed with blinded
- public key. (Section 2.4)
- [09] intro point authentication key, cross-certifying the descriptor
- signing key. (Section 2.5)
- [0B] ed25519 key derived from the curve25519 intro point encryption key,
- cross-certifying the descriptor signing key. (Section 2.5)
- Note: The value "0A" is skipped because it's reserved for the onion key
- cross-certifying ntor identity key from proposal 228.
- Appendix F. Hidden service directory format [HIDSERVDIR-FORMAT]
- This appendix section specifies the contents of the HiddenServiceDir directory:
- - "hostname" [FILE]
- This file contains the onion address of the onion service.
- - "private_key_ed25519" [FILE]
- This file contains the private master ed25519 key of the onion service.
- [TODO: Offline keys]
- - "./authorized_clients/" [DIRECTORY]
- "./authorized_clients/alice.auth" [FILE]
- "./authorized_clients/bob.auth" [FILE]
- "./authorized_clients/charlie.auth" [FILE]
- If client authorization is enabled, this directory MUST contain a ".auth"
- file for each authorized client. Each such file contains the public key of
- the respective client. The files are transmitted to the service operator by
- the client.
- See section [CLIENT-AUTH-MGMT] for more details and the format of the client file.
- (NOTE: client authorization is not implemented as of 0.3.2.1-alpha.)
- Appendix G. 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. Please see appendix
- [HIDSERVDIR-FORMAT] for more information about relevant hidden service files.
- (NOTE: client authorization is not implemented as of 0.3.2.1-alpha.)
- G.1. Configuring client authorization using torrc
- G.1.1. Hidden Service side configuration
- A hidden service that wants to enable client authorization, needs to
- populate the "authorized_clients/" directory of its HiddenServiceDir
- directory with the ".auth" files of its authorized clients.
- When Tor starts up with a configured onion service, Tor checks its
- <HiddenServiceDir>/authorized_clients/ directory for ".auth" files, and if
- any recognized and parseable such files are found, then client
- authorization becomes activated for that service.
- G.1.2. Service-side bookkeeping
- This section contains more details on how onion services should be keeping
- track of their client ".auth" files.
- For the "descriptor" authentication type, the ".auth" file MUST contain
- the x25519 public key of that client. Here is a suggested file format:
- <auth-type>:<key-type>:<base32-encoded-public-key>
- Here is an an example:
- descriptor:x25519:OM7TGIVRYMY6PFX6GAC6ATRTA5U6WW6U7A4ZNHQDI6OVL52XVV2Q
- Tor SHOULD ignore lines it does not recognize.
- Tor SHOULD ignore files that don't use the ".auth" suffix.
- G.1.3. Client side configuration
- A client who wants to register client authorization data for onion
- services needs to add the following line to their torrc to indicate the
- directory which hosts ".auth_private" files containing client-side
- credentials for onion services:
- ClientOnionAuthDir <DIR>
- The <DIR> contains a file with the suffix ".auth_private" for each onion
- service the client is authorized with. Tor should scan the directory for
- ".auth_private" files to find which onion services require client
- authorization from this client.
- For the "descriptor" auth-type, a ".auth_private" file contains the
- private x25519 key:
- <onion-address>:descriptor:x25519:<base32-encoded-privkey>
- The keypair used for client authorization is created by a third party tool
- for which the public key needs to be transferred to the service operator
- in a secure out-of-band way. The third party tool SHOULD add appropriate
- headers to the private key file to ensure that users won't accidentally
- give out their private key.
- G.2. Configuring client authorization using the control port
- G.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.
- G.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?]
- Appendix F. Two methods for managing revision counters.
- Implementations MAY generate revision counters in any way they please,
- so long as they are monotonically increasing over the lifetime of each
- blinded public key. But to avoid fingerprinting, implementors SHOULD
- choose a strategy also used by other Tor implementations. Here we
- describe two, and additionally list some strategies that implementors
- should NOT use.
- F.1. Increment-on-generation
- This is the simplest strategy, and the one used by Tor through at
- least version 0.3.4.0-alpha.
- Whenever using a new blinded key, the service records the
- highest revision counter it has used with that key. When generating
- a descriptor, the service uses the smallest non-negative number
- higher than any number it has already used.
- In other words, the revision counters under this system start fresh
- with each blinded key as 0, 1, 2, 3, and so on.
- F.2. Encrypted time in period
- This scheme is what we recommend for situations when multiple
- service instances need to coordinate their revision counters,
- without an actual coordination mechanism.
- Let T be the number of seconds that have elapsed since the descriptor
- became valid, plus 1. (T must be at least 1.) Implementations can use the
- number of seconds since the start time of the shared random protocol run
- that corresponds to this descriptor.
- Let S be a secret that all the service providers share. For
- example, it could be the private signing key corresponding to the
- current blinded key.
- Let K be an AES-256 key, generated as
- K = H("rev-counter-generation" | S)
- Use K, and AES in counter mode with IV=0, to generate a stream of T
- * 2 bytes. Consider these bytes as a sequence of T 16-bit
- little-endian words. Add these words.
- Let the sum of these words be the revision counter.
- Cryptowiki attributes roughly this scheme to G. Bebek in:
- G. Bebek. Anti-tamper database research: Inference control
- techniques. Technical Report EECS 433 Final Report, Case
- Western Reserve University, November 2002.
- Although we believe it is suitable for use in this application, it
- is not a perfect order-preserving encryption algorithm (and all
- order-preserving encryption has weaknesses). Please think twice
- before using it for anything else.
- (This scheme can be optimized pretty easily by caching the encryption of
- X*1, X*2, X*3, etc for some well chosen X.)
- For a slow reference implementation, see src/test/ope_ref.py in the
- Tor source repository. [XXXX for now, see the same file in Nick's
- "ope_hax" branch -- it isn't merged yet.]
- This scheme is not currently implemented in Tor.
- F.X. Some revision-counter strategies to avoid
- Though it might be tempting, implementations SHOULD NOT use the
- current time or the current time within the period directly as their
- revision counter -- doing so leaks their view of the current time,
- which can be used to link the onion service to other services run on
- the same host.
- Similarly, implementations SHOULD NOT let the revision counter
- increase forever without resetting it -- doing so links the service
- across changes in the blinded public key.
|