]> granicus.if.org Git - transmission/commitdiff
#4400, #5462: Move DH helpers to crypto-utils
authorMike Gelfand <mikedld@mikedld.com>
Thu, 4 Dec 2014 19:18:08 +0000 (19:18 +0000)
committerMike Gelfand <mikedld@mikedld.com>
Thu, 4 Dec 2014 19:18:08 +0000 (19:18 +0000)
On a way to factoring out OpenSSL support to a standalone file to ease
addition of other crypto libraries support in the future, move helpers
providing DH key exchange to crypto-utils.{c,h}. OpenSSL-related
functionality (DH context management) is moved to crypto-utils-openssl.c.
Since we know in advance that DH secret key management code will be the
same for most of backends, implement common functionality in separate
crypto-utils-fallback.c.

Add new tr_dh_ctx_t and tr_dh_secret_t types and functions to be
implemented by crypto backends:
* tr_dh_new - allocate DH context,
* tr_dh_free - free the context,
* tr_dh_make_key - generate private/public keypair,
* tr_dh_agree - perform DH key exchange and generate secret key,
* tr_dh_secret_derive - calculate secret key hash,
* tr_dh_secret_free - free the secret key,
* tr_dh_align_key - align some DH key in the buffer allocated for it.

Make DH secret key not accessible in plain form outside the crypto
backend. This allows for implementations where the key is managed by
the underlying library and is not even exposed to our backend.

libtransmission/CMakeLists.txt
libtransmission/Makefile.am
libtransmission/crypto-test.c
libtransmission/crypto-utils-fallback.c [new file with mode: 0644]
libtransmission/crypto-utils-openssl.c
libtransmission/crypto-utils.c
libtransmission/crypto-utils.h
libtransmission/crypto.c
libtransmission/crypto.h
libtransmission/handshake.c

