commit 7b562f53fb02f930b3c43f1571a90f6634df0664 Author: George Kadianakis desnacked@riseup.net Date: Sat Apr 26 19:14:51 2014 +0100
Make sure that AES-CTR counter of obfs{2,3} won't overflow. --- ChangeLog | 4 ++++ obfsproxy/common/aes.py | 11 ++++++++--- obfsproxy/transports/obfs2.py | 6 ++++-- obfsproxy/transports/obfs3.py | 3 ++- 4 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/ChangeLog b/ChangeLog index 6cf2400..8c2e76c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,10 @@ Changes in version 0.2.9 - UNRELEASED: explicitly picks python2. Makes obfsproxy work in platforms like Linux Arch where python3 is the default. Fixes part of #11190. Patch by Yawning Angel. + - The AES-CTR counter of obfs2 and obfs3 now wraps around to 0. + Since, the counter value was derived from the protocol, there + was an unlikely chance that PyCrypto would raise an OverflowError + exception. Spotted by Yawning Angel. Fixes #11611.
Changes in version 0.2.8 - 2014-03-28: diff --git a/obfsproxy/common/aes.py b/obfsproxy/common/aes.py index 3f29346..777fad0 100644 --- a/obfsproxy/common/aes.py +++ b/obfsproxy/common/aes.py @@ -9,13 +9,18 @@ from Crypto.Util import Counter class AES_CTR_128(object): """An AES-CTR-128 PyCrypto wrapper."""
- def __init__(self, key, iv): - """Initialize AES with the given key and IV.""" + def __init__(self, key, iv, counter_wraparound=False): + """Initialize AES with the given key and IV. + + If counter_wraparound is set to True, the AES-CTR counter will + wraparound to 0 when it overflows. + """
assert(len(key) == 16) assert(len(iv) == 16)
- self.ctr = Counter.new(128, initial_value=long(iv.encode('hex'), 16)) + self.ctr = Counter.new(128, initial_value=long(iv.encode('hex'), 16), + allow_wraparound=counter_wraparound) self.cipher = AES.new(key, AES.MODE_CTR, counter=self.ctr)
def crypt(self, data): diff --git a/obfsproxy/transports/obfs2.py b/obfsproxy/transports/obfs2.py index f8ba7c9..23a60d4 100644 --- a/obfsproxy/transports/obfs2.py +++ b/obfsproxy/transports/obfs2.py @@ -257,7 +257,8 @@ class Obfs2Transport(base.BaseTransport): secret = self.mac(pad_string, self.initiator_seed + self.responder_seed, self.shared_secret) - return aes.AES_CTR_128(secret[:KEYLEN], secret[KEYLEN:]) + return aes.AES_CTR_128(secret[:KEYLEN], secret[KEYLEN:], + counter_wraparound=True)
def _derive_padding_crypto(self, seed, pad_string): # XXX consider secret_seed """ @@ -266,7 +267,8 @@ class Obfs2Transport(base.BaseTransport): secret = self.mac(pad_string, seed, self.shared_secret) - return aes.AES_CTR_128(secret[:KEYLEN], secret[KEYLEN:]) + return aes.AES_CTR_128(secret[:KEYLEN], secret[KEYLEN:], + counter_wraparound=True)
def mac(self, s, x, secret): """ diff --git a/obfsproxy/transports/obfs3.py b/obfsproxy/transports/obfs3.py index 6a4df6b..ba45da1 100644 --- a/obfsproxy/transports/obfs3.py +++ b/obfsproxy/transports/obfs3.py @@ -221,7 +221,8 @@ class Obfs3Transport(base.BaseTransport): Derive and return an obfs3 key using the pad string in 'pad_string'. """ secret = hmac_sha256.hmac_sha256_digest(self.shared_secret, pad_string) - return aes.AES_CTR_128(secret[:KEYLEN], secret[KEYLEN:]) + return aes.AES_CTR_128(secret[:KEYLEN], secret[KEYLEN:], + counter_wraparound=True)
class Obfs3Client(Obfs3Transport):
tor-commits@lists.torproject.org