From 310b4b777559a5990223b014f8ef77126b026aec Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 31 Aug 2016 03:30:18 +0200 Subject: [PATCH] UNENCRYPTED (and unauthenticated) "ciphersuite" it can be used to integrate the plaintext mode with the AEAD modes, both use same api now. --- src/borg/crypto/low_level.pyx | 36 +++++++++++++++++++++++++++++++++++ src/borg/testsuite/crypto.py | 12 +++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/borg/crypto/low_level.pyx b/src/borg/crypto/low_level.pyx index a12828bf9..f912401de 100644 --- a/src/borg/crypto/low_level.pyx +++ b/src/borg/crypto/low_level.pyx @@ -189,6 +189,42 @@ cdef Py_buffer ro_buffer(object data) except *: return view +class UNENCRYPTED: + # Layout: HEADER + PlainText + + def __init__(self, mac_key, enc_key, iv=None): + assert mac_key is None + assert enc_key is None + self.set_iv(iv) + + def encrypt(self, data, header=b'', aad_offset=0, iv=None): + """ + IMPORTANT: it is called encrypt to satisfy the crypto api naming convention, + but this does NOT encrypt and it does NOT compute and store a MAC either. + """ + if iv is not None: + self.set_iv(iv) + assert self.iv is not None, 'iv needs to be set before encrypt is called' + return header + data + + def decrypt(self, envelope, header_len=0, aad_offset=0): + """ + IMPORTANT: it is called decrypt to satisfy the crypto api naming convention, + but this does NOT decrypt and it does NOT verify a MAC either, because data + is not encrypted and there is no MAC. + """ + return memoryview(envelope)[header_len:] + + def block_count(self, length): + return 0 + + def set_iv(self, iv): + self.iv = iv + + def next_iv(self): + return self.iv + + cdef class AES256_CTR_HMAC_SHA256: # Layout: HEADER + HMAC 32 + IV 8 + CT (same as attic / borg < 1.2 IF HEADER = TYPE_BYTE, no AAD) diff --git a/src/borg/testsuite/crypto.py b/src/borg/testsuite/crypto.py index e8eceb236..bd04f6411 100644 --- a/src/borg/testsuite/crypto.py +++ b/src/borg/testsuite/crypto.py @@ -1,6 +1,6 @@ from binascii import hexlify, unhexlify -from ..crypto.low_level import AES256_CTR_HMAC_SHA256, AES256_GCM, AES256_OCB, CHACHA20_POLY1305, \ +from ..crypto.low_level import AES256_CTR_HMAC_SHA256, AES256_GCM, AES256_OCB, CHACHA20_POLY1305, UNENCRYPTED, \ IntegrityError, hmac_sha256, blake2b_256, openssl10 from ..crypto.low_level import bytes_to_long, bytes_to_int, long_to_bytes, bytes16_to_int, int_to_bytes16, increment_iv from ..crypto.low_level import hkdf_hmac_sha512 @@ -41,6 +41,16 @@ class CryptoTestCase(BaseTestCase): self.assert_equal(increment_iv(iva, 2), ivc) self.assert_equal(increment_iv(iv0, 2**64), ivb) + def test_UNENCRYPTED(self): + iv = b'' # any IV is ok, it just must be set and not None + data = b'data' + header = b'header' + cs = UNENCRYPTED(None, None, iv) + envelope = cs.encrypt(data, header=header) + self.assert_equal(envelope, header + data) + got_data = cs.decrypt(envelope, header_len=len(header)) + self.assert_equal(got_data, data) + def test_AES256_CTR_HMAC_SHA256(self): # this tests the layout as in attic / borg < 1.2 (1 type byte, no aad) mac_key = b'Y' * 32