]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Refactor tor1 relay crypto functions into per-layer calls.
authorNick Mathewson <nickm@torproject.org>
Wed, 28 May 2025 12:52:57 +0000 (08:52 -0400)
committerNick Mathewson <nickm@torproject.org>
Tue, 10 Jun 2025 23:06:47 +0000 (19:06 -0400)
We'll need this for mixed circuits.

Also, the APIs here are a bit closer to the CGO APIs.

src/core/crypto/relay_crypto.c
src/core/crypto/relay_crypto.h
src/core/or/crypt_path.c
src/core/or/crypt_path.h
src/core/or/or.h
src/core/or/sendme.c
src/core/or/sendme.h

index 39a678ebfb62bfceb615b1a60396c23a77e4f13f..73410a74aed3f632e34a054052856fb0c11c9817 100644 (file)
 #include "core/or/or_circuit_st.h"
 #include "core/or/origin_circuit_st.h"
 
+#include "core/or/congestion_control_common.h" // XXXX refactor.
+
 /* TODO CGO: This file will be largely incorrect when we have
  * CGO crypto. */
 
+// XXXX: Remove this definition once I'm done refactoring.
+#define pvt_crypto crypto_crypt_path_private_field
+
 /* Offset of digest within relay cell body for v0 cells. */
 #define V0_DIGEST_OFFSET 5
 #define V0_DIGEST_LEN 4
@@ -109,6 +114,73 @@ tor1_crypt_one_payload(crypto_cipher_t *cipher, uint8_t *in)
   crypto_cipher_crypt_inplace(cipher, (char*) in, CELL_PAYLOAD_SIZE);
 }
 
