From: Nick Mathewson Date: Wed, 28 May 2025 12:52:57 +0000 (-0400) Subject: Refactor tor1 relay crypto functions into per-layer calls. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=90f0c977f8625fe929003cedbf7ef4372aff00f8;p=thirdparty%2Ftor.git Refactor tor1 relay crypto functions into per-layer calls. We'll need this for mixed circuits. Also, the APIs here are a bit closer to the CGO APIs. --- diff --git a/src/core/crypto/relay_crypto.c b/src/core/crypto/relay_crypto.c index 39a678ebfb..73410a74ae 100644 --- a/src/core/crypto/relay_crypto.c +++ b/src/core/crypto/relay_crypto.c @@ -25,9 +25,14 @@ #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 crypto 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); } /** diff --git a/src/core/crypto/relay_crypto.h b/src/core/crypto/relay_crypto.h index 341c612fca..41c5747aea 100644 --- a/src/core/crypto/relay_crypto.h +++ b/src/core/crypto/relay_crypto.h @@ -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) */ diff --git a/src/core/or/crypt_path.c b/src/core/or/crypt_path.c index b2cf7a8d59..d2527dfb4b 100644 --- a/src/core/or/crypt_path.c +++ b/src/core/or/crypt_path.c @@ -175,35 +175,6 @@ cpath_free(crypt_path_t *victim) tor_free(victim); } -/********************** cpath crypto API *******************************/ - -/** Encrypt or decrypt payload using the crypto of cpath. Actual - * operation decided by is_decrypt. */ -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 cpath. */ -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 cell based on the - * cell payload and update the forward digest of cpath. */ -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 cpath. */ diff --git a/src/core/or/crypt_path.h b/src/core/or/crypt_path.h index dfd2ed4857..514f4df853 100644 --- a/src/core/or/crypt_path.h +++ b/src/core/or/crypt_path.h @@ -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); diff --git a/src/core/or/or.h b/src/core/or/or.h index 44ec332838..d23aa8a2d2 100644 --- a/src/core/or/or.h +++ b/src/core/or/or.h @@ -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; diff --git a/src/core/or/sendme.c b/src/core/or/sendme.c index 426495d745..22fd803865 100644 --- a/src/core/or/sendme.c +++ b/src/core/or/sendme.c @@ -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; -} diff --git a/src/core/or/sendme.h b/src/core/or/sendme.h index fe6dc74542..c06e590a43 100644 --- a/src/core/or/sendme.h +++ b/src/core/or/sendme.h @@ -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