Trivial birthday attacks against HMAC

I ran a poll on Twitter, asking "Is HMAC vulnerable to birthday attacks?". There are 34 votes, 26% said "Yes", 27% "I don't care", and 47% "No". Thomas Pornin, a respected crypto engineer, chose no.

In this post I'll describe two trivial birthday attacks against HMAC. The first one is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365oretical, but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 second one is more practical and security-relevant.

Existential forgery attack

Suppose we have access to a HMAC-HASH signing oracle. HASH can be MD5, SHA1, SHA256, etc. The oracle has a secret key $K$, and when we send it a message $m$, it'll return $\textit{HMAC}(K, m)$.

If we query cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 oracle for $2^{n/2}$ messages, where $n$ is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 length of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 output of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hash function, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 birthday paradox says that we will likely get a collision. That means we get $m_1 \neq m_2$ such that $\textit{HMAC-HASH}(K, m_1) = \textit{HMAC-HASH}(K, m_2)$.

When this happens, and suppose that $m_1$ and $m_2$ have cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same length, we can query cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 oracle for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 tag of $m_1 \;||\; x$ where $x$ is an arbitrary message, and with high probability cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 returned value is also cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 tag of $m_2 \;||\; x$.

In ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r words, if

$\textit{HMAC-HASH}(K, m_1) = \textit{HMAC-HASH}(K, m_2)$

cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n it's likely that

$\textit{HMAC-HASH}(K, m_1 \;||\; X) = \textit{HMAC-HASH}(K, m_2  \;||\; X)$.

Thus we have successfully forged a signature for $m_2  \;||\;  X$ with half of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cost of a serialized brute force search.

Of course this attack is purely cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365oretical. For example, with HMAC-MD5 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack requires $2^{64}$ oracle queries, and $2^{71}$ bits of memory. Nevercá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365less, it's still a proof that HMAC is not safe against birthday attacks.

Two important notes before we consider cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 second attack:

- Truncating HMAC tags doesn't reduce cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cost of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 birthday attack. The running time of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack is still O($2^{n/2}$). On cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r hand if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 tag is truncated too much, just randomly guessing it might have a decent chance of success (if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 tag is $n$ bits, each random n-bit string has $2^{-n}$ chance of being correct).

- A collision in HASH doesn't necessarily lead to a forgery in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 HMAC-HASH function. With $m_1$ and $m_2$ such that MD5($m_1$) == MD5($m_2$), it's not guaranteed that $\textit{HMAC-MD5}(K, m_1)$ is equal to $\textit{HMAC-MD5}(K, m_2)$. This is because $K$ already changes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 initial state of MD5 by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 time it starts processing $m_1$ or $m_2$. All known MD5 or SHA1 collision attacks require knowing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 initial state, but $k$ is unknown, thus cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se attacks won't work against HMAC-MD5 or HMAC-SHA1.

Duplicate signature attack

