diff options
Diffstat (limited to 'aesgcmanalysis.py')
-rw-r--r-- | aesgcmanalysis.py | 40 |
1 files changed, 28 insertions, 12 deletions
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<<i) + i += 1 + def small_gf128_to_vec(x): + return [int(n) for n in bin(x)[2:].zfill(mac_bytes*8)[::-1]] + mac_vec = small_gf128_to_vec(gf128_mac) + s = (np.array(zero_tag) - np.array(mac_vec)) % 2 + return vec_to_gf128(h), vec_to_gf128(s) # Demos @@ -757,20 +770,23 @@ def forbidden_attack_demo(): assert succeeded def nonce_truncation_demo(): - k = b'YELLOW_SUBMARINE' + # Should work with non-block size multiples. + # Need to modify to consider padding, but we can't mess with the bits in the padding, + # nor can we extend ad/ct unless we also change length block. + k = b'YELLOGIOJEWARINE' aad = b'YELLOW_SUBMAFINERELLOWPUBMARINF_' MACBYTES=1 - pt = b'CELERYPATCHWORKS'*(2**9) + pt = b'CELERYPATCHWORKS'*(2**5) nonce = b'JORGELBORGES' - ct, mac = gcm_encrypt(k, nonce, aad, pt, mac_bytes=MACBYTES) + ct, mac = gcm_encrypt(k, nonce, aad, pt) + # ct, mac = gcm_encrypt(k, nonce, aad, pt, mac_bytes=MACBYTES) + mac = mac[:1] def oracle(base, aad, mac, nonce): cipher = AES.new(k, mode=AES.MODE_GCM, nonce=nonce, mac_len=MACBYTES) cipher.update(aad) pt = cipher.decrypt_and_verify(base, mac) - h = compute_auth_key(ct, mac, nonce, MACBYTES, aad, oracle) - assert h == gf128_to_bytes(authentication_key(k)) -nonce_truncation_demo() + h, s = nonce_truncation_recover_secrets(ct, mac, nonce, MACBYTES, aad, oracle) + assert h == authentication_key(k) + return h, s -# Try with different lengths -# Make it so we chosoe to generate gen_t on the fly if needed -# PRofiling +nonce_truncation_demo() |