Tom van der Woerdt info@tvdw.eu writes:
Op 04/10/15 om 06:46 schreef Tim Wilson-Brown - teor:
On 3 Oct 2015, at 13:34, Tom van der Woerdt <info@tvdw.eu mailto:info@tvdw.eu> wrote: ... 3. Compatibility and security
The implementation of these methods should, ideally, not change anything in the network, and all control changes are opt-in, so this proposal is fully backwards compatible.
Controllers handling this data must be careful to not leak rendezvous data to untrusted parties, as it could be used to intercept and manipulate hidden services traffic.
After thinking through this, I wonder if the rendezvous data should contain the decrypted cell, rather than the introduction point key and the encrypted cell. That way, if an INTRODUCE event is exposed, only the one rendezvous referred to by the event is vulnerable. (Exposure of the introduction point key means that all introductions from that point are vulnerable until it is rotated, however, there are other layers of encryption protecting the INTRODUCE2 cells [but we shouldn’t rely on these, because we want defence-in-depth].)
This is also slightly more efficient, as we are transmitting less data in the INTRODUCE event.
The drawback of this change is that decryption places slightly more load on the tor instance that receives the INTRODUCE2 cell.
I don't have a particular opinion on which to pick. The proposal leaves this decision up to the implementation for exactly that reason.
There are several things to consider that I can think of:
- If the crypto is done on the rendezvous side, HSes could potentially scale
better and be more resistant to DoSes;
- With up to 60 introduction points (= processes) made possible by
OnionBalance, the perf difference may not matter any time soon, and 224 should make HSes perform better anyway;
- If the crypto is done on the introduction side, DH replays could be detected
better, which may be good against DoSes;
- The controller is considered trusted, and connections between the controllers
needed for this proposal can be encrypted;
- The overhead of constantly adding the same key into the events can largely be
negated by using a fast compression algorithm such as Snappy -- although I don't think that these introduce events will ever become a bottleneck.
Tom
PS: So far this thread has been between Tim and myself... Does anyone else have an opinion? ;-)
Hello,
I really like this proposal!
I don't have a strong opinion on whether the decryption should happen on the master or on the slaves (need better terminology here).
Some thoughts:
==== Security =====
With regards to security, both proposals seem almost the same thing.
That is if decryption happens on the slaves as originally proposed, and the attacker is MITMing the master <-> slaves control channel and is able to snatch the introduction key, then yes she can decrypt all future encrypted introductions from that IP.
On the alternative design where decryption happens on the master, the adversary who MITMs the control channel can just read the introductions trivially since they are already decrypted.
It seems to me that in both cases the adversary wins equally if she is able to MITM the control channel, which seems to be what needs to be protected here if we even care about these attacks.
Finally, what's the deal with the replay caches here? Can the replay check be done on the master if we do the "decrypt at slaves" design? IIRC the replaycache stores the decrypted data, so probably not. Is this a big problem? The proposal does not seem to be mentioning it. We probably don't want to do replay protection on the slaves, since that might leak the number of slaves we have.
==== Performance ====
Now, with regards to performance, it indeed seems slightly faster to decrypt on the slaves. However as you said, with onionbalance enabled, the operator can have multiple master nodes, which should make this not that big of a deal.
==== Simplicity ====
In general, the "decryption at slaves" design requires you to pass encrypted blobs around. I think this is suboptimal for backwards/future compatibility especially without a version field.
If we end up going with this design, I'd prefer if the blob is specified a bit more. Maybe like Nick suggested here: https://trac.torproject.org/projects/tor/ticket/17254#comment:8
==== Usefuleness ====
As I've mentioned before, if we end up going with the "decryption at master" design, we can also use this proposal to implement the "rendezvous approver" functionality of #16059, which would be quite useful under DoS scenarios.
This could look like this:
IP_1 \ /-- rend_slave_1 \ /--- rend_slave_2 IP_2 ---> HS master -> rendezvous approver -> /---- rend_slave_3 / ---- rend_slave_4 IP_3 / --- rend_slave_5 -- rend_slave_6
The "rendezvous approver" can also be implemented with the "decryption at slave" design, but the approver will need to be attached to every rendezvous slave.
====
In any case I like this proposal regardless of which design decision we choose in the end.
If I were to chose right now, I'd probably pick the "decrypt at master" design decision, since it seems to be slightly better for security (replay cache), and also a bit simpler (no reason to pass any encrypted blobs anymore), as well as allowing the "rendezvous approver" functionality.
Thanks for the proposal!