use AES from pycryptopp instead of pycrypto, also truncate the keys slightly differently

This commit is contained in:
Brian Warner 2007-12-03 17:27:46 -07:00
parent 87e6ccbd4a
commit 0bf5a762a9
7 changed files with 31 additions and 32 deletions

View File

@ -24,7 +24,7 @@ except ImportError:
install_requires=["zfec >= 1.0.3",
"foolscap >= 0.1.6",
"simplejson >= 1.4",
"pycryptopp >= 0.2.6",
"pycryptopp >= 0.2.8",
]

View File

@ -99,10 +99,11 @@ encrypted child names to rw-URI/ro-URI pairs.
Each SDMF slot is created with a public/private key pair. The public key is
known as the "verification key", while the private key is called the
"signature key". The private key is hashed to form the "write key" (an AES
symmetric key). The write key is then hashed to form the "read key". The read
key is hashed to form the "storage index" (a unique string used as an index
to locate stored data).
"signature key". The private key is hashed and truncated to 16 bytes to form
the "write key" (an AES symmetric key). The write key is then hashed and
truncated to form the "read key". The read key is hashed and truncated to
form the 16-byte "storage index" (a unique string used as an index to locate
stored data).
The public key is hashed by itself to form the "verification key hash".

View File

@ -11,7 +11,7 @@ from allmydata.interfaces import IMutableFileNode, IDirectoryNode,\
from allmydata.util import hashutil
from allmydata.util.hashutil import netstring
from allmydata.uri import NewDirectoryURI
from allmydata.Crypto.Cipher import AES
from pycryptopp.cipher.aes import AES
from allmydata.mutable import MutableFileNode
@ -79,9 +79,8 @@ class NewDirectoryNode:
assert isinstance(rwcap, str)
IV = os.urandom(16)
key = hashutil.mutable_rwcap_key_hash(IV, self._node.get_writekey())
counterstart = "\x00"*16
cryptor = AES.new(key=key, mode=AES.MODE_CTR, counterstart=counterstart)
crypttext = cryptor.encrypt(rwcap)
cryptor = AES(key)
crypttext = cryptor.process(rwcap)
mac = hashutil.hmac(key, IV + crypttext)
assert len(mac) == 32
return IV + crypttext + mac
@ -93,9 +92,8 @@ class NewDirectoryNode:
key = hashutil.mutable_rwcap_key_hash(IV, self._node.get_writekey())
if mac != hashutil.hmac(key, IV+crypttext):
raise hashutil.IntegrityCheckError("HMAC does not match, crypttext is corrupted")
counterstart = "\x00"*16
cryptor = AES.new(key=key, mode=AES.MODE_CTR, counterstart=counterstart)
plaintext = cryptor.decrypt(crypttext)
cryptor = AES(key)
plaintext = cryptor.process(crypttext)
return plaintext
def _create_node(self, child_uri):

View File

@ -10,9 +10,9 @@ from foolscap.eventual import eventually
from allmydata.util import idlib, mathutil, hashutil
from allmydata.util.assertutil import _assert
from allmydata import codec, hashtree, storage, uri
from allmydata.Crypto.Cipher import AES
from allmydata.interfaces import IDownloadTarget, IDownloader, IFileURI
from allmydata.encode import NotEnoughPeersError
from pycryptopp.cipher.aes import AES
class HaveAllPeersError(Exception):
# we use this to jump out of the loop
@ -31,8 +31,7 @@ class DownloadStopped(Exception):
class Output:
def __init__(self, downloadable, key, total_length):
self.downloadable = downloadable
self._decryptor = AES.new(key=key, mode=AES.MODE_CTR,
counterstart="\x00"*16)
self._decryptor = AES(key)
self._crypttext_hasher = hashutil.crypttext_hasher()
self._plaintext_hasher = hashutil.plaintext_hasher()
self.length = 0
@ -59,7 +58,7 @@ class Output:
crypttext_leaves = {self._segment_number: ch.digest()}
self._crypttext_hash_tree.set_hashes(leaves=crypttext_leaves)
plaintext = self._decryptor.decrypt(crypttext)
plaintext = self._decryptor.process(crypttext)
del crypttext
# now we're back down to 1*segment_size.

View File

