Prerequisites:
- Finite Fields
- AES-GCM
In this section, we will discuss an attack on AES-GCM due to reusage of nonce during encryption process. The attack can reveal value of H
which can then help the attacker to forge authentication tag T
.
We will be using the same symbols as we did while discussing the internals of AES-GCM
In this section, we will see polynomial representation of authentication tag generation.
We know that the tag is generated using a series of multiplication over finite field GF(2256) and GF(2**256) is an Extension Field.
There are broadly two categories of Finite Fields: Prime Fields and Extension Fields. Prime Fields are of the form GF(p) where p
is a prime number and consist of integers in {0,..., p}. Extension fields are of the form GF(pm), where p
is a prime number and m
is a positive integer and consist of polynomials of the form
am-1xm-1 + am-2xm-2 + ... + a1x + a0
Here, a
can assume values in {0,..., p-1}
GF(2m) is one of the most frequently used fields in cryptography. Since multiplication in AES-GCM happens over Finite Field GF(2256) (Extension Field), elements of this Finite Field are polynomials.
Hence, all the computation discussed in authtag generation process of AES-GCM is over polynomials (The function mod_polynomial_mult(self, a, b, p)
in authtag process is an implementation of multiplication of two polynomials a
and b
modulo an irreducible polynomial f = 1 + x + x<sup>2</sup> + x<sup>7</sup> + x<sup>128</sup>
over GF(2256)).
We will discuss a trivial case scenario in encryption and authtag generation part of AES-GCM, and then derive the generalised polynomial that can be used to generate authentication tag.
Note: Polynomial Addition over a Finite Field GF(2m) is equivalent to XOR operation over integers.
Case Scenario-1: Alice (sender) wants to use AES-GCM to encrypt one block of plaintext (16 bytes) and generate authentication tag for one block of associated data and one block of ciphertext corresponding to the one block of plaintext.
Authentication Tag in this case can be written as:
g(X) = ((A1X + C1)X + L)X + S
where L is len(A) || len(C), S is Ek(J0) and X is the authentication key. The above polynomial is equal to:
g(X) = A1X3 + C1X2 + LX + S
Case Scenario-2: Alice (sender) wants to use AES-GCM to encrypt two blocks of plaintext (32 bytes) and generate authentication tag for two blocks of associated data and two blocks of ciphertext corresponding to two blocks of plaintext.
Authentication Tag in this case can be written as:
((((A1X + A2)X + C1)X + C2)X + L)X + S
This is equal to:
A1X5 + A2X4 + C1X3 + C2X2 + LX + S
Generalised polynomial: We can now define polynomial for generation of authentication tag with m
blocks of associated data and n
blocks of plaintext:
g(X) = A1Xm+n+1 + ... + AmXn+2 + C1Xn+1 + ... + CnX2 + LX + S
where L is len(A) || len(C), S is Ek(J0) and X is the authentication key. Also, when X=H, g(H) = T (T is the authentication tag generated in AES-GCM)
Now that we have derived polynomial expression for authentication tag generation in AES-GCM, let us see how the Forbidden Attack works!
For simplicity of understanding, consider a scenario where Alice (sender) sends two messages containing one block of plaintext (16 bytes) each (no associated data blocks) and generates authentication tag for ciphertext of each message using the same nonce. Our intention, as an attacker is to find out the value of H
that is the authentication key.
Note: An important condition for this attack to work is for nonce to be reused in generating ciphertext and authentication tag pair of two different messages.
We denote authentication tag polynomials for the two messages as g1(X) and g2(X). Each polynomial can be written as:
g1(X) = C1,1X2 + L1X + S
g2(X) = C2,1X2 + L2X + S
where C1,1 and C2,1 signify first block of ciphertext corresponding to the first message and first block of ciphertext corresponding to the second message respectively.
Note that S
and L
are same for both the polynomial expressions.
We know that L = len(A) || len(C)
, none of the messages have any associated data and both of them have same lengths of ciphertext = 16 bytes. Hence, L
is same for both polynomial expressions.
We also know that S = Ek(J0) and J0 contains Nonce. Since the two messages use same Nonce, we have same values of S
for the above polynomial expressions.
Also, we cannot solve any of the above polynomials separately and get the value of X. Why? Because we don't know the value of S = Ek(J0). If by any method we can eliminate S
from the expression, and equate the polynomial to zero, we can simply solve the quadratic equation and get the value of X
(authentication key). Let us now see how we can do that.
We know that g1(H) = T1 and g2(H) = T2, adding T1 on both sides of polynomial 1 and T2 on both sides of polynomial 2, we can write:
g'1(X) = C1,1X2 + L1X + S + T1
g'2(X) = C2,1X2 + L2X + S + T2
g'1(H) = g'2(H) = 0, (Since g(H) = T, g(H) + T over a Finite Field of the form GF(2m) will be equivalent to g(h) ^ T = 0). Now we add the two polynomials to get:
f(X) = (C1,1+C2,1)X2 + (L1 + L2)X + (T1 + T2)
We know that f(H) = 0, so we can easily solve the above quadratic equation to get all possible values of H
. The number of possible values of H
will be equal to the degree of the polynomial which, in turn, depends upon the number of plaintext and associated data blocks.
After we get the value of H
we can easily generate authentication tag for any message by calling the authtag_gen()
function from AES-GCM-implementation.py!