[tor-commits] [tor/master] Refactor crypto.[ch] into smaller HKDF module.

nickm at torproject.org nickm at torproject.org
Mon Jun 18 00:41:36 UTC 2018


commit d38e7ddf5b930ae7e4d3a5da63cfc32d92a8dfa7
Author: Fernando Fernandez Mancera <ffmancera at riseup.net>
Date:   Fri May 18 10:47:35 2018 +0200

    Refactor crypto.[ch] into smaller HKDF module.
    
    Add two new files (crypto_hkdf.c, crypto_hkdf.h) as new module of crypto.[ch].
    This new module includes all functions and dependencies related to HKDF
    operations.  Those have been removed from crypto.[ch].
    
    Follows #24658.
    
    Signed-off-by: Fernando Fernandez Mancera <ffmancera at riseup.net>
---
 src/common/crypto_dh.c   |  98 +----------------------------------------
 src/common/crypto_dh.h   |   9 ----
 src/common/crypto_hkdf.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++
 src/common/crypto_hkdf.h |  28 ++++++++++++
 src/common/crypto_s2k.c  |   2 +-
 src/common/crypto_util.c |   3 ++
 src/common/include.am    |   2 +
 src/or/onion_ntor.c      |   2 +-
 src/or/or.h              |   1 +
 9 files changed, 149 insertions(+), 108 deletions(-)

diff --git a/src/common/crypto_dh.c b/src/common/crypto_dh.c
index 625a27025..09e6ca506 100644
--- a/src/common/crypto_dh.c
+++ b/src/common/crypto_dh.c
@@ -12,6 +12,7 @@
 #include "compat_openssl.h"
 #include "crypto_dh.h"
 #include "crypto_digest.h"
+#include "crypto_hkdf.h"
 #include "crypto_util.h"
 
 DISABLE_GCC_WARNING(redundant-decls)
@@ -493,103 +494,6 @@ crypto_dh_free_(crypto_dh_t *dh)
   tor_free(dh);
 }
 
