mirror of
https://github.com/borgbackup/borg.git
synced 2025-02-25 07:23:28 +00:00
make sure set_iv is called before each encrypt() call
This commit is contained in:
parent
d88c0765e7
commit
5287531130
1 changed files with 13 additions and 2 deletions
|
@ -213,6 +213,8 @@ cdef class AES256_CTR_HMAC_SHA256:
|
|||
self.enc_key = enc_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):
|
||||
self.ctx = EVP_CIPHER_CTX_new()
|
||||
|
@ -227,6 +229,7 @@ cdef class AES256_CTR_HMAC_SHA256:
|
|||
encrypt data, compute mac over aad + iv + cdata, prepend header.
|
||||
aad_offset is the offset into the header where aad starts.
|
||||
"""
|
||||
assert self.blocks == 0, 'set_iv needs to be called before encrypt'
|
||||
cdef int ilen = len(data)
|
||||
cdef int hlen = len(header)
|
||||
cdef int aoffset = aad_offset
|
||||
|
@ -326,12 +329,14 @@ cdef class AES256_CTR_HMAC_SHA256:
|
|||
return (length + self.cipher_blk_len - 1) // self.cipher_blk_len
|
||||
|
||||
def set_iv(self, iv):
|
||||
# set_iv needs to be called before each encrypt() call
|
||||
assert isinstance(iv, bytes) and len(iv) == self.iv_len
|
||||
self.blocks = 0 # how many AES blocks got encrypted with this IV?
|
||||
for i in range(self.iv_len):
|
||||
self.iv[i] = iv[i]
|
||||
|
||||
def next_iv(self):
|
||||
# call this after encrypt() to get the next iv for the next encrypt() call
|
||||
return increment_iv(self.iv[:self.iv_len], self.blocks)
|
||||
|
||||
cdef fetch_iv(self, unsigned char * iv_in):
|
||||
|
@ -368,6 +373,8 @@ cdef class _AEAD_BASE:
|
|||
self.enc_key = enc_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):
|
||||
self.ctx = EVP_CIPHER_CTX_new()
|
||||
|
@ -380,6 +387,7 @@ cdef class _AEAD_BASE:
|
|||
encrypt data, compute mac over aad + iv + cdata, prepend header.
|
||||
aad_offset is the offset into the header where aad starts.
|
||||
"""
|
||||
assert self.blocks == 0, 'set_iv needs to be called before encrypt'
|
||||
cdef int ilen = len(data)
|
||||
cdef int hlen = len(header)
|
||||
cdef int aoffset = aad_offset
|
||||
|
@ -423,7 +431,7 @@ cdef class _AEAD_BASE:
|
|||
offset += olen
|
||||
if not EVP_CIPHER_CTX_ctrl(self.ctx, EVP_CTRL_GCM_GET_TAG, self.mac_len, odata+hlen):
|
||||
raise CryptoError('EVP_CIPHER_CTX_ctrl GET TAG failed')
|
||||
self.blocks += self.block_count(ilen)
|
||||
self.blocks = self.block_count(ilen)
|
||||
return odata[:offset]
|
||||
finally:
|
||||
PyMem_Free(odata)
|
||||
|
@ -473,7 +481,7 @@ cdef class _AEAD_BASE:
|
|||
# a failure here means corrupted or tampered tag (mac) or data.
|
||||
raise IntegrityError('Authentication / EVP_DecryptFinal_ex failed')
|
||||
offset += olen
|
||||
self.blocks += self.block_count(offset)
|
||||
self.blocks = self.block_count(offset)
|
||||
return odata[:offset]
|
||||
finally:
|
||||
PyMem_Free(odata)
|
||||
|
@ -484,12 +492,15 @@ cdef class _AEAD_BASE:
|
|||
return (length + self.cipher_blk_len - 1) // self.cipher_blk_len
|
||||
|
||||
def set_iv(self, iv):
|
||||
# set_iv needs to be called before each encrypt() call,
|
||||
# because encrypt does a full initialisation of the cipher context.
|
||||
assert isinstance(iv, bytes) and len(iv) == self.iv_len
|
||||
self.blocks = 0 # number of cipher blocks encrypted with this IV
|
||||
for i in range(self.iv_len):
|
||||
self.iv[i] = iv[i]
|
||||
|
||||
def next_iv(self):
|
||||
# call this after encrypt() to get the next iv for the next encrypt() call
|
||||
# AES-GCM, AES-OCB, CHACHA20 ciphers all add a internal 32bit counter to the 96bit
|
||||
# (12 byte) IV we provide, thus we only need to increment the IV by 1 (and we must
|
||||
# not encrypt more than 2^32 cipher blocks with same IV):
|
||||
|
|
Loading…
Reference in a new issue