Selaa lähdekoodia

argon2 key: use chacha20-poly1305 instead of aes256-ctr + hmac-sha256, fixes #6601

so we can completely get rid of aes-ctr some day.
Thomas Waldmann 3 vuotta sitten
vanhempi
sitoutus
ed59159649
4 muutettua tiedostoa jossa 18 lisäystä ja 32 poistoa
  1. 2 2
      src/borg/constants.py
  2. 7 17
      src/borg/crypto/key.py
  3. 4 4
      src/borg/testsuite/archiver.py
  4. 5 9
      src/borg/testsuite/crypto.py

+ 2 - 2
src/borg/constants.py

@@ -112,8 +112,8 @@ ARGON2_SALT_BYTES = 16
 KEY_ALGORITHMS = {
     # encrypt-and-MAC, kdf: PBKDF2(HMAC−SHA256), encryption: AES256-CTR, authentication: HMAC-SHA256
     'pbkdf2': 'sha256',
-    # encrypt-then-MAC, kdf: argon2, encryption: AES256-CTR, authentication: HMAC-SHA256
-    'argon2': 'argon2 aes256-ctr hmac-sha256',
+    # encrypt-then-MAC, kdf: argon2, encryption: chacha20, authentication: poly1305
+    'argon2': 'argon2 chacha20-poly1305',
 }
 
 

+ 7 - 17
src/borg/crypto/key.py

@@ -445,7 +445,7 @@ class FlexiKey:
             self._encrypted_key_algorithm = encrypted_key.algorithm
             if encrypted_key.algorithm == 'sha256':
                 return self.decrypt_key_file_pbkdf2(encrypted_key, passphrase)
-            elif encrypted_key.algorithm == 'argon2 aes256-ctr hmac-sha256':
+            elif encrypted_key.algorithm == 'argon2 chacha20-poly1305':
                 return self.decrypt_key_file_argon2(encrypted_key, passphrase)
             else:
                 raise UnsupportedKeyFormatError()
@@ -497,19 +497,14 @@ class FlexiKey:
     def decrypt_key_file_argon2(self, encrypted_key, passphrase):
         key = self.argon2(
             passphrase,
-            output_len_in_bytes=64,
+            output_len_in_bytes=32,
             salt=encrypted_key.salt,
             time_cost=encrypted_key.argon2_time_cost,
             memory_cost=encrypted_key.argon2_memory_cost,
             parallelism=encrypted_key.argon2_parallelism,
             type=encrypted_key.argon2_type,
         )
-        enc_key, mac_key = key[:32], key[32:]
-        ae_cipher = AES256_CTR_HMAC_SHA256(
-            iv=0, header_len=0, aad_offset=0,
-            enc_key=enc_key,
-            mac_key=mac_key,
-        )
+        ae_cipher = CHACHA20_POLY1305(key=key, iv=0, header_len=0, aad_offset=0)
         try:
             return ae_cipher.decrypt(encrypted_key.data)
         except low_level.IntegrityError:
@@ -518,7 +513,7 @@ class FlexiKey:
     def encrypt_key_file(self, data, passphrase, algorithm):
         if algorithm == 'sha256':
             return self.encrypt_key_file_pbkdf2(data, passphrase)
-        elif algorithm == 'argon2 aes256-ctr hmac-sha256':
+        elif algorithm == 'argon2 chacha20-poly1305':
             return self.encrypt_key_file_argon2(data, passphrase)
         else:
             raise ValueError(f'Unexpected algorithm: {algorithm}')
@@ -543,19 +538,14 @@ class FlexiKey:
         salt = os.urandom(ARGON2_SALT_BYTES)
         key = self.argon2(
             passphrase,
-            output_len_in_bytes=64,
+            output_len_in_bytes=32,
             salt=salt,
             **ARGON2_ARGS,
         )
