-
Notifications
You must be signed in to change notification settings - Fork 21
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.