borg/dedupestore/crypto.py

68 lines
2.5 KiB
Python
Raw Normal View History

2010-10-21 22:10:51 +00:00
import os
import zlib
from Crypto.Cipher import AES
2010-10-23 19:38:42 +00:00
from Crypto.Hash import SHA256, HMAC
from Crypto.Util.number import bytes_to_long, long_to_bytes
from .helpers import IntegrityError
from .oaep import OAEP
2010-10-21 22:10:51 +00:00
class CryptoManager(object):
2010-10-23 19:38:42 +00:00
CREATE = '\1'
READ = '\2'
2010-10-21 22:10:51 +00:00
def __init__(self, store):
self.key_cache = {}
self.store = store
self.tid = store.tid
self.id_key = '0' * 32
self.read_key = os.urandom(32)
self.create_key = os.urandom(32)
2010-10-23 19:38:42 +00:00
self.read_encrypted = OAEP(256, hash=SHA256).encode(self.read_key, os.urandom(32))
self.create_encrypted = OAEP(256, hash=SHA256).encode(self.create_key, os.urandom(32))
2010-10-21 22:10:51 +00:00
def id_hash(self, data):
2010-10-23 19:38:42 +00:00
return HMAC.new(self.id_key, data, SHA256).digest()
def encrypt_read(self, data):
key_data = OAEP(256, hash=SHA256).encode(self.read_key, os.urandom(32))
#key_data = self.rsa_create.encrypt(key_data)
data = zlib.compress(data)
hash = SHA256.new(data).digest()
data = AES.new(self.read_key, AES.MODE_CFB, hash[:16]).encrypt(data)
return ''.join((self.READ, self.read_encrypted, hash, data))
def encrypt_create(self, data):
key_data = OAEP(256, hash=SHA256).encode(self.create_key, os.urandom(32))
#key_data = self.rsa_create.encrypt(key_data)
data = zlib.compress(data)
hash = SHA256.new(data).digest()
data = AES.new(self.create_key, AES.MODE_CFB, hash[:16]).encrypt(data)
return ''.join((self.CREATE, self.create_encrypted, hash, data))
def decrypt(self, data):
type = data[0]
if type == self.READ:
key_data = data[1:257]
hash = data[257:289]
#key_data = self.rsa_create.decrypt(key_data)
key = OAEP(256, hash=SHA256).decode(key_data)
data = AES.new(key, AES.MODE_CFB, hash[:16]).decrypt(data[289:])
if SHA256.new(data).digest() != hash:
raise IntegrityError('decryption failed')
return zlib.decompress(data)
elif type == self.CREATE:
key_data = data[1:257]
hash = data[257:289]
#key_data = self.rsa_create.decrypt(key_data)
key = OAEP(256, hash=SHA256).decode(key_data)
data = AES.new(key, AES.MODE_CFB, hash[:16]).decrypt(data[289:])
if SHA256.new(data).digest() != hash:
raise IntegrityError('decryption failed')
return zlib.decompress(data)
else:
raise Exception('Unknown pack type %d found' % ord(type))