From: Philipp Gesang Date: Fri, 5 May 2017 15:52:51 +0000 (+0200) Subject: add unit test for IV reuse X-Git-Tag: v2.2~7^2~125 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=fd10b44af9bd02549a2e8f2c1697c1f9b9da88e4;p=python-delta-tar add unit test for IV reuse --- diff --git a/testing/test_crypto.py b/testing/test_crypto.py index 4b4a016..cfb332c 100644 --- a/testing/test_crypto.py +++ b/testing/test_crypto.py @@ -37,11 +37,12 @@ def faux_hdr (ctsize=1337, iv=None): } -def fill_mod (n): +def fill_mod (n, off=0): buf = bytearray (n) bufv = memoryview (buf) for i in range (n): - c = i % 64 + 32 + off += 1 + c = off % 64 + 32 struct.pack_into ("c", bufv, i, chr(c).encode("UTF-8")) return bytes (buf) @@ -232,6 +233,67 @@ class AESGCMTest (CryptoLayerTest): pass + def test_crypto_aes_gcm_dec_iv_reuse (self): + """ + Meddle with encrypted content: extract the IV from one object + and inject it into the header of another. This must be rejected + by the decryptor. + """ + cnksiz = 1 << 10 + orig_pt_1 = fill_mod (1 << 10) + orig_pt_2 = fill_mod (1 << 10, 42) + password = str (os.urandom (42)) + encryptor = crypto.Encrypt (password, TEST_VERSION, + TEST_PARAMVERSION, + nacl=TEST_STATIC_NACL) + + def enc (pt): + header_dummy = encryptor.next (TEST_DUMMY_FILENAME) + + off = 0 + ct = b"" + while off < len (pt): + upto = min (off + cnksiz, len (pt)) + cnk = encryptor.process (pt [off:upto]) + ct += cnk + off += cnksiz + cnk, header, fixed = encryptor.done (header_dummy) + return ct + cnk, header, fixed + + ct_1, hdr_1, _____ = enc (orig_pt_1) + ct_2, hdr_2, fixed = enc (orig_pt_2) + + mut_hdr_2 = bytearray (hdr_2) + mut_hdr_2_vw = memoryview (mut_hdr_2) + # get IV + iv_lo = crypto.HDR_OFF_IV + iv_hi = crypto.HDR_OFF_IV + crypto.PDTCRYPT_HDR_SIZE_IV + iv_1 = hdr_1 [iv_lo : iv_hi] + # transplant into other header + mut_hdr_2_vw [iv_lo : iv_hi] = iv_1 + hdr_2_mod = bytes (mut_hdr_2) + decryptor = crypto.Decrypt (password, fixedparts=fixed, + strict_ivs=True) + + def dec (hdr, ct): + decryptor.next (hdr) + off = 0 + pt = b"" + while off < len (ct): + upto = min (off + cnksiz, len (ct)) + cnk = decryptor.process (ct [off:upto]) + pt += cnk + off += cnksiz + return pt + decryptor.done () + + decr_pt_1 = dec (hdr_1, ct_1) + decr_pt_2 = dec (hdr_2, ct_2) # good header, different IV + try: + decr_pt_2 = dec (hdr_2_mod, ct_2) + except crypto.DuplicateIV: # bad header, reuse detected + pass + + class HeaderTest (CryptoLayerTest): def test_crypto_fmt_hdr_make (self):