From: Philipp Gesang Date: Thu, 30 Jan 2020 13:28:06 +0000 (+0100) Subject: unit test detection of non-consecutive ivs X-Git-Tag: v2.2~7^2~2 X-Git-Url: http://developer.intra2net.com/git/?p=python-delta-tar;a=commitdiff_plain;h=2f0b128c7f06af2340af10e1504e70c638316ac2 unit test detection of non-consecutive ivs The detection works as expected except for a bug in the exception formatting. --- diff --git a/deltatar/crypto.py b/deltatar/crypto.py index 53150f1..d18d406 100755 --- a/deltatar/crypto.py +++ b/deltatar/crypto.py @@ -1367,7 +1367,7 @@ class Decrypt (Crypto): and self.last_iv [1] != cnt - 1: raise NonConsecutiveIV ("iv %s counter not successor of " "last object (expected %d, found %d)" - % (fixed, iv_fmt (self.last_iv [1]), cnt)) + % (iv_fmt (iv), self.last_iv [1], cnt)) self.last_iv = (fixed, cnt) diff --git a/testing/test_crypto.py b/testing/test_crypto.py index dc652e2..41b38d7 100644 --- a/testing/test_crypto.py +++ b/testing/test_crypto.py @@ -618,6 +618,73 @@ class AESGCMTest (CryptoLayerTest): _ = decryptor.done () + def test_crypto_aes_gcm_dec_iv_gap (self): + """ + Encrypt multiple objects using non-consecutive IVs and verify that the + decryptor errors out with an exception in strict mode but keeps quiet + otherwise. + """ + cnksiz = 1 << 10 + orig_pt_1 = fill_mod (1 << 10) + orig_pt_2 = fill_mod (1 << 10, 23) + orig_pt_3 = fill_mod (1 << 10, 42) + password = str (os.urandom (42)) + encryptor = crypto.Encrypt (TEST_VERSION, + TEST_PARAMVERSION, + password=password, + 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)) + _n, 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) + + ## Here we bump the iv of the encryptor, breaking the series. + encryptor.set_object_counter (encryptor.cnt + 1) + ct_2, hdr_2, fixed = enc (orig_pt_2) + + ## IV of final object is again in-sequence. + ct_3, hdr_3, fixed = enc (orig_pt_3) + + def decrypt (strict_ivs): + decryptor = crypto.Decrypt (password=password, fixedparts=fixed, + strict_ivs=strict_ivs) + + 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, non-consecutive IV + decr_pt_3 = dec (hdr_3, ct_3) + + assert decr_pt_1 == orig_pt_1 + assert decr_pt_2 == orig_pt_2 + assert decr_pt_3 == orig_pt_3 + + with self.assertRaises (crypto.NonConsecutiveIV): + decrypt (True) + + decrypt (False) # Sequence passes + + def test_crypto_aes_gcm_dec_iv_reuse (self): """ Meddle with encrypted content: extract the IV from one object