]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
relay crypto: functions to get key material length.
authorNick Mathewson <nickm@torproject.org>
Wed, 28 May 2025 16:22:03 +0000 (12:22 -0400)
committerNick Mathewson <nickm@torproject.org>
Tue, 10 Jun 2025 23:06:47 +0000 (19:06 -0400)
src/core/crypto/onion_crypto.c
src/core/crypto/relay_crypto.c
src/core/crypto/relay_crypto.h
src/core/crypto/relay_crypto_cgo.c
src/core/crypto/relay_crypto_tor1.c
src/core/crypto/relay_crypto_tor1.h

index 232dbcc5df1740e765e20c354c5647fb68c1e7f6..f8088745d2e55b70582c8636ef9af2583caaed1c 100644 (file)
@@ -41,6 +41,7 @@
 #include "lib/crypt_ops/crypto_util.h"
 #include "feature/relay/routerkeys.h"
 #include "core/or/congestion_control_common.h"
+#include "core/crypto/relay_crypto.h"
 
 #include "core/or/circuitbuild.h"
 
@@ -247,9 +248,10 @@ negotiate_v3_ntor_server_circ_params(const uint8_t *param_request_msg,
 }
 
 /* This is the maximum value for keys_out_len passed to
- * onion_skin_server_handshake, plus 16. We can make it bigger if needed:
+ * onion_skin_server_handshake, plus 20 for the rend_nonce.
+ * We can make it bigger if needed:
  * It just defines how many bytes to stack-allocate. */
-#define MAX_KEYS_TMP_LEN 128
+#define MAX_KEYS_TMP_LEN (MAX_RELAY_KEY_MATERIAL_LEN + DIGEST_LEN)
 
 /** Perform the second (server-side) step of a circuit-creation handshake of
  * type <b>type</b>, responding to the client request in <b>onion_skin</b>
@@ -265,6 +267,7 @@ onion_skin_server_handshake(int type,
                       const circuit_params_t *our_ns_params,
                       uint8_t *reply_out,
                       size_t reply_out_maxlen,
+     // XXXX keys_out_len will depend on the algorithm we're negotiating.
                       uint8_t *keys_out, size_t keys_out_len,
                       uint8_t *rend_nonce_out,
                       circuit_params_t *params_out)
index baddd704e0230eb73ad3723305af2a34b836c85f..bc69f4ef25f1a3865204f64d7526c15afcb0de23 100644 (file)
@@ -188,6 +188,23 @@ relay_crypto_init(relay_crypto_t *crypto,
   return tor1_crypt_init(crypto, key_data, key_data_len, reverse, is_hs_v3);
 }
 
+/** Return the amount of key material we need to initialize
+ * the given relay crypto algorithm.
+ *
+ * Return -1 if the algorithm is unrecognized.
+ */
+ssize_t
+relay_crypto_key_material_len(relay_crypto_alg_t alg)
+{
+  switch (alg) {
+    case RELAY_CRYPTO_ALG_TOR1:
+      return tor1_key_material_len(false);
+    case RELAY_CRYPTO_ALG_TOR1_HS:
+      return tor1_key_material_len(true);
+  }
+  return -1;
+}
+
 /** Assert that <b>crypto</b> is valid and set. */
 void
 relay_crypto_assert_ok(const relay_crypto_t *crypto)
index 5340c073388ad8dca884780fcbcb0b38c6c29bbb..5e04dd1cd10f9e08d87919fac30a2cab89a1bab0 100644 (file)
 #ifndef TOR_RELAY_CRYPTO_H
 #define TOR_RELAY_CRYPTO_H
 
+typedef enum relay_crypto_alg_t {
+  RELAY_CRYPTO_ALG_TOR1,
+  RELAY_CRYPTO_ALG_TOR1_HS,
+} relay_crypto_alg_t;
+
+#define relay_crypto_alg_bitfield_t ENUM_BF(relay_crypto_alg_t)
+
+/** Largest possible return value for relay_crypto_key_material_len. */
+/* This is 2x the length needed for a single cgo direction with 256-bit AES
+ */
+#define MAX_RELAY_KEY_MATERIAL_LEN 224
+
+ssize_t relay_crypto_key_material_len(relay_crypto_alg_t alg);
+
 int relay_crypto_init(relay_crypto_t *crypto,
                       const char *key_data, size_t key_data_len,
                       int reverse, int is_hs_v3);
index 1e900861fe580c8eada22da48e27ccc96830d169..9dbc6a65fffa6d9341b039eb8a044b04adee09c6 100644 (file)
@@ -21,6 +21,7 @@
 #include "lib/arch/bytes.h"
 #include "ext/polyval/polyval.h"
 #include "core/crypto/relay_crypto_cgo.h"
+#include "core/crypto/relay_crypto.h"
 #include "core/or/cell_st.h"
 
 #if 0
@@ -361,7 +362,9 @@ size_t
 cgo_key_material_len(int aesbits)
 {
   tor_assert(aesbits == 128 || aesbits == 192 || aesbits == 256);
-  return (cgo_uiv_keylen(aesbits) + CGO_TAG_LEN);
+  size_t r = (cgo_uiv_keylen(aesbits) + CGO_TAG_LEN);
+  tor_assert(r * 2 <= MAX_RELAY_KEY_MATERIAL_LEN);
+  return r;
 }
 
 /**
index 21e0139f8138a9890818f92aef66067a90b0413c..baef282f3b859093d707c836bce7092f2328d359 100644 (file)
@@ -191,10 +191,20 @@ tor1_crypt_client_backward(tor1_crypt_t *tor1, cell_t *cell)
   return false;
 }
 
+/** Return the number of bytes that tor1_crypt_init expects. */
+size_t
+tor1_key_material_len(bool is_hs)
+{
+  if (is_hs)
+    return HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN;
+  else
+    return CPATH_KEY_MATERIAL_LEN;
+}
+
 /** Initialize <b>crypto</b> from the key material in key_data.
  *
  * If <b>is_hs_v3</b> is set, this cpath will be used for next gen hidden
- * service circuits and <b>key_data</b> must be at least
+ * service circuits and <b>key_data</b> must be
  * HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN bytes in length.
  *
  * If <b>is_hs_v3</b> is not set, key_data must contain CPATH_KEY_MATERIAL_LEN
index 636ca2e2169b6d50842773a97bad2a0f604603c8..8a07a8bdd45d02af3dd9b325003e0dfff236c046 100644 (file)
@@ -21,6 +21,7 @@ bool tor1_crypt_relay_forward(tor1_crypt_t *tor1, cell_t *cell);
 bool tor1_crypt_client_backward(tor1_crypt_t *tor1, cell_t *cell);
 void tor1_crypt_client_forward(tor1_crypt_t *tor1, cell_t *cell);
 
+size_t tor1_key_material_len(bool is_hs);
 int tor1_crypt_init(relay_crypto_t *crypto,
                     const char *key_data, size_t key_data_len,
                     int reverse, int is_hs_v3);