diff options
author | Thomas Waldmann <tw@waldmann-edv.de> | 2023-02-19 21:06:54 +0100 |
---|---|---|
committer | Thomas Waldmann <tw@waldmann-edv.de> | 2023-02-19 21:14:20 +0100 |
commit | fea630027c6981094293deeeff9aa5a35fca9628 (patch) | |
tree | 04b48280f51d1af612e93d2fd2be1d2bddf98e7d | |
parent | 93a4bd61f81872a10e640c2b18575df60beb4be1 (diff) |
assert_id: better be paranoid, fixes #7362
This makes borg2's new crypto do the same check as borg1's old crypto
and makes sure that no chunks created by an evil borg client would
go unnoticed.
-rw-r--r-- | src/borg/crypto/key.py | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/src/borg/crypto/key.py b/src/borg/crypto/key.py index c31270cd5..01b08579d 100644 --- a/src/borg/crypto/key.py +++ b/src/borg/crypto/key.py @@ -840,11 +840,23 @@ class AEADKeyBase(KeyBase): MAX_IV = 2**48 - 1 def assert_id(self, id, data): - # note: assert_id(id, data) is not needed any more for the new AEAD crypto. - # we put the id into AAD when storing the chunk, so it gets into the authentication tag computation. + # Comparing the id hash here would not be needed any more for the new AEAD crypto **IF** we + # could be sure that chunks were created by normal (not tampered, not evil) borg code: + # We put the id into AAD when storing the chunk, so it gets into the authentication tag computation. # when decrypting, we provide the id we **want** as AAD for the auth tag verification, so # decrypting only succeeds if we got the ciphertext we wrote **for that chunk id**. - pass + # So, basically the **repository** can not cheat on us by giving us a different chunk. + # + # **BUT**, if chunks are created by tampered, evil borg code, the borg client code could put + # a wrong chunkid into AAD and then AEAD-encrypt-and-auth this and store it into the + # repository using this bad chunkid as key (violating the usual chunkid == id_hash(data)). + # Later, when reading such a bad chunk, AEAD-auth-and-decrypt would not notice any + # issue and decrypt successfully. + # Thus, to notice such evil borg activity, we must check for such violations here: + if id and id != Manifest.MANIFEST_ID: + id_computed = self.id_hash(data) + if not hmac.compare_digest(id_computed, id): + raise IntegrityError("Chunk %s: id verification failed" % bin_to_hex(id)) def encrypt(self, id, data): # to encrypt new data in this session we use always self.cipher and self.sessionid |