-        enc_key, mac_key = key[:32], key[32:]
-        ae_cipher = AES256_CTR_HMAC_SHA256(
-            iv=0, header_len=0, aad_offset=0,
-            enc_key=enc_key,
-            mac_key=mac_key,
-        )
+        ae_cipher = CHACHA20_POLY1305(key=key, iv=0, header_len=0, aad_offset=0)
         encrypted_key = EncryptedKey(
             version=1,
-            algorithm='argon2 aes256-ctr hmac-sha256',
+            algorithm='argon2 chacha20-poly1305',
             salt=salt,
             data=ae_cipher.encrypt(data),
             **{'argon2_' + k: v for k, v in ARGON2_ARGS.items()},

+ 4 - 4
src/borg/testsuite/archiver.py

@@ -3600,7 +3600,7 @@ id: 2 / e29442 3506da 4e1ea7 / 25f62a 5a3d41 - 02
         self.cmd('init', '--encryption=repokey', self.repository_location)
         with Repository(self.repository_path) as repository:
             key = msgpack.unpackb(a2b_base64(repository.load_key()))
-        assert key[b'algorithm'] == b'argon2 aes256-ctr hmac-sha256'
+        assert key[b'algorithm'] == b'argon2 chacha20-poly1305'
 
     def test_init_with_explicit_key_algorithm(self):
         """https://github.com/borgbackup/borg/issues/747#issuecomment-1076160401"""
@@ -3620,7 +3620,7 @@ id: 2 / e29442 3506da 4e1ea7 / 25f62a 5a3d41 - 02
             assert key[b'algorithm'] == expected_algorithm
 
     def test_change_passphrase_does_not_change_algorithm_argon2(self):
-        self.verify_change_passphrase_does_not_change_algorithm('argon2', b'argon2 aes256-ctr hmac-sha256')
+        self.verify_change_passphrase_does_not_change_algorithm('argon2', b'argon2 chacha20-poly1305')
 
     def test_change_passphrase_does_not_change_algorithm_pbkdf2(self):
         self.verify_change_passphrase_does_not_change_algorithm('pbkdf2', b'sha256')
@@ -3635,7 +3635,7 @@ id: 2 / e29442 3506da 4e1ea7 / 25f62a 5a3d41 - 02
             assert key[b'algorithm'] == expected_algorithm
 
     def test_change_location_does_not_change_algorithm_argon2(self):
-        self.verify_change_location_does_not_change_algorithm('argon2', b'argon2 aes256-ctr hmac-sha256')
+        self.verify_change_location_does_not_change_algorithm('argon2', b'argon2 chacha20-poly1305')
 
     def test_change_location_does_not_change_algorithm_pbkdf2(self):
         self.verify_change_location_does_not_change_algorithm('pbkdf2', b'sha256')
@@ -3647,7 +3647,7 @@ id: 2 / e29442 3506da 4e1ea7 / 25f62a 5a3d41 - 02
 
         with Repository(self.repository_path) as repository:
             _, key = Manifest.load(repository, Manifest.NO_OPERATION_CHECK)
-        assert key._encrypted_key_algorithm == 'argon2 aes256-ctr hmac-sha256'
+        assert key._encrypted_key_algorithm == 'argon2 chacha20-poly1305'
         self.cmd('info', self.repository_location)
 
 

+ 5 - 9
src/borg/testsuite/crypto.py

@@ -247,15 +247,11 @@ class CryptoTestCase(BaseTestCase):
         assert okm == bytes.fromhex('1407d46013d98bc6decefcfee55f0f90b0c7f63d68eb1a80eaf07e953cfc0a3a5240a155d6e4daa965bb')
 
 
-def test_decrypt_key_file_argon2_aes256_ctr_hmac_sha256():
+def test_decrypt_key_file_argon2_chacha20_poly1305():
     plain = b'hello'
-    # echo -n "hello, pass phrase" | argon2 saltsaltsaltsalt -id -t 1 -k 8 -p 1 -l 64 -r
-    key = bytes.fromhex('d07cc7f9cfb483303e0b9fec176b2a9c559bb70c3a9fb0d5f9c0c23527cd09570212449f09f8cd28c1a41b73fa0098e889c3f2642e87c392e51f95d70d248d9d')
-    ae_cipher = AES256_CTR_HMAC_SHA256(
-        iv=0, header_len=0, aad_offset=0,
-        enc_key=key[:32],
-        mac_key=key[32:],
-    )
+    # echo -n "hello, pass phrase" | argon2 saltsaltsaltsalt -id -t 1 -k 8 -p 1 -l 32 -r
+    key = bytes.fromhex('a1b0cba145c154fbd8960996c5ce3428e9920cfe53c84ef08b4102a70832bcec')
+    ae_cipher = CHACHA20_POLY1305(key=key, iv=0, header_len=0, aad_offset=0)
 
     envelope = ae_cipher.encrypt(plain)
 
@@ -266,7 +262,7 @@ def test_decrypt_key_file_argon2_aes256_ctr_hmac_sha256():
         'argon2_memory_cost': 8,
         'argon2_parallelism': 1,
         'argon2_type': b'id',
-        'algorithm': 'argon2 aes256-ctr hmac-sha256',
+        'algorithm': 'argon2 chacha20-poly1305',
         'data': envelope,
     })
     key = KeyfileKey(None)