[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Add kdf_tor function
commit 73ba1f3506d44e8d65c439b404f7cd40eed5ceb9
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Tue Jan 30 11:35:25 2018 -0800
Add kdf_tor function
Supporting KDF-TOR for the CREATE_FAST handshake. Test data is derived from
what endosome's function provides.
---
stem/client/__init__.py | 24 ++++++++++++++++++++++++
stem/client/cell.py | 3 +--
test/settings.cfg | 1 +
test/unit/client/__init__.py | 1 +
test/unit/client/kdf_tor.py | 19 +++++++++++++++++++
5 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index fb0f899d..663bc048 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -12,6 +12,7 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the same way as
::
split - splits bytes into substrings
+ kdf_tor - calculates the derived key using the KDF-TOR protocol
Field - Packable and unpackable datatype.
|- Size - Field of a static size.
@@ -106,6 +107,7 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the same way as
===================== ===========
"""
+import hashlib
import io
import struct
@@ -115,6 +117,8 @@ import stem.util.enum
from stem.util import _hash_attr
ZERO = '\x00'
+HASH_LEN = 20
+KEY_LEN = 16
__all__ = [
'cell',
@@ -457,6 +461,26 @@ class Certificate(Field):
return _hash_attr(self, 'type_int', 'value')
+def kdf_tor(key):
+ """
+ Tor's key derivation function used by TAP, CREATE_FAST handshakes, and hidden
+ service protocols as defined in section 5.2.1 of the tor spec.
+
+ :param bytes key: shared key with endpoint (K0 in the spec)
+
+ :returns: **bytes** with the KDF-TOR of the key
+ """
+
+ derived_key_len = KEY_LEN * 2 + HASH_LEN * 3
+ derived_key, counter = '', 0
+
+ while len(derived_key) < derived_key_len:
+ derived_key += hashlib.sha1(key + Size.CHAR.pack(counter)).digest()
+ counter += 1
+
+ return derived_key[:derived_key_len]
+
+
setattr(Size, 'CHAR', Size('CHAR', 1, '!B'))
setattr(Size, 'SHORT', Size('SHORT', 2, '!H'))
setattr(Size, 'LONG', Size('LONG', 4, '!L'))
diff --git a/stem/client/cell.py b/stem/client/cell.py
index 59fbc14c..9b0c3274 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -47,12 +47,11 @@ import sys
import stem.client
from stem import UNDEFINED
-from stem.client import ZERO, Address, Size, split
+from stem.client import HASH_LEN, ZERO, Address, Size, split
from stem.util import _hash_attr, datetime_to_unix
FIXED_PAYLOAD_LEN = 509
AUTH_CHALLENGE_SIZE = 32
-HASH_LEN = 20
class Cell(object):
diff --git a/test/settings.cfg b/test/settings.cfg
index 518ae2b2..7af57181 100644
--- a/test/settings.cfg
+++ b/test/settings.cfg
@@ -233,6 +233,7 @@ test.unit_tests
|test.unit.client.size.TestSize
|test.unit.client.address.TestAddress
|test.unit.client.certificate.TestCertificate
+|test.unit.client.kdf_tor.TestKdfTor
|test.unit.client.cell.TestCell
|test.unit.connection.authentication.TestAuthenticate
|test.unit.connection.connect.TestConnect
diff --git a/test/unit/client/__init__.py b/test/unit/client/__init__.py
index 7e745352..ba93b3e6 100644
--- a/test/unit/client/__init__.py
+++ b/test/unit/client/__init__.py
@@ -6,6 +6,7 @@ __all__ = [
'address',
'cell',
'certificate',
+ 'kdf_tor',
'size',
]
diff --git a/test/unit/client/kdf_tor.py b/test/unit/client/kdf_tor.py
new file mode 100644
index 00000000..894d4fae
--- /dev/null
+++ b/test/unit/client/kdf_tor.py
@@ -0,0 +1,19 @@
+"""
+Unit tests for stem.client.kdf_tor.
+"""
+
+import unittest
+
+import stem.client
+
+KEY_1 = '\xec\xec.\xeb7R\xf2\n\xcb\xce\x97\xf4\x86\x82\x19#\x10\x0f\x08\xf0\xa2Z\xdeJ\x8f2\x8cc\xf6\xfa\x0e\t\x83f\xc5\xe2\xb3\x94\xa8\x13'
+KEY_2 = '\xe0v\xe4\xfaTB\x91\x1c\x81Gz\xa0\tI\xcb{\xc56\xcfV\xc2\xa0\x19\x9c\x98\x9a\x06\x0e\xc5\xfa\xb0z\x83\xa6\x10\xf6r"<b'
+
+DERIVED_1 = '\xca+\x81\x05\x14\x9d)o\xa6\x82\xe9B\xa8?\xf2\xaf\x85\x1b]6\xac\xcc\xbc\x91\xb1\xaf\xd7\xe0\xe9\x9dF#\xd8\xdbz\xe8\xe6\xca\x83,*\xe5scX\xbb+\xca \xcb\xa4\xbc\xad\x0f\x95\x0cO\xcc\xac\xf1\xc3\xbe\xc9\xe1\xf4\x90f\xdai\xf3\xf3\xf5\x14\xb5\xb9\x03U\xaf\x1e\x1b\xb1q||\x86A<_\xf7\xa0%\x86'
+DERIVED_2 = '\xbc0\xf99\x8e;Te\xbb+\xdb\xabR3l\xb9f?\x07KZC8\xe7\xa15\xd1IS\xd9\xd4\x1e\x96\xf6\xcd\x82\x91\x0b}r\x7f\xc5\xc0\xb1/[\x97dW\xba\x82g\xe7m^\x06[\xe6\xf8\xb4\x83f>c\x8b\x0f\x03\xcc\x98\x1f~t\x88\xe1\x83\xec\xbf*_\x8cF\x0e1\xa9\x17\xce\xa6\xa3\xd1+]\x1f'
+
+
+class TestKdfTor(unittest.TestCase):
+ def test_kdf_tor(self):
+ self.assertEqual(DERIVED_1, stem.client.kdf_tor(KEY_1))
+ self.assertEqual(DERIVED_2, stem.client.kdf_tor(KEY_2))
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits