浏览代码

check: --verify-data does not need to decompress with new crypto modes

Thomas Waldmann 3 年之前
父节点
当前提交
b0db800b5a
共有 1 个文件被更改,包括 9 次插入3 次删除
  1. 9 3
      src/borg/archive.py

+ 9 - 3
src/borg/archive.py

@@ -21,7 +21,7 @@ logger = create_logger()
 from . import xattr
 from . import xattr
 from .chunker import get_chunker, Chunk
 from .chunker import get_chunker, Chunk
 from .cache import ChunkListEntry
 from .cache import ChunkListEntry
-from .crypto.key import key_factory
+from .crypto.key import key_factory, AEADKeyBase
 from .compress import Compressor, CompressionSpec
 from .compress import Compressor, CompressionSpec
 from .constants import *  # NOQA
 from .constants import *  # NOQA
 from .crypto.low_level import IntegrityError as IntegrityErrorBase
 from .crypto.low_level import IntegrityError as IntegrityErrorBase
@@ -1684,6 +1684,12 @@ class ArchiveChecker:
         chunks_count_index = len(self.chunks)
         chunks_count_index = len(self.chunks)
         chunks_count_segments = 0
         chunks_count_segments = 0
         errors = 0
         errors = 0
+        # for the new crypto, derived from AEADKeyBase, we know that it checks authenticity on
+        # the crypto.low_level level - invalid chunks will fail to AEAD authenticate.
+        # for these key types, we know that there is no need to decompress the data afterwards.
+        # for all other modes, we assume that we must decompress, so we can verify authenticity
+        # based on the plaintext MAC (via calling ._assert_id(id, plaintext)).
+        decompress = not isinstance(self.key, AEADKeyBase)
         defect_chunks = []
         defect_chunks = []
         pi = ProgressIndicatorPercent(
         pi = ProgressIndicatorPercent(
             total=chunks_count_index, msg="Verifying data %6.2f%%", step=0.01, msgid="check.verify_data"
             total=chunks_count_index, msg="Verifying data %6.2f%%", step=0.01, msgid="check.verify_data"
@@ -1714,7 +1720,7 @@ class ArchiveChecker:
                         chunk_data_iter = self.repository.get_many(chunk_ids)
                         chunk_data_iter = self.repository.get_many(chunk_ids)
                 else:
                 else:
                     try:
                     try:
-                        self.key.decrypt(chunk_id, encrypted_data)
+                        self.key.decrypt(chunk_id, encrypted_data, decompress=decompress)
                     except IntegrityErrorBase as integrity_error:
                     except IntegrityErrorBase as integrity_error:
                         self.error_found = True
                         self.error_found = True
                         errors += 1
                         errors += 1
@@ -1745,7 +1751,7 @@ class ArchiveChecker:
                     # from the underlying media.
                     # from the underlying media.
                     try:
                     try:
                         encrypted_data = self.repository.get(defect_chunk)
                         encrypted_data = self.repository.get(defect_chunk)
-                        self.key.decrypt(defect_chunk, encrypted_data)
+                        self.key.decrypt(defect_chunk, encrypted_data, decompress=decompress)
                     except IntegrityErrorBase:
                     except IntegrityErrorBase:
                         # failed twice -> get rid of this chunk
                         # failed twice -> get rid of this chunk
                         del self.chunks[defect_chunk]
                         del self.chunks[defect_chunk]