Full Report
In Cryptography a nonce (number used only once) is an important part of any encryption or signature algorithm. It's a big deal to not reuse nonces in cryptography but they are allowed to be public most of the time. When done incorrectly, it can be used to reveal secrets in encrypted messages or even recover the crypto key in the case of DSA. The article talks about why the reuse of nonces is so bad. Encrypted channels work by changing the content of a message to be effectively random noise and then decoded on the other end. Going back to old ciphers from the 1500s, the mechanism was to sub in a given symbol with another mapped symbol. This could be done in the opposite direction to decrypt it. The security of this relies on the third parties (Evil Eve) not being able to infer information about the symbol-substitution procedure when looking at the encrypted data. Many ciphers were broken by observing patterns within the individual encrypted messages, such as the Banburismus technique used to break the Enigma machine. To prevent his from happening, instead of having a single symbol to map to modern ciphers have 128 or 256-bit block sizeS. Additionally, there are rules in place to ensure to create a good substitution table for every symbol or block in this case. The first part shows the classic Linux tux penguin being encrypted using ECB mode. Even though it's encrypted, you can still see Tux in the image! This is because blocks with the same data will produce the same output. To prevent this from happening, we introduce a nonce. AES-CTR and ChaCha20 are both encryption modes that use an incrementing value as the nonce. When using the same noise (nonce) with two images, XORing the values together will produce the plaintext. If you ever reuse a nonce, an attacker who sees two encrypted messages can learn the XOR of the plaintext. If nonces aren't reused between different messages, then it's impossible to recover the original data. AES Ctr mode is weird - it encrypts the nonce then XORs that with the plaintext. This is why this is possible. Recently, when auditing a protocol, they found an issue relating to this where Alice, Bob and Carol were the actors in a peer-to-peer communication model. After doing a secret sharing algorithm via asymmetric cryptography, they generate a key for ChaCha20 to use. When the algorithm is initialized, they all start with a nonce of zero. As a result, if an attacker can sniff the message going from Alice to Bob then another from Bob to Alice with the same key and nonce, they can XOR the encrypted data together to recover the original! The important fields that are XORed are pseudorandom so it's not possible to learn all of their contents. The nonce reuse did allow them to leak the MAC key and an MitM could have been done to modify messages in transit. The major difference can be seen on Tux and Betsy on why they couldn't get the message. Notice that the image was not perfectly recovered. These images were perfect because of the large amount of white and black on them, making them easy for overlaps. In the real world, if the numbers are random, you won't be able to see anything because the XORs will appear random. Overall, I enjoyed the post and the visuals from it!
Analysis Summary
# Vulnerability: Nonce Reuse in Peer-to-Peer Threshold Signature Scheme
## CVE Details
* **CVE ID:** Not provided (Discovery by Trail of Bits during a private audit).
* **CVSS Score:** N/A (Estimated High severity based on cryptographic failure).
* **CWE:** [CWE-323: Reusing a Nonce, Key Pair in Encryption](https://cwe.mitre.org/data/definitions/323.html).
## Affected Systems
* **Products:** A client’s implementation of a threshold signature scheme.
* **Versions:** Not specified (Proprietary/Audited code).
* **Configurations:** Peer-to-peer (P2P) communication models where multiple parties (e.g., Alice, Bob, and Carol) share a single encryption key and use a synchronized, but non-directional, global nonce counter.
## Vulnerability Description
The vulnerability arises from an incorrect implementation of a "counter-mode" stream cipher (such as ChaCha20). While the developers adhered to the rule of not reusing a nonce for a *single* sender, they failed to account for bidirectional collisions.
After performing a secret sharing algorithm through asymmetric cryptography, the parties generated a single shared key for ChaCha20. All parties initialized their nonce counter to zero. Consequently, when Alice sent a message to Bob, and Bob sent a message back to Alice using the same key, both utilized the same initial nonce. In counter-mode ciphers, reusing a nonce with the same key generates identical keystreams.
## Exploitation
* **Status:** PoC described; identified during security audit.
* **Complexity:** Medium (Requires sniffing network traffic between two peers).
* **Attack Vector:** Network (Adjacency or MitM).
An attacker observing two messages ($C_1$ and $C_2$) encrypted with the same key ($K$) and same nonce ($N$) can XOR the ciphertexts together. This cancels out the keystream, leaving the XOR of the two original plaintexts ($P_1 \oplus P_2$).
## Impact
* **Confidentiality:** High. Reusing nonces allows for the recovery of original data via XOR analysis. In this specific audit, it resulted in the leaking of **MAC keys**.
* **Integrity:** High. The leakage of authentication secrets allows a Man-in-the-Middle (MitM) attacker to modify messages in transit without detection.
* **Availability:** Low (not the primary focus of this flaw).
## Remediation
### Patches
* **Directional Keys:** Implement separate keys for each communication direction (e.g., $Key_{A\to B}$ and $Key_{B\to A}$). This ensures that even if nonces match, the resulting keystreams differ.
* **Noise Protocol Framework:** Adopting the Noise Protocol Framework is recommended, as it natively handles CipherState objects for sending and receiving independently.
### Workarounds
* **Nonce Partitioning:** If a single key must be used, partition the nonce space. For example, assign one party to use only even numbers and the other to use only odd numbers (Note: This reduces the effective entropy of the nonce).
## Detection
* **Indicators of Compromise:** Difficult to detect via standard logs as it is a cryptographic design flaw.
* **Detection Methods:**
* **Static Analysis:** Auditing code for shared state/keys across bidirectional channels.
* **Traffic Analysis:** Monitoring for repeated Initialization Vectors (IVs) or nonces within the same session across different senders.
## References
* [Trail of Bits Blog: Friends don’t let friends reuse IVs](https://blog.trailofbits.com/2024/09/13/friends-dont-let-friends-reuse-ivs/)
* [Noise Protocol Framework](https://noiseprotocol.org/noise.html)