@ -8,10 +8,10 @@ from foolscap.eventual import eventually
from allmydata.interfaces import IMutableFileNode, IMutableFileURI
from allmydata.util import hashutil, mathutil, idlib, log
from allmydata.uri import WriteableSSKFileURI
from allmydata.Crypto.Cipher import AES
from allmydata import hashtree, codec
from allmydata.encode import NotEnoughPeersError
from pycryptopp.publickey import rsa
from pycryptopp.cipher.aes import AES
class NotMutableError(Exception):
@ -400,6 +400,7 @@ class Retrieve:
if not self._pubkey:
fingerprint = hashutil.ssk_pubkey_fingerprint_hash(pubkey_s)
assert len(fingerprint) == 32
if fingerprint != self._node._fingerprint:
raise CorruptShareError(peerid, shnum,
"pubkey doesn't match fingerprint")
@ -682,8 +683,8 @@ class Retrieve:
def _decrypt(self, crypttext, IV, seqnum, root_hash):
key = hashutil.ssk_readkey_data_hash(IV, self._readkey)
decryptor = AES.new(key=key, mode=AES.MODE_CTR, counterstart="\x00"*16)
plaintext = decryptor.decrypt(crypttext)
decryptor = AES(key)
plaintext = decryptor.process(crypttext)
# it worked, so record the seqnum and root_hash for next time
self._node._populate_seqnum(seqnum)
self._node._populate_root_hash(root_hash)
@ -1016,8 +1017,8 @@ class Publish:
self.log("_encrypt_and_encode")
key = hashutil.ssk_readkey_data_hash(IV, readkey)
enc = AES.new(key=key, mode=AES.MODE_CTR, counterstart="\x00"*16)
crypttext = enc.encrypt(newdata)
enc = AES(key)
crypttext = enc.process(newdata)
assert len(crypttext) == len(newdata)
# now apply FEC
@ -1320,13 +1321,13 @@ class MutableFileNode:
return d
def _encrypt_privkey(self, writekey, privkey):
enc = AES.new(key=writekey, mode=AES.MODE_CTR, counterstart="\x00"*16)
crypttext = enc.encrypt(privkey)
enc = AES(writekey)
crypttext = enc.process(privkey)
return crypttext
def _decrypt_privkey(self, enc_privkey):
enc = AES.new(key=self._writekey, mode=AES.MODE_CTR, counterstart="\x00"*16)
privkey = enc.decrypt(enc_privkey)
enc = AES(self._writekey)
privkey = enc.process(enc_privkey)
return privkey
def _populate(self, stuff):

View File

@ -13,7 +13,7 @@ from allmydata.util.hashutil import file_renewal_secret_hash, \
from allmydata import encode, storage, hashtree, uri
from allmydata.util import idlib, mathutil
from allmydata.interfaces import IUploadable, IUploader, IEncryptedUploadable
from allmydata.Crypto.Cipher import AES
from pycryptopp.cipher.aes import AES
from cStringIO import StringIO
@ -329,7 +329,7 @@ class EncryptAnUploadable:
d = self.original.get_encryption_key()
def _got(key):
e = AES.new(key=key, mode=AES.MODE_CTR, counterstart="\x00"*16)
e = AES(key)
self._encryptor = e
storage_index = storage_index_chk_hash(key)
@ -390,7 +390,7 @@ class EncryptAnUploadable:
chunk = data.pop(0)
self._plaintext_hasher.update(chunk)
self._update_segment_hash(chunk)
cryptdata.append(self._encryptor.encrypt(chunk))
cryptdata.append(self._encryptor.process(chunk))
del chunk
return cryptdata
d.addCallback(_got)

View File

@ -123,9 +123,9 @@ def hmac(tag, data):
return h2
def mutable_rwcap_key_hash(iv, writekey):
return tagged_pair_hash("allmydata_mutable_rwcap_key_v1", iv, writekey)
return tagged_pair_hash("allmydata_mutable_rwcap_key_v1", iv, writekey)[:16]
def ssk_writekey_hash(privkey):
return tagged_hash("allmydata_mutable_writekey_v1", privkey)
return tagged_hash("allmydata_mutable_writekey_v1", privkey)[:16]
def ssk_write_enabler_master_hash(writekey):
return tagged_hash("allmydata_mutable_write_enabler_master_v1", writekey)
def ssk_write_enabler_hash(writekey, peerid):
@ -137,8 +137,8 @@ def ssk_pubkey_fingerprint_hash(pubkey):
return tagged_hash("allmydata_mutable_pubkey_v1", pubkey)
def ssk_readkey_hash(writekey):
return tagged_hash("allmydata_mutable_readkey_v1", writekey)
return tagged_hash("allmydata_mutable_readkey_v1", writekey)[:16]
def ssk_readkey_data_hash(IV, readkey):
return tagged_pair_hash("allmydata_mutable_readkey_data_v1", IV, readkey)
return tagged_pair_hash("allmydata_mutable_readkey_data_v1", IV, readkey)[:16]
def ssk_storage_index_hash(readkey):
return tagged_hash("allmydata_mutable_storage_index_v1", readkey)[:16]