- 
                Notifications
    You must be signed in to change notification settings 
- Fork 23
Registration Tagging and Signaling
In Dark Decoys we don't need to decrypt the original flow, and station engineers agree that if we have a chance not to import OpenSSL, then we should not import OpenSSL. However, we used to have variable-length protobuf in a header of first HTTP request, which we don't want to decrypt anymore.
We do however need multiple cryptographic keys now. And we do want a variable-length sized protobuf in there for extensibility.
High-level decryption algorithm:
- extract shared_secret from Representative and generate encryption keys
- decrypt Fixed-Size Payload, which will contain size of Variable-Size Payload
- decrypt Variable-Size Payload
[     VSP    ][VSP GMAC][Representative][ FSP  ][ FSP GMAC ][ Suffix ]
 \ variable* /  \ 16* /   \ 32 bytes* /  \ 6* /  \   16*  /  \  4   /
* before base64-style encoding. Actual size on the wire will increase by 33%.
Same old stuff. Grab eligator-transformed representative of client's public key, combine it with station's private key, get 32 byte-long shared_secret.
Located at 92 bytes offset from the end. Calculations(from the end):
- [16 bytes] GMAC for the whole TLS record
- [4 bytes] suffix
- [16 bytes] GMAC from FSP encryption
- [6 bytes] FSP
- [32 bytes] representative
(32 + 6 + 16) / 3 * 4 + 4 + 16 = 92
Use HKDF to expand and extract with following parameters
- PRK = SHA256
- SECRET = shared_secret, derived from representative
- SALT = []byte{"tapdancetapdancetapdancetapdance"}
- INFO = nil
This gives us a Key Derivation Function, that is able to generate a stream, which we then use to derive multiple secure keys of any length:
- 
FSP_key= first 16 bytes from HKDF
- 
FSP_iv= next 12 bytes
- 
VSP_key= next 16 bytes
- 
VSP_iv= next 12 bytes
- 
new_master_secret= next 48 bytes
- 
DarkDecoy_seed= next 16 bytes
Encrypted with AES-128-GCM, using FSP_key and FSP_iv.
- size of encrypted VSP [2 bytes, BigEndian uint16] - MUST be divisible by 3
- flags [1 byte]
- Unassigned [3 bytes]
Contains ClientToStation protobuf.
4 bytes long.
Allows us to append \r\n\r\n at the end of the request to complete it. For incomplete requests, may be filled with anything in ASCII range.