[tor-commits] [obfsproxy/master] Implemented iterated hashing and updated the protocol spec.

nickm at torproject.org nickm at torproject.org
Sun May 29 01:33:38 UTC 2011


commit d63d9d56a0da3a51aa7ec599635ec8a02ab0c8cb
Author: George Kadianakis <desnacked at gmail.com>
Date:   Wed May 25 02:13:37 2011 +0200

    Implemented iterated hashing and updated the protocol spec.
---
 doc/protocol-spec.txt |   28 ++++++++++++++++++----------
 src/protocols/obfs2.c |   21 ++++++++++++++++++++-
 src/protocols/obfs2.h |    1 +
 3 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/doc/protocol-spec.txt b/doc/protocol-spec.txt
index 9a7d4fa..0f9edf9 100644
--- a/doc/protocol-spec.txt
+++ b/doc/protocol-spec.txt
@@ -27,9 +27,10 @@ The Twobfuscator
     s[:n] is the first n bytes of s.
     s[n:] is the last n bytes of s.
 
-    MAGIC_VALUE  is  0x2BF5CA7E
-    SEED_LENGTH  is  16
-    MAX_PADDING  is  8192
+    MAGIC_VALUE      is  0x2BF5CA7E
+    SEED_LENGTH      is  16
+    MAX_PADDING      is  8192
+    HASH_ITERATIONS  is  100000
 
     KEYLEN is the length of the key used by E_K(s) -- that is, 16.
     IVLEN is the length of the IV used by E_K(s) -- that is, 16
@@ -38,6 +39,9 @@ The Twobfuscator
 
     MAC(s, x) = H(s | x | s)
 
+    Let n = HASH_ITERATIONS through section '2. Key establishment phase.'.
+    Then, H^n(x) is H(x) called iteratively n times. 
+
     A "byte" is an 8-bit octet.
 
     We require that HASHLEN >= KEYLEN + IVLEN
@@ -49,12 +53,14 @@ The Twobfuscator
    a padding key as follows.  The initiator generates:
 
     INIT_SEED = SR(SEED_LENGTH)
-    INIT_PAD_KEY = MAC("Initiator obfuscation padding", INIT_SEED)[:KEYLEN]
+    INIT_PAD_TEMP = MAC("Initiator obfuscation padding", INIT_SEED)[:KEYLEN]
+    INIT_PAD_KEY = H^n(INIT_PAD_TEMP)
 
    And the responder generates:
 
     RESP_SEED = SR(SEED_LENGTH)
-    RESP_PAD_KEY = MAC("Responder obfuscation padding", INIT_SEED)[:KEYLEN]
+    RESP_PAD_TEMP = MAC("Responder obfuscation padding", INIT_SEED)[:KEYLEN]
+    RESP_PAD_KEY = H^n(RESP_PAD_TEMP)
 
    Each then generates a random number PADLEN in range from 0 through
    MAX_PADDING (inclusive), and sends:
@@ -73,10 +79,12 @@ The Twobfuscator
 
      INIT_SECRET = MAC("Initiator obfuscated data", INIT_SEED|RESP_SEED)
      RESP_SECRET = MAC("Responder obfuscated data", INIT_SEED|RESP_SEED)
-     INIT_KEY = INIT_SECRET[:KEYLEN]
-     INIT_IV = INIT_SECRET[KEYLEN:]
-     RESP_KEY = RESP_SECRET[:KEYLEN]
-     RESP_IV = RESP_SECRET[KEYLEN:]
+     INIT_MASTER_KEY = H^n(INIT_SECRET)
+     RESP_MASTER_KEY = H^n(RESP_SECRET)
+     INIT_KEY = INIT_MASTER_KEY[:KEYLEN]
+     INIT_IV = INIT_MASTER_KEY[KEYLEN:]
+     RESP_KEY = RESP_MASTER_KEY[:KEYLEN]
+     RESP_IV = RESP_MASTER_KEY[KEYLEN:]
 
    The INIT_KEY value keys a stream cipher used to encrypt values from
    initiator to responder thereafter.  The stream cipher's IV is
@@ -89,5 +97,5 @@ The Twobfuscator
    Optionally, if the client and server share a secret value SECRET,
    they can replace the MAC function with:
 
-      MAC(s,x) = MAC(s | x | SECRET | s)
+      MAC(s,x) = H(s | x | SECRET | s)
 
diff --git a/src/protocols/obfs2.c b/src/protocols/obfs2.c
index 3490d0e..6221bb2 100644
--- a/src/protocols/obfs2.c
+++ b/src/protocols/obfs2.c
@@ -72,10 +72,12 @@ static crypt_t *
 derive_key(void *s, const char *keytype)
 {
   obfs2_state_t *state = s;
-
   crypt_t *cryptstate;
   uchar buf[SHA256_LENGTH];
   digest_t *c = digest_new();
+  digest_t *d;
+  int i;
+
   digest_update(c, (uchar*)keytype, strlen(keytype));
   if (seed_nonzero(state->initiator_seed))
     digest_update(c, state->initiator_seed, OBFUSCATE_SEED_LENGTH);
@@ -85,6 +87,13 @@ derive_key(void *s, const char *keytype)
     digest_update(c, state->secret_seed, SHARED_SECRET_LENGTH);
   digest_update(c, (uchar*)keytype, strlen(keytype));
   digest_getdigest(c, buf, sizeof(buf));
+
+  for (i=0; i < OBFUSCATE_HASH_ITERATIONS; i++) {
+    d = digest_new();
+    digest_update(d, buf, sizeof(buf));
+    digest_getdigest(d, buf, sizeof(buf));
+  }
+
   cryptstate = crypt_new(buf, 16);
   crypt_set_iv(cryptstate, buf+16, 16);
   memset(buf, 0, sizeof(buf));
@@ -101,6 +110,9 @@ derive_padding_key(void *s, const uchar *seed,
   crypt_t *cryptstate;
   uchar buf[SHA256_LENGTH];
   digest_t *c = digest_new();
+  digest_t *d;
+  int i;
+
   digest_update(c, (uchar*)keytype, strlen(keytype));
   if (seed_nonzero(seed))
     digest_update(c, seed, OBFUSCATE_SEED_LENGTH);
@@ -108,6 +120,13 @@ derive_padding_key(void *s, const uchar *seed,
     digest_update(c, state->secret_seed, OBFUSCATE_SEED_LENGTH);
   digest_update(c, (uchar*)keytype, strlen(keytype));
   digest_getdigest(c, buf, sizeof(buf));
+
+  for (i=0; i < OBFUSCATE_HASH_ITERATIONS; i++) {
+    d = digest_new();
+    digest_update(d, buf, sizeof(buf));
+    digest_getdigest(d, buf, sizeof(buf));
+  }
+
   cryptstate = crypt_new(buf, 16);
   crypt_set_iv(cryptstate, buf+16, 16);
   memset(buf, 0, 16);
diff --git a/src/protocols/obfs2.h b/src/protocols/obfs2.h
index 1f9f31d..0d70144 100644
--- a/src/protocols/obfs2.h
+++ b/src/protocols/obfs2.h
@@ -36,6 +36,7 @@ void *obfs2_new(struct protocol_t *proto_struct,
 #define OBFUSCATE_SEED_LENGTH        16
 #define OBFUSCATE_MAX_PADDING        8192
 #define OBFUSCATE_ZERO_SEED "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+#define OBFUSCATE_HASH_ITERATIONS     100000
 
 #define INITIATOR_PAD_TYPE "Initiator obfuscation padding"
 #define RESPONDER_PAD_TYPE "Responder obfuscation padding"





More information about the tor-commits mailing list