From 96a52a1030c1bb27619372c6cebb633e02017847 Mon Sep 17 00:00:00 2001 From: cyfraeviolae Date: Thu, 25 Aug 2022 02:16:03 -0400 Subject: data truncation truncation launch remove files --- aesgcmanalysis.py | 40 +++-- app.py | 43 ++++- templates/index.html | 13 +- templates/nonce-reuse.html | 87 ++++----- templates/nonce-truncation.html | 386 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 492 insertions(+), 77 deletions(-) create mode 100644 templates/nonce-truncation.html diff --git a/aesgcmanalysis.py b/aesgcmanalysis.py index abdfdb3..9e0d5b6 100644 --- a/aesgcmanalysis.py +++ b/aesgcmanalysis.py @@ -686,7 +686,8 @@ def find_b(n, basis, ct, mac, nonce, aad, oracle): base[j*16:(j+1)*16] = xor(base[j*16:(j+1)*16], block) idx += 1 -def compute_auth_key(ct, mac, nonce, mac_bytes, aad, oracle): +def nonce_truncation_recover_secrets(ct, mac, nonce, mac_bytes, aad, oracle): + orig_ct = ct ct = aad + ct n = compute_n(ct) assert n > (mac_bytes*8//2) @@ -716,11 +717,23 @@ def compute_auth_key(ct, mac, nonce, mac_bytes, aad, oracle): K = np.concatenate([K, incrK]) _, _, basisKerK = kernel(K, rref_mod_2) X = np.array(basisKerK).transpose() - print(len(basisKerK)) _, _, kerK = kernel(K, rref_mod_2) assert len(kerK) == 1 h = kerK[0] - return gf128_to_bytes(vec_to_gf128(h)) + + zero_tag = gf128_to_vec(bytes_to_gf128(gmac(vec_to_gf128(h), 0, aad, orig_ct)))[:mac_bytes*8] + gf128_mac = 0 + i = 0 + for b in mac: + for j in range(8): + if b & (1 << (7-j)): + gf128_mac += (1<source code · nonce reuse - @@ -42,13 +42,14 @@ started to reuse AES-GCM nonces. You must perform the Forbidden Attack in order to recover the authentication key and forge arbitrary ciphertext.

- @@ -48,7 +48,7 @@ {% endif %}
- Roseacrucis chooses a key, a nonce, and two messages. He encrypts both messages under the same nonce. + Roseacrucis chooses a key, a nonce, and encrypts two messages under the same nonce.

@@ -62,17 +62,19 @@
- +
- +

- After intercepting the ciphertexts, you choose a new message to forge under the same key and nonce. + After intercepting the ciphertexts and recovering the + authentication key, you choose a new message to forge under the + same key and nonce.

@@ -139,9 +141,10 @@

However, we still need to compute a new MAC over the forged ciphertext. - Simplifying for a ciphertext \(c\) of two blocks, the GMAC MAC is computed as + Simplifying for a ciphertext \(c\) of two blocks and no additional + authenticated data, the GMAC MAC is computed as \[ - mac = s + (len)h + c_1h^2 + c_0h^3, + mac = s + \vert c\vert h + c_1h^2 + c_0h^3, \] where \(s\) is a constant depending on the AES-GCM key and the nonce, and \(h\) is the authentication key depending only on the AES-GCM key. @@ -167,6 +170,28 @@ Note that there may be multiple possible monomial roots; in this case, one can check each possibility against the enemy.

+

+ One can use SageMath to compute factors of a polynomial: +

+
+K = GF(2**128, name='x', modulus=x^128+x^7+x^2+x+1)
+x = K.gen()
+S = PolynomialRing(K, 'y')
+y = S.gen()
+p = (1)*y^4 + (x^7)*y^3 + (x^9 + x^4 + 1)*y^2 + (x^12 + x^2)*y + (x^10 + x^5)
+for factor, _ in p.factor():
+    if factor.degree() == 1:
+        print('Authentication key:', factor - y)
+

+ However, the library powering this demonstration implements polynomial factoring over finite fields from scratch, which is an edifying exercise. +

+

+ We present advice for those who wish to implement polynomial factorization as well: +

+
    +
  • The gcd of two polynomials is unique only up to multiplication by a non-zero constant because “greater” is defined for polynomials in terms of degree. When used in algorithms, gcd refers to the monic gcd, which is unique.
  • +
  • The inverse Frobenius automorphism (i.e., square root) in \(\mathbb{F}_{2^{128}}\) is given by \(\sqrt{x} = x^{2^{127}}\).
  • +

Readers who wish to implement this attack themselves can try Cryptopals; specifically @@ -197,52 +222,6 @@ c_forged, aad_forged = xor(c1, xor(m1, m_forged)), b"" for h, s in possible_secrets: print("MAC candidate": gmac(h, s, aad_forged, c_forged)) -

- - Show me the math. - -

- Once the polynomial difference is computed, one can use SageMath - to compute the factors: -

-
-K = GF(2**128, name='x', modulus=x^128+x^7+x^2+x+1)
-x = K.gen()
-S = PolynomialRing(K, 'y')
-y = S.gen()
-p = (x^127 + x^125 + x^121 + x^118 + x^117 + x^116 + x^113 + x^111 + x^108 + x^105 + x^102 + x^99 + x^97 + x^95 + x^89 + x^87 +
- x^85 + x^84 + x^81 + x^78 + x^73 + x^71 + x^69 + x^67 + x^65 + x^63 + x^62 + x^59 + x^57 + x^55 + x^54 + x^53 + x^52 + x^51 +
-x^49 + x^47 + x^46 + x^45 + x^43 + x^41 + x^39 + x^38 + x^37 + x^36 + x^33 + x^29 + x^28 + x^25 + x^21 + x^20 + x^17 + x^15 + x
-^13 + x^9 + x^7 + x^4 + x^3 + x)*y^5 + (x^127 + x^125 + x^121 + x^118 + x^117 + x^116 + x^113 + x^111 + x^108 + x^105 + x^102 +
- x^99 + x^97 + x^95 + x^89 + x^87 + x^85 + x^84 + x^81 + x^78 + x^73 + x^71 + x^69 + x^67 + x^65 + x^63 + x^62 + x^59 + x^57 +
-x^55 + x^54 + x^53 + x^52 + x^51 + x^49 + x^47 + x^46 + x^45 + x^43 + x^41 + x^39 + x^38 + x^37 + x^36 + x^33 + x^29 + x^28 + x
-^25 + x^21 + x^20 + x^17 + x^15 + x^13 + x^9 + x^7 + x^4 + x^3 + x)*y^4 + (x^127 + x^125 + x^124 + x^123 + x^122 + x^120 + x^11
-9 + x^118 + x^115 + x^112 + x^111 + x^110 + x^109 + x^108 + x^106 + x^101 + x^100 + x^99 + x^98 + x^96 + x^93 + x^88 + x^87 + x
-^84 + x^83 + x^82 + x^78 + x^77 + x^74 + x^71 + x^70 + x^69 + x^68 + x^65 + x^62 + x^61 + x^60 + x^57 + x^55 + x^53 + x^50 + x^
-49 + x^47 + x^46 + x^44 + x^43 + x^41 + x^40 + x^39 + x^37 + x^36 + x^35 + x^34 + x^33 + x^31 + x^30 + x^25 + x^19 + x^16 + x^1
-4 + x^13 + x^12 + x^11 + x^10 + x^5 + x^2 + x + 1)*y^3 + (x^124 + x^123 + x^121 + x^120 + x^119 + x^118 + x^117 + x^116 + x^115
- + x^113 + x^112 + x^110 + x^107 + x^106 + x^104 + x^103 + x^101 + x^99 + x^98 + x^95 + x^94 + x^83 + x^82 + x^81 + x^80 + x^79
- + x^77 + x^76 + x^75 + x^73 + x^72 + x^67 + x^64 + x^63 + x^62 + x^61 + x^59 + x^57 + x^56 + x^54 + x^53 + x^51 + x^49 + x^48
-+ x^46 + x^45 + x^44 + x^42 + x^36 + x^35 + x^34 + x^33 + x^31 + x^28 + x^22 + x^21 + x^17 + x^12 + x^11 + x^10 + x^8 + x^5 + x
-^4 + 1)*y^2 + (x^120 + x^119 + x^56 + x^55)*y + (x^127 + x^126 + x^125 + x^124 + x^123 + x^118 + x^117 + x^116 + x^115 + x^114
-+ x^113 + x^105 + x^103 + x^98 + x^96 + x^94 + x^91 + x^90 + x^89 + x^87 + x^86 + x^85 + x^83 + x^81 + x^80 + x^78 + x^77 + x^7
-0 + x^66 + x^63 + x^62 + x^59 + x^58 + x^54 + x^53 + x^52 + x^50 + x^47 + x^45 + x^44 + x^42 + x^40 + x^39 + x^37 + x^35 + x^34
- + x^30 + x^29 + x^27 + x^26 + x^25 + x^23 + x^18 + x^16 + x^14 + x^13 + x^12 + x^10 + x^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3
-+ 1)
-for factor, _ in p.factor():
-    if factor.degree() == 1:
-        print('Authentication key:', factor - y)
-

- However, the library powering this demonstration implements polynomial factoring over finite fields from scratch, which is an edifying exercise. -

-

- We present advice for those who wish to implement polynomial factorization as well: -

-
    -
  • The gcd of two polynomials is unique only up to multiplication by a non-zero constant because “greater” is defined for polynomials in terms of degree. When used in algorithms, gcd refers to the monic gcd, which is unique.
  • -
  • The inverse Frobenius automorphism (i.e., square root) in \(\mathbb{F}_{2^{128}}\) is given by \(\sqrt{x} = x^{2^{127}}\).
  • -
-
+ + + -- cgit v1.2.3