(Dan Kaminsky wrote about this attack last year: http://dankaminsky.com/2015/05/07/cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365-little-mac-attack/. See also this thread on Hacker News: https://news.ycombinator.com/item?id=9533984)

Let's take a look at how HMAC is defined:
$\textit{HMAC-HASH}(K, m) = \textit{HASH} \Bigl( (K \oplus opad) \;||\; \textit{HASH} \bigl( (K \oplus ipad) \;||\; m \bigr) \Bigr)$,

where opad and ipad are padding constants. If we have a collision in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 inner hash $\textit{HASH} \bigl( (K \oplus ipad) \;||\; m \bigr)$, we are guaranteed to have a collision in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 outer hash and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 whole HMAC-HASH function. That means if we know $K$, and we can find $m_1$ and $m_2$ such that $\textit{HASH} \bigl( (K \oplus ipad) \;||\; m_1 \bigr) = \textit{HASH} \bigl( (K \oplus ipad) \;||\; m_2 \bigr)$, we will obtain $\textit{HMAC-HASH}(K, m_1) = \textit{HMAC-HASH}(K, m_2)$.

This is not a forgery attack, because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker must know cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 key. It is called duplicate signature attack in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 literature, as it produces two messages having cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same tag. It is more security-relevant that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first attack.

I once looked at a server that:
- accepts a signed command from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 requester
- verifies cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 signature
- validates cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 command
- finally executes it.

Because command validation is expensive, once cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 command is validated, its signature is added to a cache. For every new command cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system just needs to verify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 signature, and checks if it is in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cache, and if so, runs it, without having to validate it again. This system is thus vulnerable to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 duplicate signature attack. An adversary can generate two commands having cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same signature, one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m is benign, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r malicious. They send cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 benign command first so that its signature is added to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cache. Then cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y send cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 malicious command, which bypasses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 validation because its signature is already in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cache. The root cause of this bug is that HMAC is a pseudorandom function (PRF), it should not be used as a pseudorandom permutation (PRP) (more on PRP vs PRF).

This second attack is much easier to exploit than cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first one. We just need to generate a collision in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hash function, and we can do that offline (without having to query any oracle). Again cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 birthday paradox tells us that we need to generate only $2^{n/2}$ messages before hitting a collision. The problem is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory cost. Storing $2^{n/2}$ messages is a big deal. Fortunately cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is an algorithm that reduces not only cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory cost, but also cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 running time. This algorithm is described in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 classic paper "Parallel collision search with cryptanalytic applications" by van Oorschot and Wiener.

The core idea is similar to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mining process in Bitcoin. Each CPU independently searches for a "distinguished point", e.g., cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first 32 bits are all zero, by iterating a function $f$ and producing a trail. When a distinguished point is found, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CPU reports a triple consisting of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 starting point, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 number of iterations, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 distinguished point to a centralized server. The CPU cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n picks anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r starting point, and searches for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next distinguished point. As cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is no communication or synchronization between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CPUs, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 algorithm is perfectly parallelized, which in turn vastly reduces cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 running time. After cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CPUs have run for a while, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 central server will sort cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 distinguished points and find collisions. If it founds a collision, that means two trails produced by two CPUs collided and merged with each ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r at some point. Right before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 trail collision, we will find two values $a$ and $b$ such that $f(a) = f(b)$.

$f(x_2) = f(x_{1'})$. Picture stolen from "Parallel collision search with cryptanalytic applications".
Suppose that we are attacking HMAC-SHA1.

Suppose that we have a machine with $2^{40}$ SHA1 circuits, and we feed each of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m a random starting point, and let cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m work in parallel to find distinguished points which start with 40 zero bits. The machine can compute $2^{80}$ hashes in time of only $2^{40}$ SHA1 computations. See "Understanding brute force" by Dan Bernstein for how such a machine can be built.

The central server has to store cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 distinguished points, thus it needs some memory. Let's say that it has 128 GB of memory. It has to store many aforementioned triples. Because we're going to produce $2^{40}$ trails, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 starting point can be represented with 5 bytes. The distinguished point can be represented with 16 bytes because a SHA1 hash value is 20 bytes long, and distinguished points have at least 4 leading zero bytes which need not be stored. The number of steps can be represented with 6 bytes, because $2^{48}$ is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 maximum number of iterations before we abandon a trail (e.g., it has a cycle). Overall, a triple requires 27 bytes. Thus with 128 GB of memory we can store around $4,74 * 10^9$ said triples.

Since it takes on average $2^{40}$ iterations before a trail reaches a distinguished point, by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 time cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 central server is nearly full, we have computed on average $2^{40} * 4,92 * 10^9 \approx 2^{72}$ SHA1 hashes. This should give us (approximately) a $2^{-17}$ chance of having a collision. If we run cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 machine again and again, each run takes slightly more time than $2^{40}$ SHA1 computations, we'll increase cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 chance of hitting a collision to pretty close to 1.

As noted by van Oorschot and Wiener, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 run time of this attack is proportional to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 square root of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hash result space. Thus if this attack were applied to SHA256, it would be $2^{48}$ times slower.

Three conclusions:
- There are birthday attacks that work well against HMAC.
- Birthday attacks can usually be parallelized.
- Use HMAC-SHA256 when you can.

Comments

rnystery said…
This comment has been removed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 author.