|
@@ -4,14 +4,14 @@ import getpass
|
|
import os
|
|
import os
|
|
import sys
|
|
import sys
|
|
import textwrap
|
|
import textwrap
|
|
-from hmac import HMAC, compare_digest
|
|
|
|
|
|
+from hmac import compare_digest
|
|
from hashlib import sha256, pbkdf2_hmac
|
|
from hashlib import sha256, pbkdf2_hmac
|
|
|
|
|
|
from .helpers import IntegrityError, get_keys_dir, Error, yes
|
|
from .helpers import IntegrityError, get_keys_dir, Error, yes
|
|
from .logger import create_logger
|
|
from .logger import create_logger
|
|
logger = create_logger()
|
|
logger = create_logger()
|
|
|
|
|
|
-from .crypto import AES, bytes_to_long, long_to_bytes, bytes_to_int, num_aes_blocks
|
|
|
|
|
|
+from .crypto import AES, bytes_to_long, long_to_bytes, bytes_to_int, num_aes_blocks, hmac_sha256
|
|
from .compress import Compressor, COMPR_BUFFER
|
|
from .compress import Compressor, COMPR_BUFFER
|
|
import msgpack
|
|
import msgpack
|
|
|
|
|
|
@@ -126,28 +126,29 @@ class AESKeyBase(KeyBase):
|
|
def id_hash(self, data):
|
|
def id_hash(self, data):
|
|
"""Return HMAC hash using the "id" HMAC key
|
|
"""Return HMAC hash using the "id" HMAC key
|
|
"""
|
|
"""
|
|
- return HMAC(self.id_key, data, sha256).digest()
|
|
|
|
|
|
+ return hmac_sha256(self.id_key, data)
|
|
|
|
|
|
def encrypt(self, data):
|
|
def encrypt(self, data):
|
|
data = self.compressor.compress(data)
|
|
data = self.compressor.compress(data)
|
|
self.enc_cipher.reset()
|
|
self.enc_cipher.reset()
|
|
data = b''.join((self.enc_cipher.iv[8:], self.enc_cipher.encrypt(data)))
|
|
data = b''.join((self.enc_cipher.iv[8:], self.enc_cipher.encrypt(data)))
|
|
- hmac = HMAC(self.enc_hmac_key, data, sha256).digest()
|
|
|
|
|
|
+ hmac = hmac_sha256(self.enc_hmac_key, data)
|
|
return b''.join((self.TYPE_STR, hmac, data))
|
|
return b''.join((self.TYPE_STR, hmac, data))
|
|
|
|
|
|
def decrypt(self, id, data):
|
|
def decrypt(self, id, data):
|
|
if not (data[0] == self.TYPE or
|
|
if not (data[0] == self.TYPE or
|
|
data[0] == PassphraseKey.TYPE and isinstance(self, RepoKey)):
|
|
data[0] == PassphraseKey.TYPE and isinstance(self, RepoKey)):
|
|
raise IntegrityError('Invalid encryption envelope')
|
|
raise IntegrityError('Invalid encryption envelope')
|
|
- hmac_given = memoryview(data)[1:33]
|
|
|
|
- hmac_computed = memoryview(HMAC(self.enc_hmac_key, memoryview(data)[33:], sha256).digest())
|
|
|
|
|
|
+ data_view = memoryview(data)
|
|
|
|
+ hmac_given = data_view[1:33]
|
|
|
|
+ hmac_computed = memoryview(hmac_sha256(self.enc_hmac_key, data_view[33:]))
|
|
if not compare_digest(hmac_computed, hmac_given):
|
|
if not compare_digest(hmac_computed, hmac_given):
|
|
raise IntegrityError('Encryption envelope checksum mismatch')
|
|
raise IntegrityError('Encryption envelope checksum mismatch')
|
|
self.dec_cipher.reset(iv=PREFIX + data[33:41])
|
|
self.dec_cipher.reset(iv=PREFIX + data[33:41])
|
|
- data = self.compressor.decompress(self.dec_cipher.decrypt(data[41:]))
|
|
|
|
|
|
+ data = self.compressor.decompress(self.dec_cipher.decrypt(data_view[41:]))
|
|
if id:
|
|
if id:
|
|
hmac_given = id
|
|
hmac_given = id
|
|
- hmac_computed = HMAC(self.id_key, data, sha256).digest()
|
|
|
|
|
|
+ hmac_computed = hmac_sha256(self.id_key, data)
|
|
if not compare_digest(hmac_computed, hmac_given):
|
|
if not compare_digest(hmac_computed, hmac_given):
|
|
raise IntegrityError('Chunk id verification failed')
|
|
raise IntegrityError('Chunk id verification failed')
|
|
return data
|
|
return data
|
|
@@ -322,14 +323,14 @@ class KeyfileKeyBase(AESKeyBase):
|
|
assert d[b'algorithm'] == b'sha256'
|
|
assert d[b'algorithm'] == b'sha256'
|
|
key = passphrase.kdf(d[b'salt'], d[b'iterations'], 32)
|
|
key = passphrase.kdf(d[b'salt'], d[b'iterations'], 32)
|
|
data = AES(is_encrypt=False, key=key).decrypt(d[b'data'])
|
|
data = AES(is_encrypt=False, key=key).decrypt(d[b'data'])
|
|
- if HMAC(key, data, sha256).digest() == d[b'hash']:
|
|
|
|
|
|
+ if hmac_sha256(key, data) == d[b'hash']:
|
|
return data
|
|
return data
|
|
|
|
|
|
def encrypt_key_file(self, data, passphrase):
|
|
def encrypt_key_file(self, data, passphrase):
|
|
salt = os.urandom(32)
|
|
salt = os.urandom(32)
|
|
iterations = 100000
|
|
iterations = 100000
|
|
key = passphrase.kdf(salt, iterations, 32)
|
|
key = passphrase.kdf(salt, iterations, 32)
|
|
- hash = HMAC(key, data, sha256).digest()
|
|
|
|
|
|
+ hash = hmac_sha256(key, data)
|
|
cdata = AES(is_encrypt=True, key=key).encrypt(data)
|
|
cdata = AES(is_encrypt=True, key=key).encrypt(data)
|
|
d = {
|
|
d = {
|
|
'version': 1,
|
|
'version': 1,
|