Browse Source

crypto: simplify api for new crypto, AEAD only needs 1 key

Thomas Waldmann 3 years ago
parent
commit
9633273622
2 changed files with 21 additions and 25 deletions
  1. 13 15
      src/borg/crypto/low_level.pyx
  2. 8 10
      src/borg/testsuite/crypto.py

+ 13 - 15
src/borg/crypto/low_level.pyx

@@ -428,7 +428,7 @@ cdef class _AEAD_BASE:
 
     cdef CIPHER cipher
     cdef EVP_CIPHER_CTX *ctx
-    cdef unsigned char *enc_key
+    cdef unsigned char *key
     cdef int cipher_blk_len
     cdef int iv_len
     cdef int aad_offset
@@ -442,30 +442,28 @@ cdef class _AEAD_BASE:
         """check whether library requirements for this ciphersuite are satisfied"""
         raise NotImplemented  # override / implement in child class
 
-    def __init__(self, mac_key, enc_key, iv=None, header_len=1, aad_offset=0):
+    def __init__(self, key, iv=None, header_len=1, aad_offset=0):
         """
         init AEAD crypto
 
-        :param mac_key: must be None
-        :param enc_key: 256bit encrypt-then-mac key
+        :param key: 256bit encrypt-then-mac key
         :param iv: 96bit initialisation vector / nonce
-        :param header_len: length of header *without* IV
+        :param header_len: expected length of header *without* IV
         :param aad_offset: where in the header the authenticated data starts
         """
-        assert mac_key is None
-        assert isinstance(enc_key, bytes) and len(enc_key) == 32
+        assert isinstance(key, bytes) and len(key) == 32
         self.iv_len = sizeof(self.iv)
         self.header_len_expected = header_len + self.iv_len
         assert aad_offset <= header_len
         self.aad_offset = aad_offset
         self.mac_len = 16
-        self.enc_key = enc_key
+        self.key = key
         if iv is not None:
             self.set_iv(iv)
         else:
             self.blocks = -1  # make sure set_iv is called before encrypt
 
-    def __cinit__(self, mac_key, enc_key, iv=None, header_len=1, aad_offset=0):
+    def __cinit__(self, key, iv=None, header_len=1, aad_offset=0):
         self.ctx = EVP_CIPHER_CTX_new()
 
     def __dealloc__(self):
@@ -511,7 +509,7 @@ cdef class _AEAD_BASE:
                 raise CryptoError('EVP_EncryptInit_ex failed')
             if not EVP_CIPHER_CTX_ctrl(self.ctx, EVP_CTRL_AEAD_SET_IVLEN, self.iv_len, NULL):
                 raise CryptoError('EVP_CIPHER_CTX_ctrl SET IVLEN failed')
-            rc = EVP_EncryptInit_ex(self.ctx, NULL, NULL, self.enc_key, self.iv)
+            rc = EVP_EncryptInit_ex(self.ctx, NULL, NULL, self.key, self.iv)
             if not rc:
                 raise CryptoError('EVP_EncryptInit_ex failed')
             rc = EVP_EncryptUpdate(self.ctx, NULL, &olen, <const unsigned char*> hdata.buf+aoffset, alen)
@@ -561,7 +559,7 @@ cdef class _AEAD_BASE:
             self.set_iv(iv)
             if not EVP_CIPHER_CTX_ctrl(self.ctx, EVP_CTRL_AEAD_SET_IVLEN, self.iv_len, NULL):
                 raise CryptoError('EVP_CIPHER_CTX_ctrl SET IVLEN failed')
-            if not EVP_DecryptInit_ex(self.ctx, NULL, NULL, self.enc_key, iv):
+            if not EVP_DecryptInit_ex(self.ctx, NULL, NULL, self.key, iv):
                 raise CryptoError('EVP_DecryptInit_ex failed')
             if not EVP_CIPHER_CTX_ctrl(self.ctx, EVP_CTRL_AEAD_SET_TAG, self.mac_len, <unsigned char *> idata.buf + hlen):
                 raise CryptoError('EVP_CIPHER_CTX_ctrl SET TAG failed')
@@ -637,10 +635,10 @@ cdef class AES256_OCB(_AES_BASE):
         if is_libressl:
             raise ValueError('AES OCB is not implemented by LibreSSL (yet?).')
 
-    def __init__(self, mac_key, enc_key, iv=None, header_len=1, aad_offset=0):
+    def __init__(self, key, iv=None, header_len=1, aad_offset=0):
         self.requirements_check()
         self.cipher = EVP_aes_256_ocb
-        super().__init__(mac_key, enc_key, iv=iv, header_len=header_len, aad_offset=aad_offset)
+        super().__init__(key, iv=iv, header_len=header_len, aad_offset=aad_offset)
 
 
 cdef class CHACHA20_POLY1305(_CHACHA_BASE):