+/* XXXX DOCDOC */
+void
+tor1_crypt_client_originate(relay_crypto_t *tor1,
+                            cell_t *cell,
+                            bool record_sendme_digest)
+{
+  tor1_set_digest_v0(tor1->f_digest, cell);
+  if (record_sendme_digest) {
+    tor1_save_sendme_digest(tor1, true);
+  }
+  tor1_crypt_one_payload(tor1->f_crypto, cell->payload);
+}
+
+/* XXXX DOCDOC */
+void
+tor1_crypt_relay_originate(relay_crypto_t *tor1,
+                           cell_t *cell,
+                           bool save_sendme_digest)
+{
+  tor1_set_digest_v0(tor1->b_digest, cell);
+  if (save_sendme_digest) {
+    tor1_save_sendme_digest(tor1, false);
+  }
+  tor1_crypt_one_payload(tor1->b_crypto, cell->payload);
+}
+
+/* XXXX DOCDOC */
+void
+tor1_crypt_client_forward(relay_crypto_t *tor1, cell_t *cell)
+{
+  tor1_crypt_one_payload(tor1->f_crypto, cell->payload);
+}
+
+/* XXXX DOCDOC */
+void
+tor1_crypt_relay_backward(relay_crypto_t *tor1, cell_t *cell)
+{
+  tor1_crypt_one_payload(tor1->b_crypto, cell->payload);
+}
+
+/* XXXX DOCDOC */
+bool
+tor1_crypt_relay_forward(relay_crypto_t *tor1, cell_t *cell)
+{
+  tor1_crypt_one_payload(tor1->f_crypto, cell->payload);
+  if (relay_cell_is_recognized_v0(cell)) {
+    if (tor1_relay_digest_matches_v0(tor1->f_digest, cell)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+/* XXXX DOCDOC */
+bool
+tor1_crypt_client_backward(relay_crypto_t *tor1, cell_t *cell)
+{
+  tor1_crypt_one_payload(tor1->b_crypto, cell->payload);
+
+  if (relay_cell_is_recognized_v0(cell)) {
+    if (tor1_relay_digest_matches_v0(tor1->b_digest, cell)) {
+      return true;
+    }
+  }
+  return false;
+}
+
 /** Return the sendme_digest within the <b>crypto</b> object.
  *
  * Before calling this function, you must call relay_crypto_save_sendme_digest.
@@ -184,41 +256,31 @@ relay_decrypt_cell(circuit_t *circ, cell_t *cell,
       do { /* Remember: cpath is in forward order, that is, first hop first. */
         tor_assert(thishop);
 
-        /* decrypt one layer */
-        cpath_crypt_cell(thishop, cell->payload, true);
-
-        if (relay_cell_is_recognized_v0(cell)) {
-          /* it's possibly recognized. have to check digest to be sure. */
-          if (tor1_relay_digest_matches_v0(cpath_get_incoming_digest(thishop),
-                                      cell)) {
-            *recognized = 1;
-            *layer_hint = thishop;
-            return 0;
-          }
-        }
+        bool rec = tor1_crypt_client_backward(&thishop->pvt_crypto, cell);
 
+        if (rec) {
+          *recognized = 1;
+          *layer_hint = thishop;
+          return 0;
+        }
         thishop = thishop->next;
       } while (thishop != cpath && thishop->state == CPATH_STATE_OPEN);
       log_fn(LOG_PROTOCOL_WARN, LD_OR,
              "Incoming cell at client not recognized. Closing.");
       return -1;
     } else {
-      relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;
       /* We're in the middle. Encrypt one layer. */
-      tor1_crypt_one_payload(crypto->b_crypto, cell->payload);
+      relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;
+      tor1_crypt_relay_backward(crypto, cell);
     }
   } else /* cell_direction == CELL_DIRECTION_OUT */ {
     /* We're in the middle. Decrypt one layer. */
     relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;
 
-    tor1_crypt_one_payload(crypto->f_crypto, cell->payload);
-
-    if (relay_cell_is_recognized_v0(cell)) {
-      /* it's possibly recognized. have to check digest to be sure. */
-      if (tor1_relay_digest_matches_v0(crypto->f_digest, cell)) {
-        *recognized = 1;
-        return 0;
-      }
+    bool rec = tor1_crypt_relay_forward(crypto, cell);
+    if (rec) {
+      *recognized = 1;
+      return 0;
     }
   }
   return 0;
@@ -236,21 +298,18 @@ relay_encrypt_cell_outbound(cell_t *cell,
                             origin_circuit_t *circ,
                             crypt_path_t *layer_hint)
 {
-  crypt_path_t *thishop; /* counter for repeated crypts */
-  cpath_set_cell_forward_digest(layer_hint, cell);
+  crypt_path_t *thishop = layer_hint;
 
-  /* Record cell digest as the SENDME digest if need be. */
-  sendme_save_sending_cell_digest(TO_CIRCUIT(circ), layer_hint);
+  bool save_sendme =
+    circuit_sent_cell_for_sendme(TO_CIRCUIT(circ), thishop);
 
-  thishop = layer_hint;
-  /* moving from farthest to nearest hop */
-  do {
-    tor_assert(thishop);
-    log_debug(LD_OR,"encrypting a layer of the relay cell.");
-    cpath_crypt_cell(thishop, cell->payload, false);
+  tor1_crypt_client_originate(&thishop->pvt_crypto, cell, save_sendme);
+  thishop = thishop->prev;
 
+  while (thishop != circ->cpath->prev) {
+    tor1_crypt_client_forward(&thishop->pvt_crypto, cell);
     thishop = thishop->prev;
-  } while (thishop != circ->cpath->prev);
+  }
 }
 
 /**
@@ -264,13 +323,9 @@ void
 relay_encrypt_cell_inbound(cell_t *cell,
                            or_circuit_t *or_circ)
 {
-  tor1_set_digest_v0(or_circ->crypto.b_digest, cell);
-
-  /* Record cell digest as the SENDME digest if need be. */
-  sendme_save_sending_cell_digest(TO_CIRCUIT(or_circ), NULL);
-
-  /* encrypt one layer */
-  tor1_crypt_one_payload(or_circ->crypto.b_crypto, cell->payload);
+  bool save_sendme =
+    circuit_sent_cell_for_sendme(TO_CIRCUIT(or_circ), NULL);
+  tor1_crypt_relay_originate(&or_circ->crypto, cell, save_sendme);
 }
 
 /**
index 341c612fca5b03a59ace0d36c8df6d45ac2d7470..41c5747aea283238ede39adf2de8c62f33fc863d 100644 (file)
@@ -29,13 +29,21 @@ void relay_crypto_assert_ok(const relay_crypto_t *crypto);
 
 uint8_t *relay_crypto_get_sendme_digest(relay_crypto_t *crypto);
 
-void tor1_save_sendme_digest(relay_crypto_t *crypto,
+void tor1_save_sendme_digest(tor1_crypt_t *crypto,
                              bool is_foward_digest);
 
-void
-tor1_crypt_one_payload(crypto_cipher_t *cipher, uint8_t *in);
-
-void
-tor1_set_digest_v0(crypto_digest_t *digest, cell_t *cell);
+void tor1_crypt_client_originate(tor1_crypt_t *tor1,
+                            cell_t *cell,
+                            bool record_sendme_digest);
+void tor1_crypt_relay_originate(tor1_crypt_t *tor1,
+                           cell_t *cell,
+                           bool record_sendme_digest);
+void tor1_crypt_relay_backward(tor1_crypt_t *tor1, cell_t *cell);
+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);
+
+void tor1_crypt_one_payload(crypto_cipher_t *cipher, uint8_t *in);
+void tor1_set_digest_v0(crypto_digest_t *digest, cell_t *cell);
 
 #endif /* !defined(TOR_RELAY_CRYPTO_H) */
index b2cf7a8d595c7e546aad85f446f2b0bd5fed56ca..d2527dfb4bcfd0d256367d89a8795324e36b0837 100644 (file)
@@ -175,35 +175,6 @@ cpath_free(crypt_path_t *victim)
   tor_free(victim);
 }
 
