diff --git a/web/how-it-works.html b/web/how-it-works.html index 6c4de39..81440a1 100644 --- a/web/how-it-works.html +++ b/web/how-it-works.html @@ -197,6 +197,46 @@
+ The encryption happens before anything becomes volume, so the carrier
+ never holds the readable text — it holds scrambled bytes. Here is the
+ journey of "hi" in passphrase mode:
+
"hi" is two bytes of ASCII:
+ 0x68 0x69.IV (12) +
+ ciphertext (2) + auth tag (16) =
+ 30 bytes. The ciphertext is the same length as the plaintext
+ (GCM is a stream mode) and looks like random noise: GCM XORs a key+IV
+ keystream into your bytes, turning 0x68 0x69 into two
+ unpredictable ones. Because the IV is random every time, sending
+ "hi" twice yields completely different ciphertext, so no
+ patterns leak.
+ By the time it is volume, the readable h,i is gone
+ three layers up. Someone reading the volume locally (the same-UID PulseAudio
+ attack this project documents) demodulates the amplitude back to bytes and gets
+ 30 bytes of random-looking ciphertext, not "hi". Without the
+ passphrase the encryption is irreversible, and the auth tag means tampering
+ fails outright — flip one bit and decryption rejects it.
+
+ And it is doubled up: that is the application layer (AES-GCM).
+ WebRTC independently wraps the whole audio stream in DTLS-SRTP,
+ so the carrier is encrypted again in transit. Two separate keys, two separate
+ layers — the readable "hi" exists only in RAM on the two
+ endpoints, never on the wire and never in the volume.
+
Protects against a network observer reading chat content. Does not protect against another process on either endpoint recording the local audio, or an @@ -227,8 +267,8 @@