@@ -649,10 +647,10 @@ cdef class CHACHA20_POLY1305(_CHACHA_BASE):
         if is_libressl:
             raise ValueError('CHACHA20-POLY1305 is not implemented by LibreSSL (yet?).')
 
-    def __init__(self, mac_key, enc_key, iv=None, header_len=1, aad_offset=0):
+    def __init__(self, key, iv=None, header_len=1, aad_offset=0):
         self.requirements_check()
         self.cipher = EVP_chacha20_poly1305
-        super().__init__(mac_key, enc_key, iv=iv, header_len=header_len, aad_offset=aad_offset)
+        super().__init__(key, iv=iv, header_len=header_len, aad_offset=aad_offset)
 
 
 cdef class AES:

+ 8 - 10
src/borg/testsuite/crypto.py

@@ -91,8 +91,7 @@ class CryptoTestCase(BaseTestCase):
 
     def test_AE(self):
         # used in legacy-like layout (1 type byte, no aad)
-        mac_key = None
-        enc_key = b'X' * 32
+        key = b'X' * 32
         iv = 0
         data = b'foo' * 10
         header = b'\x23'
@@ -111,7 +110,7 @@ class CryptoTestCase(BaseTestCase):
         for cs_cls, exp_mac, exp_cdata in tests:
             # print(repr(cs_cls))
             # encrypt/mac
-            cs = cs_cls(mac_key, enc_key, iv, header_len=len(header), aad_offset=1)
+            cs = cs_cls(key, iv, header_len=len(header), aad_offset=1)
             hdr_mac_iv_cdata = cs.encrypt(data, header=header)
             hdr = hdr_mac_iv_cdata[0:1]
             iv = hdr_mac_iv_cdata[1:13]
@@ -123,20 +122,19 @@ class CryptoTestCase(BaseTestCase):
             self.assert_equal(hexlify(cdata), exp_cdata)
             self.assert_equal(cs.next_iv(), 1)
             # auth/decrypt
-            cs = cs_cls(mac_key, enc_key, header_len=len(header), aad_offset=1)
+            cs = cs_cls(key, header_len=len(header), aad_offset=1)
             pdata = cs.decrypt(hdr_mac_iv_cdata)
             self.assert_equal(data, pdata)
             self.assert_equal(cs.next_iv(), 1)
             # auth-failure due to corruption (corrupted data)
-            cs = cs_cls(mac_key, enc_key, header_len=len(header), aad_offset=1)
+            cs = cs_cls(key, header_len=len(header), aad_offset=1)
             hdr_mac_iv_cdata_corrupted = hdr_mac_iv_cdata[:29] + b'\0' + hdr_mac_iv_cdata[30:]
             self.assert_raises(IntegrityError,
                                lambda: cs.decrypt(hdr_mac_iv_cdata_corrupted))
 
     def test_AEAD(self):
         # test with aad
-        mac_key = None
-        enc_key = b'X' * 32
+        key = b'X' * 32
         iv = 0
         data = b'foo' * 10
         header = b'\x12\x34\x56'
@@ -155,7 +153,7 @@ class CryptoTestCase(BaseTestCase):
         for cs_cls, exp_mac, exp_cdata in tests:
             # print(repr(cs_cls))
             # encrypt/mac
-            cs = cs_cls(mac_key, enc_key, iv, header_len=len(header), aad_offset=1)
+            cs = cs_cls(key, iv, header_len=len(header), aad_offset=1)
             hdr_mac_iv_cdata = cs.encrypt(data, header=header)
             hdr = hdr_mac_iv_cdata[0:3]
             iv = hdr_mac_iv_cdata[3:15]
@@ -167,12 +165,12 @@ class CryptoTestCase(BaseTestCase):
             self.assert_equal(hexlify(cdata), exp_cdata)
             self.assert_equal(cs.next_iv(), 1)
             # auth/decrypt
-            cs = cs_cls(mac_key, enc_key, header_len=len(header), aad_offset=1)
+            cs = cs_cls(key, header_len=len(header), aad_offset=1)
             pdata = cs.decrypt(hdr_mac_iv_cdata)
             self.assert_equal(data, pdata)
             self.assert_equal(cs.next_iv(), 1)
             # auth-failure due to corruption (corrupted aad)
-            cs = cs_cls(mac_key, enc_key, header_len=len(header), aad_offset=1)
+            cs = cs_cls(key, header_len=len(header), aad_offset=1)
             hdr_mac_iv_cdata_corrupted = hdr_mac_iv_cdata[:1] + b'\0' + hdr_mac_iv_cdata[2:]
             self.assert_raises(IntegrityError,
                                lambda: cs.decrypt(hdr_mac_iv_cdata_corrupted))