index 30ff96022362cd4b5866a00a8a376a18885e2245..5da288eb3a3290ac6aaad69356db69d0a4f69c30 100644 (file)
@@ -15,6 +15,7 @@ set(${PROJECT_NAME}_SOURCES
     ConvertUTF.c
     crypto.c
     crypto-utils.c
+    crypto-utils-fallback.c
     crypto-utils-openssl.c
     error.c
     fdlimit.c
index 8ddc21d306bed6c5c947c852cc72534313c8cdfd..712ce217a731c913bdef606ebe2c0c55b8e65e36 100644 (file)
@@ -29,6 +29,7 @@ libtransmission_a_SOURCES = \
   ConvertUTF.c \
   crypto.c \
   crypto-utils.c \
+  crypto-utils-fallback.c \
   crypto-utils-openssl.c \
   error.c \
   fdlimit.c \
index df283b0085a39b555dc260d7cc45ac5476499bdf..697686897704f9ac81c704afc221134f238aaa16 100644 (file)
@@ -73,8 +73,8 @@ test_encrypt_decrypt (void)
 
   tr_cryptoConstruct (&a, hash, false);
   tr_cryptoConstruct (&b, hash, true);
-  tr_cryptoComputeSecret (&a, tr_cryptoGetMyPublicKey (&b, &i));
-  tr_cryptoComputeSecret (&b, tr_cryptoGetMyPublicKey (&a, &i));
+  check (tr_cryptoComputeSecret (&a, tr_cryptoGetMyPublicKey (&b, &i)));
+  check (tr_cryptoComputeSecret (&b, tr_cryptoGetMyPublicKey (&a, &i)));
 
   tr_cryptoEncryptInit (&a);
   tr_cryptoEncrypt (&a, sizeof (test1), test1, buf11);
diff --git a/libtransmission/crypto-utils-fallback.c b/libtransmission/crypto-utils-fallback.c
new file mode 100644 (file)
index 0000000..e06bc92
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * This file Copyright (C) Mnemosyne LLC
+ *
+ * It may be used under the GNU GPL versions 2 or 3
+ * or any future license endorsed by Mnemosyne LLC.
+ *
+ * $Id$
+ */
+
+/* This file is designed specifically to be included by other source files to
+   implement missing (or duplicate) functionality without exposing internal
+   details in header files. */
+
+#include <assert.h>
+
+#include "transmission.h"
+#include "crypto-utils.h"
+#include "utils.h"
+
+/***
+****
+***/
+
+#ifdef TR_CRYPTO_DH_SECRET_FALLBACK
+
+/* Most Diffie-Hellman backends handle secret key in the very same way: by
+   manually allocating memory for it and storing the value in plain form. */
+
+struct tr_dh_secret
+{
+  size_t  key_length;
+  uint8_t key[];
+};
+
+static struct tr_dh_secret *
+tr_dh_secret_new (size_t key_length)
+{
+  struct tr_dh_secret * handle = tr_malloc (sizeof (struct tr_dh_secret) + key_length);
+  handle->key_length = key_length;
+  return handle;
+}
+
+static void
+tr_dh_secret_align (struct tr_dh_secret * handle,
+                    size_t                current_key_length)
+{
+  tr_dh_align_key (handle->key, current_key_length, handle->key_length);
+}
+
+bool
+tr_dh_secret_derive (tr_dh_secret_t   raw_handle,
+                     const void     * prepend_data,
+                     size_t           prepend_data_size,
+                     const void     * append_data,
+                     size_t           append_data_size,
+                     uint8_t        * hash)
+{
+  struct tr_dh_secret * handle = raw_handle;
+
+  assert (handle != NULL);
+  assert (hash != NULL);
+
+  return tr_sha1 (hash,
+                  prepend_data == NULL ? "" : prepend_data,
+                  prepend_data == NULL ? 0 : (int) prepend_data_size,
+                  handle->key, (int) handle->key_length,
+                  append_data, append_data == NULL ? 0 : (int) append_data_size,
+                  NULL);
+}
+
+void
+tr_dh_secret_free (tr_dh_secret_t handle)
+{
+  tr_free (handle);
+}
+
+#endif /* TR_CRYPTO_DH_SECRET_FALLBACK */
index 0270b17b3b11636221e5366bd13671ed591c5ebd..2245f153f3764bbed4b150b29d07fe2fd9167a84 100644 (file)
@@ -9,6 +9,8 @@
 
 #include <assert.h>
 
+#include <openssl/bn.h>
+#include <openssl/dh.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/rand.h>
@@ -18,6 +20,9 @@
 #include "log.h"
 #include "utils.h"
 
+#define TR_CRYPTO_DH_SECRET_FALLBACK
+#include "crypto-utils-fallback.c"
+
 /***
 ****
 ***/
@@ -193,6 +198,101 @@ tr_rc4_process (tr_rc4_ctx_t   handle,
 ****
 ***/
 
+tr_dh_ctx_t
+tr_dh_new (const uint8_t * prime_num,
+           size_t          prime_num_length,
+           const uint8_t * generator_num,
+           size_t          generator_num_length)
+{
+  DH * handle = DH_new ();
+
+  assert (prime_num != NULL);
+  assert (generator_num != NULL);
+
+  if (!check_pointer (handle->p = BN_bin2bn (prime_num, prime_num_length, NULL)) ||
+      !check_pointer (handle->g = BN_bin2bn (generator_num, generator_num_length, NULL)))
+    {
+      DH_free (handle);
+      handle = NULL;
+    }
+
+  return handle;
+}
+
+void
+tr_dh_free (tr_dh_ctx_t handle)
+{
+  if (handle == NULL)
+    return;
+
+  DH_free (handle);
+}
+
+bool
+tr_dh_make_key (tr_dh_ctx_t   raw_handle,
+                size_t        private_key_length,
+                uint8_t     * public_key,
+                size_t      * public_key_length)
+{
+  DH * handle = raw_handle;
+  int dh_size, my_public_key_length;
+
+  assert (handle != NULL);
+  assert (public_key != NULL);
+
+  handle->length = private_key_length * 8;
+
+  if (!check_result (DH_generate_key (handle)))
+    return false;
+
+  my_public_key_length = BN_bn2bin (handle->pub_key, public_key);
+  dh_size = DH_size (handle);
+
+  tr_dh_align_key (public_key, my_public_key_length, dh_size);
+
+  if (public_key_length != NULL)
+    *public_key_length = dh_size;
+
+  return true;
+}
+
+tr_dh_secret_t
+tr_dh_agree (tr_dh_ctx_t     handle,
+             const uint8_t * other_public_key,
+             size_t          other_public_key_length)
+{
+  struct tr_dh_secret * ret;
+  int dh_size, secret_key_length;
+  BIGNUM * other_key;
+
+  assert (handle != NULL);
+  assert (other_public_key != NULL);
+
+  if (!check_pointer (other_key = BN_bin2bn (other_public_key, other_public_key_length, NULL)))
+    return NULL;
+
+  dh_size = DH_size (handle);
+  ret = tr_dh_secret_new (dh_size);
+
+  secret_key_length = DH_compute_key (ret->key, other_key, handle);
+  if (check_result_neq (secret_key_length, -1))
+    {
+      tr_dh_secret_align (ret, secret_key_length);
+    }
+  else
+    {
+      tr_dh_secret_free (ret);
+      ret = NULL;
+    }
+
+  BN_free (other_key);
+  return ret;
+}
+
+/***
+****
+***/
+
 bool
 tr_rand_buffer (void   * buffer,
                 size_t   length)
index f6f0273ab1c8f12f906943d1d02bb20aadb74576..a11cdee531a42af374e202aefa7210cee91d74f8 100644 (file)
@@ -10,6 +10,7 @@
 #include <assert.h>
 #include <stdarg.h>
 #include <stdlib.h> /* abs (), srand (), rand () */
+#include <string.h> /* memmove (), memset () */
 
 #include "transmission.h"
 #include "crypto-utils.h"
 ****
 ***/
 
+void
+tr_dh_align_key (uint8_t * key_buffer,
+                 size_t    key_size,
+                 size_t    buffer_size)
+{
+  assert (key_size <= buffer_size);
+
+  /* DH can generate key sizes that are smaller than the size of
+     key buffer with exponentially decreasing probability, in which case
+     the msb's of key buffer need to be zeroed appropriately. */
+  if (key_size < buffer_size)
+    {
+      const size_t offset = buffer_size - key_size;
+      memmove (key_buffer + offset, key_buffer, key_size);
+      memset (key_buffer, 0, offset);
+    }
+}
+
+/***
+****
+***/
+
 bool
 tr_sha1 (uint8_t    * hash,
          const void * data1,
index 024728780622c86f8f0061146aed0cfc9bb7fc0a..3091443b61c251c1ef81e591fae89a472ccd80e9 100644 (file)
 typedef void * tr_sha1_ctx_t;
  /** @brief Opaque RC4 context type. */
 typedef void * tr_rc4_ctx_t;
+ /** @brief Opaque DH context type. */
+typedef void * tr_dh_ctx_t;
+ /** @brief Opaque DH secret key type. */
+typedef void * tr_dh_secret_t;
 
 /**
  * @brief Generate a SHA1 hash from one or more chunks of memory.
@@ -76,6 +80,57 @@ void             tr_rc4_process        (tr_rc4_ctx_t     handle,
                                         void           * output,
                                         size_t           length);
 
+/**
+ * @brief Allocate and initialize new Diffie-Hellman (DH) key exchange context.
+ */
+tr_dh_ctx_t      tr_dh_new             (const uint8_t  * prime_num,
+                                        size_t           prime_num_length,
+                                        const uint8_t  * generator_num,
+                                        size_t           generator_num_length);
+
+/**
+ * @brief Free DH key exchange context.
+ */
+void             tr_dh_free            (tr_dh_ctx_t      handle);
+
+/**
+ * @brief Generate private and public DH keys, export public key.
+ */
+bool             tr_dh_make_key        (tr_dh_ctx_t      handle,
+                                        size_t           private_key_length,
+                                        uint8_t        * public_key,
+                                        size_t         * public_key_length);
+
+/**
+ * @brief Perform DH key exchange, generate secret key.
+ */
+tr_dh_secret_t   tr_dh_agree           (tr_dh_ctx_t      handle,
+                                        const uint8_t  * other_public_key,
+                                        size_t           other_public_key_length);
+
+/**
+ * @brief Calculate SHA1 hash of DH secret key, prepending and/or appending
+ *        given data to the key during calculation.
+ */
+bool             tr_dh_secret_derive   (tr_dh_secret_t   handle,
+                                        const void     * prepend_data,
+                                        size_t           prepend_data_size,
+                                        const void     * append_data,
+                                        size_t           append_data_size,
+                                        uint8_t        * hash);
+
+/**
+ * @brief Free DH secret key returned by @ref tr_dh_agree.
+ */
+void             tr_dh_secret_free     (tr_dh_secret_t   handle);
+
+/**
+ * @brief Align DH key (big-endian number) to required length (internal, do not use).
+ */
+void             tr_dh_align_key       (uint8_t        * key_buffer,
+                                        size_t           key_size,
+                                        size_t           buffer_size);
+
 /**
  * @brief Returns a random number in the range of [0...upper_bound).
  */
index 974bd3d543a37ea15eea5550c980a37a1da3a103..d7ece443270705d2cda0f311bc2ffd133f557b20 100644 (file)
@@ -8,30 +8,18 @@
  */
 
 #include <assert.h>
-#include <stdarg.h>
 #include <string.h> /* memcpy (), memmove (), memset (), strcmp () */
 
-#include <openssl/bn.h>
-#include <openssl/dh.h>
-#include <openssl/err.h>
-
 #include "transmission.h"
 #include "crypto.h"
 #include "crypto-utils.h"
-#include "log.h"
 #include "utils.h"
 
-#define MY_NAME "tr_crypto"
-
 /**
 ***
 **/
 
-#define KEY_LEN 96
-
 #define PRIME_LEN 96
-
-#define DH_PRIVKEY_LEN_MIN 16
 #define DH_PRIVKEY_LEN 20
 
 static const uint8_t dh_P[PRIME_LEN] =
@@ -52,53 +40,17 @@ static const uint8_t dh_G[] = { 2 };
 ***
 **/
 
-#define logErrorFromSSL(...) \
-  do { \
-    if (tr_logLevelIsActive (TR_LOG_ERROR)) { \
-      char buf[512]; \
-      ERR_error_string_n (ERR_get_error (), buf, sizeof (buf)); \
-      tr_logAddMessage (__FILE__, __LINE__, TR_LOG_ERROR, MY_NAME, "%s", buf); \
-    } \
-  } while (0)
-
 static void
 ensureKeyExists (tr_crypto * crypto)
 {
   if (crypto->dh == NULL)
     {
-      int len, offset;
-      DH * dh = DH_new ();
-
-      dh->p = BN_bin2bn (dh_P, sizeof (dh_P), NULL);
-      if (dh->p == NULL)
-        logErrorFromSSL ();
-
-      dh->g = BN_bin2bn (dh_G, sizeof (dh_G), NULL);
-      if (dh->g == NULL)
-        logErrorFromSSL ();
-
-      /* private DH value: strong random BN of DH_PRIVKEY_LEN*8 bits */
-      dh->priv_key = BN_new ();
-      do
-        {
-          if (BN_rand (dh->priv_key, DH_PRIVKEY_LEN * 8, -1, 0) != 1)
-            logErrorFromSSL ();
-        }
-      while (BN_num_bits (dh->priv_key) < DH_PRIVKEY_LEN_MIN * 8);
-
-      if (!DH_generate_key (dh))
-        logErrorFromSSL ();
-
-      /* DH can generate key sizes that are smaller than the size of
-         P with exponentially decreasing probability, in which case
-         the msb's of myPublicKey need to be zeroed appropriately. */
-      len = BN_num_bytes (dh->pub_key);
-      offset = KEY_LEN - len;
-      assert (len <= KEY_LEN);
-      memset (crypto->myPublicKey, 0, offset);
-      BN_bn2bin (dh->pub_key, crypto->myPublicKey + offset);
-
-      crypto->dh = dh;
+      size_t public_key_length;
+
+      crypto->dh = tr_dh_new (dh_P, sizeof (dh_P), dh_G, sizeof (dh_G));
+      tr_dh_make_key (crypto->dh, DH_PRIVKEY_LEN, crypto->myPublicKey, &public_key_length);
+
+      assert (public_key_length == KEY_LEN);
     }
 }
 
@@ -107,7 +59,6 @@ tr_cryptoConstruct (tr_crypto * crypto, const uint8_t * torrentHash, bool isInco
 {
   memset (crypto, 0, sizeof (tr_crypto));
 
-  crypto->dh = NULL;
   crypto->isIncoming = isIncoming;
   tr_cryptoSetTorrentHash (crypto, torrentHash);
 }
@@ -115,8 +66,8 @@ tr_cryptoConstruct (tr_crypto * crypto, const uint8_t * torrentHash, bool isInco
 void
 tr_cryptoDestruct (tr_crypto * crypto)
 {
-  if (crypto->dh != NULL)
-    DH_free (crypto->dh);
+  tr_dh_secret_free (crypto->mySecret);
+  tr_dh_free (crypto->dh);
   tr_rc4_free (crypto->enc_key);
   tr_rc4_free (crypto->dec_key);
 }
@@ -125,37 +76,13 @@ tr_cryptoDestruct (tr_crypto * crypto)
 ***
 **/
 
-const uint8_t*
+bool
 tr_cryptoComputeSecret (tr_crypto *     crypto,
                         const uint8_t * peerPublicKey)
 {
-  DH * dh;
-  int len;
-  uint8_t secret[KEY_LEN];
-  BIGNUM * bn = BN_bin2bn (peerPublicKey, KEY_LEN, NULL);
-
   ensureKeyExists (crypto);
-  dh = crypto->dh;
-
-  assert (DH_size (dh) == KEY_LEN);
-
-  len = DH_compute_key (secret, bn, dh);
-  if (len == -1)
-    {
-      logErrorFromSSL ();
-    }
-  else
-    {
-      int offset;
-      assert (len <= KEY_LEN);
-      offset = KEY_LEN - len;
-      memset (crypto->mySecret, 0, offset);
-      memcpy (crypto->mySecret + offset, secret, len);
-      crypto->mySecretIsSet = true;
-    }
-
-  BN_free (bn);
-  return crypto->mySecret;
+  crypto->mySecret = tr_dh_agree (crypto->dh, peerPublicKey, KEY_LEN);
+  return crypto->mySecret != NULL;
 }
 
 const uint8_t*
@@ -179,16 +106,14 @@ initRC4 (tr_crypto    * crypto,
   uint8_t buf[SHA_DIGEST_LENGTH];
 
   assert (crypto->torrentHashIsSet);
-  assert (crypto->mySecretIsSet);
 
   if (*setme == NULL)
     *setme = tr_rc4_new ();
 
-  if (tr_sha1 (buf,
-               key, 4,
-               crypto->mySecret, KEY_LEN,
-               crypto->torrentHash, SHA_DIGEST_LENGTH,
-               NULL))
+  if (tr_cryptoSecretKeySha1 (crypto,
+                              key, 4,
+                              crypto->torrentHash, SHA_DIGEST_LENGTH,
+                              buf))
     tr_rc4_set_key (*setme, buf, SHA_DIGEST_LENGTH);
 }
 
@@ -246,6 +171,23 @@ tr_cryptoEncrypt (tr_crypto  * crypto,
   tr_rc4_process (crypto->enc_key, buf_in, buf_out, buf_len);
 }
 
+bool
+tr_cryptoSecretKeySha1 (const tr_crypto * crypto,
+                        const void      * prepend_data,
+                        size_t            prepend_data_size,
+                        const void      * append_data,
+                        size_t            append_data_size,
+                        uint8_t         * hash)
+{
+  assert (crypto != NULL);
+  assert (crypto->mySecret != NULL);
+
+  return tr_dh_secret_derive (crypto->mySecret,
+                              prepend_data, prepend_data_size,
+                              append_data, append_data_size,
+                              hash);
+}
+
 /**
 ***
 **/
index 2a0baf554e67b6c161a231fe12f055daf68ebb52..d7c093338e471dba4a163d1956b3c5649e5c04f8 100644 (file)
 *** @{
 **/
 
-#include <openssl/dh.h> /* DH */
-
 enum
 {
-    KEY_LEN = 96
+  KEY_LEN = 96
 };
 
 /** @brief Holds state information for encrypted peer communications */
@@ -36,13 +34,12 @@ typedef struct
 {
     tr_rc4_ctx_t    dec_key;
     tr_rc4_ctx_t    enc_key;
-    DH *            dh;
+    tr_dh_ctx_t     dh;
     uint8_t         myPublicKey[KEY_LEN];
-    uint8_t         mySecret[KEY_LEN];
+    tr_dh_secret_t  mySecret;
     uint8_t         torrentHash[SHA_DIGEST_LENGTH];
     bool            isIncoming;
     bool            torrentHashIsSet;
-    bool            mySecretIsSet;
 }
 tr_crypto;
 
@@ -59,7 +56,7 @@ const uint8_t* tr_cryptoGetTorrentHash (const tr_crypto * crypto);
 
 bool           tr_cryptoHasTorrentHash (const tr_crypto * crypto);
 
-const uint8_t* tr_cryptoComputeSecret (tr_crypto *     crypto,
+bool           tr_cryptoComputeSecret (tr_crypto *     crypto,
                                        const uint8_t * peerPublicKey);
 
 const uint8_t* tr_cryptoGetMyPublicKey (const tr_crypto * crypto,
@@ -79,6 +76,13 @@ void           tr_cryptoEncrypt (tr_crypto *  crypto,
                                  const void * buf_in,
                                  void *       buf_out);
 
+bool           tr_cryptoSecretKeySha1 (const tr_crypto * crypto,
+                                       const void      * prepend_data,
+                                       size_t            prepend_data_size,
+                                       const void      * append_data,
+                                       size_t            append_data_size,
+                                       uint8_t         * hash);
+
 /* @} */
 
 /**
index 25c91b8623b21ab7eba8713ce72dd773ffc7ec50..c307f2f3d0d0224764aeae14307a829ce0ea632c 100644 (file)
@@ -101,7 +101,6 @@ struct tr_handshake
   tr_peerIo *           io;
   tr_crypto *           crypto;
   tr_session *          session;
-  uint8_t               mySecret[KEY_LEN];
   handshake_state_t     state;
   tr_encryption_mode    encryptionMode;
   uint16_t              pad_c_len;
@@ -385,11 +384,18 @@ getCryptoSelect (const tr_handshake * handshake,
   return 0;
 }
 
+static void
+computeRequestHash (const tr_handshake * handshake,
+                    const char         * name,
+                    uint8_t            * hash)
+{
+  tr_cryptoSecretKeySha1 (handshake->crypto, name, 4, NULL, 0, hash);
+}
+
 static int
 readYb (tr_handshake * handshake, struct evbuffer * inbuf)
 {
   int isEncrypted;
-  const uint8_t * secret;
   uint8_t yb[KEY_LEN];
   struct evbuffer * outbuf;
   size_t needlen = HANDSHAKE_NAME_LEN;
@@ -420,8 +426,7 @@ readYb (tr_handshake * handshake, struct evbuffer * inbuf)
 
   /* compute the secret */
   evbuffer_remove (inbuf, yb, KEY_LEN);
-  secret = tr_cryptoComputeSecret (handshake->crypto, yb);
-  memcpy (handshake->mySecret, secret, KEY_LEN);
+  tr_cryptoComputeSecret (handshake->crypto, yb);
 
   /* now send these: HASH ('req1', S), HASH ('req2', SKEY) xor HASH ('req3', S),
    * ENCRYPT (VC, crypto_provide, len (PadC), PadC, len (IA)), ENCRYPT (IA) */
@@ -430,7 +435,7 @@ readYb (tr_handshake * handshake, struct evbuffer * inbuf)
   /* HASH ('req1', S) */
   {
     uint8_t req1[SHA_DIGEST_LENGTH];
-    tr_sha1 (req1, "req1", 4, secret, KEY_LEN, NULL);
+    computeRequestHash (handshake, "req1", req1);
     evbuffer_add (outbuf, req1, SHA_DIGEST_LENGTH);
   }
 
@@ -442,7 +447,7 @@ readYb (tr_handshake * handshake, struct evbuffer * inbuf)
     uint8_t buf[SHA_DIGEST_LENGTH];
 
     tr_sha1 (req2, "req2", 4, tr_cryptoGetTorrentHash (handshake->crypto), SHA_DIGEST_LENGTH, NULL);
-    tr_sha1 (req3, "req3", 4, secret, KEY_LEN, NULL);
+    computeRequestHash (handshake, "req3", req3);
 
     for (i=0; i<SHA_DIGEST_LENGTH; ++i)
       buf[i] = req2[i] ^ req3[i];
@@ -728,7 +733,6 @@ readYa (tr_handshake    * handshake,
   uint8_t ya[KEY_LEN];
   uint8_t * walk, outbuf[KEY_LEN + PadB_MAXLEN];
   const uint8_t * myKey;
-  const uint8_t * secret;
   int len;
 
   dbgmsg (handshake, "in readYa... need %d, have %"TR_PRIuSIZE,
@@ -738,9 +742,8 @@ readYa (tr_handshake    * handshake,
 
   /* read the incoming peer's public key */
   evbuffer_remove (inbuf, ya, KEY_LEN);
-  secret = tr_cryptoComputeSecret (handshake->crypto, ya);
-  memcpy (handshake->mySecret, secret, KEY_LEN);
-  tr_sha1 (handshake->myReq1, "req1", 4, secret, KEY_LEN, NULL);
+  tr_cryptoComputeSecret (handshake->crypto, ya);
+  computeRequestHash (handshake, "req1", handshake->myReq1);
 
   /* send our public key to the peer */
   dbgmsg (handshake, "sending B->A: Diffie Hellman Yb, PadB");
@@ -810,7 +813,7 @@ readCryptoProvide (tr_handshake    * handshake,
    * by building the latter and xor'ing it with what the peer sent us */
   dbgmsg (handshake, "reading obfuscated torrent hash...");
   evbuffer_remove (inbuf, req2, SHA_DIGEST_LENGTH);
-  tr_sha1 (req3, "req3", 4, handshake->mySecret, KEY_LEN, NULL);
+  computeRequestHash (handshake, "req3", req3);
   for (i=0; i<SHA_DIGEST_LENGTH; ++i)
     obfuscatedTorrentHash[i] = req2[i] ^ req3[i];
   if ((tor = tr_torrentFindFromObfuscatedHash (handshake->session, obfuscatedTorrentHash)))