-/** Given <b>key_in_len</b> bytes of negotiated randomness in <b>key_in</b>
- * ("K"), expand it into <b>key_out_len</b> bytes of negotiated key material in
- * <b>key_out</b> by taking the first <b>key_out_len</b> bytes of
- *    H(K | [00]) | H(K | [01]) | ....
- *
- * This is the key expansion algorithm used in the "TAP" circuit extension
- * mechanism; it shouldn't be used for new protocols.
- *
- * Return 0 on success, -1 on failure.
- */
-int
-crypto_expand_key_material_TAP(const uint8_t *key_in, size_t key_in_len,
-                               uint8_t *key_out, size_t key_out_len)
-{
-  int i, r = -1;
-  uint8_t *cp, *tmp = tor_malloc(key_in_len+1);
-  uint8_t digest[DIGEST_LEN];
-
-  /* If we try to get more than this amount of key data, we'll repeat blocks.*/
-  tor_assert(key_out_len <= DIGEST_LEN*256);
-
-  memcpy(tmp, key_in, key_in_len);
-  for (cp = key_out, i=0; cp < key_out+key_out_len;
-       ++i, cp += DIGEST_LEN) {
-    tmp[key_in_len] = i;
-    if (crypto_digest((char*)digest, (const char *)tmp, key_in_len+1) < 0)
-      goto exit;
-    memcpy(cp, digest, MIN(DIGEST_LEN, key_out_len-(cp-key_out)));
-  }
-
-  r = 0;
- exit:
-  memwipe(tmp, 0, key_in_len+1);
-  tor_free(tmp);
-  memwipe(digest, 0, sizeof(digest));
-  return r;
-}
-
-/** Expand some secret key material according to RFC5869, using SHA256 as the
- * underlying hash.  The <b>key_in_len</b> bytes at <b>key_in</b> are the
- * secret key material; the <b>salt_in_len</b> bytes at <b>salt_in</b> and the
- * <b>info_in_len</b> bytes in <b>info_in_len</b> are the algorithm's "salt"
- * and "info" parameters respectively.  On success, write <b>key_out_len</b>
- * bytes to <b>key_out</b> and return 0.  Assert on failure.
- */
-int
-crypto_expand_key_material_rfc5869_sha256(
-                                    const uint8_t *key_in, size_t key_in_len,
-                                    const uint8_t *salt_in, size_t salt_in_len,
-                                    const uint8_t *info_in, size_t info_in_len,
-                                    uint8_t *key_out, size_t key_out_len)
-{
-  uint8_t prk[DIGEST256_LEN];
-  uint8_t tmp[DIGEST256_LEN + 128 + 1];
-  uint8_t mac[DIGEST256_LEN];
-  int i;
-  uint8_t *outp;
-  size_t tmp_len;
-
-  crypto_hmac_sha256((char*)prk,
-                     (const char*)salt_in, salt_in_len,
-                     (const char*)key_in, key_in_len);
-
-  /* If we try to get more than this amount of key data, we'll repeat blocks.*/
-  tor_assert(key_out_len <= DIGEST256_LEN * 256);
-  tor_assert(info_in_len <= 128);
-  memset(tmp, 0, sizeof(tmp));
-  outp = key_out;
-  i = 1;
-
-  while (key_out_len) {
-    size_t n;
-    if (i > 1) {
-      memcpy(tmp, mac, DIGEST256_LEN);
-      memcpy(tmp+DIGEST256_LEN, info_in, info_in_len);
-      tmp[DIGEST256_LEN+info_in_len] = i;
-      tmp_len = DIGEST256_LEN + info_in_len + 1;
-    } else {
-      memcpy(tmp, info_in, info_in_len);
-      tmp[info_in_len] = i;
-      tmp_len = info_in_len + 1;
-    }
-    crypto_hmac_sha256((char*)mac,
-                       (const char*)prk, DIGEST256_LEN,
-                       (const char*)tmp, tmp_len);
-    n = key_out_len < DIGEST256_LEN ? key_out_len : DIGEST256_LEN;
-    memcpy(outp, mac, n);
-    key_out_len -= n;
-    outp += n;
-    ++i;
-  }
-
-  memwipe(tmp, 0, sizeof(tmp));
-  memwipe(mac, 0, sizeof(mac));
-  return 0;
-}
-
 void
 crypto_dh_free_all(void)
 {
diff --git a/src/common/crypto_dh.h b/src/common/crypto_dh.h
index 7c78d8c90..111c199fa 100644
--- a/src/common/crypto_dh.h
+++ b/src/common/crypto_dh.h
@@ -37,15 +37,6 @@ ssize_t crypto_dh_compute_secret(int severity, crypto_dh_t *dh,
 void crypto_dh_free_(crypto_dh_t *dh);
 #define crypto_dh_free(dh) FREE_AND_NULL(crypto_dh_t, crypto_dh_free_, (dh))
 
-int crypto_expand_key_material_TAP(const uint8_t *key_in,
-                                   size_t key_in_len,
-                                   uint8_t *key_out, size_t key_out_len);
-int crypto_expand_key_material_rfc5869_sha256(
-                                    const uint8_t *key_in, size_t key_in_len,
-                                    const uint8_t *salt_in, size_t salt_in_len,
-                                    const uint8_t *info_in, size_t info_in_len,
-                                    uint8_t *key_out, size_t key_out_len);
-
 /* Crypto DH free */
 void crypto_dh_free_all(void);
 
diff --git a/src/common/crypto_hkdf.c b/src/common/crypto_hkdf.c
new file mode 100644
index 000000000..6256f632d
--- /dev/null
+++ b/src/common/crypto_hkdf.c
@@ -0,0 +1,112 @@
+/* Copyright (c) 2001, Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file crypto_hkdf.c
+ * \brief Block of functions related with HKDF utilities and operations.
+ **/
+
+#include "crypto_hkdf.h"
+#include "crypto_util.h"
+#include "crypto_digest.h"
+
+/** Given <b>key_in_len</b> bytes of negotiated randomness in <b>key_in</b>
+ * ("K"), expand it into <b>key_out_len</b> bytes of negotiated key material in
+ * <b>key_out</b> by taking the first <b>key_out_len</b> bytes of
+ *    H(K | [00]) | H(K | [01]) | ....
+ *
+ * This is the key expansion algorithm used in the "TAP" circuit extension
+ * mechanism; it shouldn't be used for new protocols.
+ *
+ * Return 0 on success, -1 on failure.
+ */
+int
+crypto_expand_key_material_TAP(const uint8_t *key_in, size_t key_in_len,
+                               uint8_t *key_out, size_t key_out_len)
+{
+  int i, r = -1;
+  uint8_t *cp, *tmp = tor_malloc(key_in_len+1);
+  uint8_t digest[DIGEST_LEN];
+
+  /* If we try to get more than this amount of key data, we'll repeat blocks.*/
+  tor_assert(key_out_len <= DIGEST_LEN*256);
+
+  memcpy(tmp, key_in, key_in_len);
+  for (cp = key_out, i=0; cp < key_out+key_out_len;
+       ++i, cp += DIGEST_LEN) {
+    tmp[key_in_len] = i;
+    if (crypto_digest((char*)digest, (const char *)tmp, key_in_len+1) < 0)
+      goto exit;
+    memcpy(cp, digest, MIN(DIGEST_LEN, key_out_len-(cp-key_out)));
+  }
+
+  r = 0;
+ exit:
+  memwipe(tmp, 0, key_in_len+1);
+  tor_free(tmp);
+  memwipe(digest, 0, sizeof(digest));
+  return r;
+}
+
+/** Expand some secret key material according to RFC5869, using SHA256 as the
+ * underlying hash.  The <b>key_in_len</b> bytes at <b>key_in</b> are the
+ * secret key material; the <b>salt_in_len</b> bytes at <b>salt_in</b> and the
+ * <b>info_in_len</b> bytes in <b>info_in_len</b> are the algorithm's "salt"
+ * and "info" parameters respectively.  On success, write <b>key_out_len</b>
+ * bytes to <b>key_out</b> and return 0.  Assert on failure.
+ */
+int
+crypto_expand_key_material_rfc5869_sha256(
+                                    const uint8_t *key_in, size_t key_in_len,
+                                    const uint8_t *salt_in, size_t salt_in_len,
+                                    const uint8_t *info_in, size_t info_in_len,
+                                    uint8_t *key_out, size_t key_out_len)
+{
+  uint8_t prk[DIGEST256_LEN];
+  uint8_t tmp[DIGEST256_LEN + 128 + 1];
+  uint8_t mac[DIGEST256_LEN];
+  int i;
+  uint8_t *outp;
+  size_t tmp_len;
+
+  crypto_hmac_sha256((char*)prk,
+                     (const char*)salt_in, salt_in_len,
+                     (const char*)key_in, key_in_len);
+
+  /* If we try to get more than this amount of key data, we'll repeat blocks.*/
+  tor_assert(key_out_len <= DIGEST256_LEN * 256);
+  tor_assert(info_in_len <= 128);
+  memset(tmp, 0, sizeof(tmp));
+  outp = key_out;
+  i = 1;
+
+  while (key_out_len) {
+    size_t n;
+    if (i > 1) {
+      memcpy(tmp, mac, DIGEST256_LEN);
+      memcpy(tmp+DIGEST256_LEN, info_in, info_in_len);
+      tmp[DIGEST256_LEN+info_in_len] = i;
+      tmp_len = DIGEST256_LEN + info_in_len + 1;
+    } else {
+      memcpy(tmp, info_in, info_in_len);
+      tmp[info_in_len] = i;
+      tmp_len = info_in_len + 1;
+    }
+    crypto_hmac_sha256((char*)mac,
+                       (const char*)prk, DIGEST256_LEN,
+                       (const char*)tmp, tmp_len);
+    n = key_out_len < DIGEST256_LEN ? key_out_len : DIGEST256_LEN;
+    memcpy(outp, mac, n);
+    key_out_len -= n;
+    outp += n;
+    ++i;
+  }
+
+  memwipe(tmp, 0, sizeof(tmp));
+  memwipe(mac, 0, sizeof(mac));
+  return 0;
+}
+
diff --git a/src/common/crypto_hkdf.h b/src/common/crypto_hkdf.h
new file mode 100644
index 000000000..5b5517209
--- /dev/null
+++ b/src/common/crypto_hkdf.h
@@ -0,0 +1,28 @@
+/* Copyright (c) 2001, Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file crypto_hkdf.h
+ *
+ * \brief Headers for crypto_hkdf.h
+ **/
+
+#ifndef TOR_CRYPTO_HKDF_H
+#define TOR_CRYPTO_HKDF_H
+
+#include "util.h"
+
+int crypto_expand_key_material_TAP(const uint8_t *key_in,
+                                   size_t key_in_len,
+                                   uint8_t *key_out, size_t key_out_len);
+int crypto_expand_key_material_rfc5869_sha256(
+                                    const uint8_t *key_in, size_t key_in_len,
+                                    const uint8_t *salt_in, size_t salt_in_len,
+                                    const uint8_t *info_in, size_t info_in_len,
+                                    uint8_t *key_out, size_t key_out_len);
+
+#endif /* !defined(TOR_CRYPTO_HKDF_H) */
+
diff --git a/src/common/crypto_s2k.c b/src/common/crypto_s2k.c
index 47cb62d07..2977a2d12 100644
--- a/src/common/crypto_s2k.c
+++ b/src/common/crypto_s2k.c
@@ -15,7 +15,7 @@
 #include "compat.h"
 #include "crypto.h"
 #include "crypto_digest.h"
-#include "crypto_dh.h"
+#include "crypto_hkdf.h"
 #include "crypto_rand.h"
 #include "crypto_s2k.h"
 #include "crypto_util.h"
diff --git a/src/common/crypto_util.c b/src/common/crypto_util.c
index 1e1e7284e..2933579cf 100644
--- a/src/common/crypto_util.c
+++ b/src/common/crypto_util.c
@@ -106,6 +106,9 @@ memwipe(void *mem, uint8_t byte, size_t sz)
   memset(mem, byte, sz);
 }
 
+/** Log all pending crypto errors at level <b>severity</b>.  Use
+ * <b>doing</b> to describe our current activities.
+ */
 void
 crypto_log_errors(int severity, const char *doing)
 {
diff --git a/src/common/include.am b/src/common/include.am
index 6dafcea20..c9706c6b4 100644
--- a/src/common/include.am
+++ b/src/common/include.am
@@ -118,6 +118,7 @@ LIBOR_CRYPTO_A_SRC = \
   src/common/crypto_dh.c       \
   src/common/crypto_digest.c     \
   src/common/crypto_format.c	\
+  src/common/crypto_hkdf.c      \
   src/common/crypto_openssl_mgt.c    \
   src/common/crypto_pwbox.c     \
   src/common/crypto_rand.c     \
@@ -175,6 +176,7 @@ COMMONHEADERS = \
   src/common/crypto_curve25519.h		\
   src/common/crypto_ed25519.h			\
   src/common/crypto_format.h			\
+  src/common/crypto_hkdf.h              \
   src/common/crypto_openssl_mgt.h         \
   src/common/crypto_pwbox.h			\
   src/common/crypto_rand.h          \
diff --git a/src/or/onion_ntor.c b/src/or/onion_ntor.c
index 74403ac7a..3df8c2ab6 100644
--- a/src/or/onion_ntor.c
+++ b/src/or/onion_ntor.c
@@ -22,7 +22,7 @@
 
 #define ONION_NTOR_PRIVATE
 #include "crypto.h"
-#include "crypto_dh.h"
+#include "crypto_hkdf.h"
 #include "crypto_digest.h"
 #include "crypto_util.h"
 #include "onion_ntor.h"
diff --git a/src/or/or.h b/src/or/or.h
index e64ad1d4b..30a9828aa 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -69,6 +69,7 @@
 #include "crypto.h"
 #include "crypto_format.h"
 #include "crypto_dh.h"
+#include "crypto_hkdf.h"
 #include "tortls.h"
 #include "torlog.h"
 #include "container.h"





More information about the tor-commits mailing list