]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/commitdiff
use AES from pycryptopp instead of pycrypto, also truncate the keys slightly differently
authorBrian Warner <warner@allmydata.com>
Tue, 4 Dec 2007 00:27:46 +0000 (17:27 -0700)
committerBrian Warner <warner@allmydata.com>
Tue, 4 Dec 2007 00:27:46 +0000 (17:27 -0700)
calcdeps.py
docs/mutable.txt
src/allmydata/dirnode2.py
src/allmydata/download.py
src/allmydata/mutable.py
src/allmydata/upload.py
src/allmydata/util/hashutil.py

index d5adc97546053b8f03450abb5760070a474a5126..53c1358ab402bad7b0511540238e40ddaf6addb0 100644 (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",
                   ]
 
 
index ee01d0449ac775ee1e54caea728d10a322f51da9..858f804352009f0ce5b72d070bfe802dd82b111e 100644 (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".
 
index 5a1cecdb8e76b328c479bdaddfb12791395e6cca..9b5e630d0dc15bd629aac4f992759e98a73d91ca 100644 (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):
index 888346672393eb28d1547f7fb75122beb7ecc04b..a0a0367ec3f15278d5e2ed4ded7997eeb4820a1e 100644 (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.
index c8fa347fe6916120551b51d7f1fd037ac618ce98..29e1ba2a3f8c41269103e15f487f9f642479a13f 100644 (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):
index 496568c7e11a807120996b8f887cf948fd9b10b5..972de770fa8ecf54aa3b96f8cb8759879134f3b2 100644 (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)
index 5bac1ae210f72cd1d3254f28e4a0dff4e878f591..98d5f1519e5ef885000bddc2fcf3bc4da85a1caf 100644 (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]