mirror of https://github.com/borgbackup/borg.git
refactor / generalize to num_cipher_blocks
This commit is contained in:
parent
310b4b7775
commit
2d79f19263
|
@ -27,7 +27,7 @@ from ..item import Key, EncryptedKey
|
||||||
from ..platform import SaveFile
|
from ..platform import SaveFile
|
||||||
|
|
||||||
from .nonces import NonceManager
|
from .nonces import NonceManager
|
||||||
from .low_level import AES, bytes_to_long, long_to_bytes, bytes_to_int, num_aes_blocks, hmac_sha256, blake2b_256, hkdf_hmac_sha512
|
from .low_level import AES, bytes_to_long, long_to_bytes, bytes_to_int, num_cipher_blocks, hmac_sha256, blake2b_256, hkdf_hmac_sha512
|
||||||
from .low_level import AES256_CTR_HMAC_SHA256 as CIPHERSUITE
|
from .low_level import AES256_CTR_HMAC_SHA256 as CIPHERSUITE
|
||||||
|
|
||||||
|
|
||||||
|
@ -514,7 +514,7 @@ class PassphraseKey(ID_HMAC_SHA_256, AESKeyBase):
|
||||||
key.init(repository, passphrase)
|
key.init(repository, passphrase)
|
||||||
try:
|
try:
|
||||||
key.decrypt(None, manifest_data)
|
key.decrypt(None, manifest_data)
|
||||||
num_blocks = num_aes_blocks(len(manifest_data) - 41)
|
num_blocks = num_cipher_blocks(len(manifest_data) - 41)
|
||||||
key.init_ciphers(key.extract_nonce(manifest_data) + num_blocks)
|
key.init_ciphers(key.extract_nonce(manifest_data) + num_blocks)
|
||||||
key._passphrase = passphrase
|
key._passphrase = passphrase
|
||||||
return key
|
return key
|
||||||
|
@ -554,7 +554,7 @@ class KeyfileKeyBase(AESKeyBase):
|
||||||
else:
|
else:
|
||||||
if not key.load(target, passphrase):
|
if not key.load(target, passphrase):
|
||||||
raise PassphraseWrong
|
raise PassphraseWrong
|
||||||
num_blocks = num_aes_blocks(len(manifest_data) - 41)
|
num_blocks = num_cipher_blocks(len(manifest_data) - 41)
|
||||||
key.init_ciphers(key.extract_nonce(manifest_data) + num_blocks)
|
key.init_ciphers(key.extract_nonce(manifest_data) + num_blocks)
|
||||||
key._passphrase = passphrase
|
key._passphrase = passphrase
|
||||||
return key
|
return key
|
||||||
|
|
|
@ -168,11 +168,20 @@ def increment_iv(iv, amount=1):
|
||||||
return iv
|
return iv
|
||||||
|
|
||||||
|
|
||||||
def num_aes_blocks(length):
|
def num_cipher_blocks(length, blocksize=16):
|
||||||
"""Return the number of AES blocks required to encrypt/decrypt *length* bytes of data.
|
"""Return the number of cipher blocks required to encrypt/decrypt <length> bytes of data.
|
||||||
Note: this is only correct for modes without padding, like AES-CTR.
|
|
||||||
|
For a precise computation, <blocksize> must be the used cipher's block size (AES: 16, CHACHA20: 64).
|
||||||
|
|
||||||
|
For a safe-upper-boundary computation, <blocksize> must be the MINIMUM of the block sizes (in
|
||||||
|
bytes) of ALL supported ciphers. This can be used to adjust a counter if the used cipher is not
|
||||||
|
known (yet).
|
||||||
|
The default value of blocksize must be adjusted so it reflects this minimum, so a call of this
|
||||||
|
function without a blocksize is "safe-upper-boundary by default".
|
||||||
|
|
||||||
|
Padding cipher modes are not supported.
|
||||||
"""
|
"""
|
||||||
return (length + 15) // 16
|
return (length + blocksize - 1) // blocksize
|
||||||
|
|
||||||
|
|
||||||
class CryptoError(Exception):
|
class CryptoError(Exception):
|
||||||
|
@ -363,8 +372,7 @@ cdef class AES256_CTR_HMAC_SHA256:
|
||||||
PyBuffer_Release(&idata)
|
PyBuffer_Release(&idata)
|
||||||
|
|
||||||
def block_count(self, length):
|
def block_count(self, length):
|
||||||
# number of cipher blocks needed for data of length bytes
|
return num_cipher_blocks(length, self.cipher_blk_len)
|
||||||
return (length + self.cipher_blk_len - 1) // self.cipher_blk_len
|
|
||||||
|
|
||||||
def set_iv(self, iv):
|
def set_iv(self, iv):
|
||||||
# set_iv needs to be called before each encrypt() call
|
# set_iv needs to be called before each encrypt() call
|
||||||
|
@ -528,8 +536,7 @@ cdef class _AEAD_BASE:
|
||||||
PyBuffer_Release(&idata)
|
PyBuffer_Release(&idata)
|
||||||
|
|
||||||
def block_count(self, length):
|
def block_count(self, length):
|
||||||
# number of cipher blocks needed for data of length bytes
|
return num_cipher_blocks(length, self.cipher_blk_len)
|
||||||
return (length + self.cipher_blk_len - 1) // self.cipher_blk_len
|
|
||||||
|
|
||||||
def set_iv(self, iv):
|
def set_iv(self, iv):
|
||||||
# set_iv needs to be called before each encrypt() call,
|
# set_iv needs to be called before each encrypt() call,
|
||||||
|
@ -679,8 +686,7 @@ cdef class AES:
|
||||||
PyBuffer_Release(&idata)
|
PyBuffer_Release(&idata)
|
||||||
|
|
||||||
def block_count(self, length):
|
def block_count(self, length):
|
||||||
# number of cipher blocks needed for data of length bytes
|
return num_cipher_blocks(length, self.cipher_blk_len)
|
||||||
return (length + self.cipher_blk_len - 1) // self.cipher_blk_len
|
|
||||||
|
|
||||||
def set_iv(self, iv):
|
def set_iv(self, iv):
|
||||||
# set_iv needs to be called before each encrypt() call,
|
# set_iv needs to be called before each encrypt() call,
|
||||||
|
|
|
@ -36,7 +36,7 @@ from ..archive import Archive, ChunkBuffer, flags_noatime, flags_normal
|
||||||
from ..archiver import Archiver, parse_storage_quota
|
from ..archiver import Archiver, parse_storage_quota
|
||||||
from ..cache import Cache, LocalCache
|
from ..cache import Cache, LocalCache
|
||||||
from ..constants import * # NOQA
|
from ..constants import * # NOQA
|
||||||
from ..crypto.low_level import bytes_to_long, num_aes_blocks
|
from ..crypto.low_level import bytes_to_long, num_cipher_blocks
|
||||||
from ..crypto.key import KeyfileKeyBase, RepoKey, KeyfileKey, Passphrase, TAMRequiredError
|
from ..crypto.key import KeyfileKeyBase, RepoKey, KeyfileKey, Passphrase, TAMRequiredError
|
||||||
from ..crypto.keymanager import RepoIdMismatch, NotABorgKeyFile
|
from ..crypto.keymanager import RepoIdMismatch, NotABorgKeyFile
|
||||||
from ..crypto.file_integrity import FileIntegrityError
|
from ..crypto.file_integrity import FileIntegrityError
|
||||||
|
@ -2169,7 +2169,7 @@ class ArchiverTestCase(ArchiverTestCaseBase):
|
||||||
hash = sha256(data).digest()
|
hash = sha256(data).digest()
|
||||||
if hash not in seen:
|
if hash not in seen:
|
||||||
seen.add(hash)
|
seen.add(hash)
|
||||||
num_blocks = num_aes_blocks(len(data) - 41)
|
num_blocks = num_cipher_blocks(len(data) - 41)
|
||||||
nonce = bytes_to_long(data[33:41])
|
nonce = bytes_to_long(data[33:41])
|
||||||
for counter in range(nonce, nonce + num_blocks):
|
for counter in range(nonce, nonce + num_blocks):
|
||||||
self.assert_not_in(counter, used)
|
self.assert_not_in(counter, used)
|
||||||
|
|
Loading…
Reference in New Issue