Skip to content

HSv3: First draft of HS Ntor implementation.

George Kadianakis requested to merge asn/arti:hsv3_ntor_dev into main

Here is a first draft of the HS ntor implementation.

I spent lots of time yesterday trying to come up with the right interface for this module and I feel like I was going in circles, so I decided to go with the basic approach so that I can show something, and we can revise together.

The problem here is that HS Ntor does not natively fit into the ClientHandshake and ServerHandshake model of That's because it does opportunistic encryption in the middle of the handshake. This creates two big problems:

a) The client1() and server() functions need to return back the plaintext after decrypting what the other side sent them. Right now the interface does not support that. We could achieve this by using associated types (and associating the HS Ntor handshake with additional return values), or by using the ugly client1_with_extra_data() approach which can be seen in my branch, and basically diverges from the path. We would also need to expand the inputs so that the client() gets the plaintext that needs to be encrypted.

b) The other (bigger?) problem I encountered is that in the middle of the handshake, the client is asked to MAC the entire introduction cell, and the service is asked to verify that MAC. This means that we would need to pass the client the entire introduction cell and same goes for the service. I started implementing that, but I started feeling that I was doing more and more Tor protocol stuff inside the HS NTor crate and that didn't feel natural. As the service, I basically had to decrypt the INTRODUCE1 ciphertext, then concatenate the result with the rest of the cell, and then verify the MAC of that. I was also fearing that all this logic would make unittesting harder, especially if we ever hope to use little-t-tor's tool to do integration tests.

Right now the code is taking the simplest approach out, which is to define new functions that don't adhere to the interface, and they return the minimal information required to finish the HS Ntor protocol. It's up to the caller to use the resulting keys properly, which is suboptimal. I don't yet know how the crate will be used as part of the async code, so I considered this to be a reasonable short-term approach until we understand more of the interface required.

Nick, I welcome any thoughts.

Merge request reports