-/********************** cpath crypto API *******************************/
-
-/** Encrypt or decrypt <b>payload</b> using the crypto of <b>cpath</b>. Actual
- *  operation decided by <b>is_decrypt</b>.  */
-void
-cpath_crypt_cell(const crypt_path_t *cpath, uint8_t *payload, bool is_decrypt)
-{
-  if (is_decrypt) {
-    tor1_crypt_one_payload(cpath->pvt_crypto.b_crypto, payload);
-  } else {
-    tor1_crypt_one_payload(cpath->pvt_crypto.f_crypto, payload);
-  }
-}
-
-/** Getter for the incoming digest of <b>cpath</b>. */
-struct crypto_digest_t *
-cpath_get_incoming_digest(const crypt_path_t *cpath)
-{
-  return cpath->pvt_crypto.b_digest;
-}
-
-/** Set the right integrity digest on the outgoing <b>cell</b> based on the
- *  cell payload and update the forward digest of <b>cpath</b>. */
-void
-cpath_set_cell_forward_digest(crypt_path_t *cpath, cell_t *cell)
-{
-  tor1_set_digest_v0(cpath->pvt_crypto.f_digest, cell);
-}
-
 /************ cpath sendme API ***************************/
 
 /** Return the sendme_digest of this <b>cpath</b>. */
index dfd2ed485745bca574ae599eb647a3fa8b881d4a..514f4df853daaeb43480613432591f94caefa8fd 100644 (file)
@@ -21,18 +21,9 @@ cpath_free(crypt_path_t *victim);
 
 void cpath_extend_linked_list(crypt_path_t **head_ptr, crypt_path_t *new_hop);
 
-void
-cpath_crypt_cell(const crypt_path_t *cpath, uint8_t *payload, bool is_decrypt);
-
-struct crypto_digest_t *
-cpath_get_incoming_digest(const crypt_path_t *cpath);
-
 void cpath_sendme_save_cell_digest(crypt_path_t *cpath,
                                      bool is_foward_digest);
 
-void
-cpath_set_cell_forward_digest(crypt_path_t *cpath, cell_t *cell);
-
 crypt_path_t *cpath_get_next_non_open_hop(crypt_path_t *cpath);
 
 void cpath_sendme_circuit_record_inbound_cell(crypt_path_t *cpath);
index 44ec332838b8d08cb20fb6ae9caec38f5b5eff6f..d23aa8a2d2dba1efc38183c2c9b99f95d682ed64 100644 (file)
@@ -894,6 +894,8 @@ typedef enum {
 
 typedef struct onion_handshake_state_t onion_handshake_state_t;
 typedef struct relay_crypto_t relay_crypto_t;
+// XXXX Temporary alias.
+typedef struct relay_crypto_t tor1_crypt_t;
 typedef struct crypt_path_t crypt_path_t;
 typedef struct crypt_path_reference_t crypt_path_reference_t;
 
index 426495d745ff5d61fa6d7f516ad6fc88f3cda44b..22fd803865e40420b0984459926eb74531fcc2fe 100644 (file)
@@ -727,6 +727,7 @@ sendme_record_cell_digest_on_circ(circuit_t *circ, crypt_path_t *cpath)
 void
 sendme_save_received_cell_digest(circuit_t *circ, crypt_path_t *cpath)
 {
+  // XXXX: all sendme_save functions probably belong inside tor1_*
   tor_assert(circ);
 
   /* Only record if the next cell is expected to be a SENDME. */
@@ -744,29 +745,3 @@ sendme_save_received_cell_digest(circuit_t *circ, crypt_path_t *cpath)
     tor1_save_sendme_digest(&TO_OR_CIRCUIT(circ)->crypto, true);
   }
 }
-
-/* Called once we encrypted a cell. Save the cell digest as the next sendme
- * as the next sendme digest in the cpath's relay_crypto_t
- * only if the we expect to receive a SENDME matching this cell's digest.
- */
-void
-sendme_save_sending_cell_digest(circuit_t *circ, crypt_path_t *cpath)
-{
-  tor_assert(circ);
-
-  /* Only record if the next cell is expected to be a SENDME. */
-  if (!circuit_sent_cell_for_sendme(circ, cpath)) {
-    goto end;
-  }
-
-  if (cpath) {
-    /* Record the forward digest. */
-    cpath_sendme_save_cell_digest(cpath, true);
-  } else {
-    /* Record the incoming digest. */
-    tor1_save_sendme_digest(&TO_OR_CIRCUIT(circ)->crypto, false);
-  }
-
- end:
-  return;
-}
index fe6dc74542d507ce943248a123dd4acd75c0f6f1..c06e590a430ca5a779e3849e1d6e02eb084fcbf8 100644 (file)
@@ -39,7 +39,6 @@ int sendme_note_stream_data_packaged(edge_connection_t *conn, size_t len);
 void sendme_record_cell_digest_on_circ(circuit_t *circ, crypt_path_t *cpath);
 /* Record cell digest as the SENDME digest. */
 void sendme_save_received_cell_digest(circuit_t *circ, crypt_path_t *cpath);
-void sendme_save_sending_cell_digest(circuit_t *circ, crypt_path_t *cpath);
 
 /* Private section starts. */
 #ifdef SENDME_PRIVATE