hsv3: Support onionbalance keys when handling INTRO2 cells
We have encountered a small issue with onionbalance viability for v3s.
While the descriptor cross-certificates are no longer an issue (legacy/trac#29583 (moved)), there is an issue with the ntor handshake during the INTRODUCE1/INTRODUCE2 handshake between the client and service.
In particular, as specified in rend-spec-v3.txt [NTOR-WITH-EXTRA-DATA] the subcredential (which includes the onion address) is used as part of the ntor key material to generate end-to-end encryption keys and MAC keys so that the service can communicate with the client:
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]
The issue here is that when the client prepares the INTRO1 cell, it uses the subcredential of the frontend OBv3 service, but the INTRO2 cell actually goes to a backend OBv3 instance which has a different subcredential. This causes the backend instance to not be able to verify the MAC of the cell, and generally finish the ntor handshake....