tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

commit ca962e2f14ba1a4e48e536bdc5cfa728a2cf9759
parent 1ca19e83a8b35640449ad672e935d89e79fc0fe1
Author: Nick Mathewson <nickm@torproject.org>
Date:   Tue,  3 Jun 2025 08:31:02 -0400

Set the key material length correctly based on crypto algorithm.

With this change, it appears that we can successfully negotiate
CGO.

Diffstat:
Msrc/core/crypto/onion_crypto.c | 32++++++++++++++++++++++----------
1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/src/core/crypto/onion_crypto.c b/src/core/crypto/onion_crypto.c @@ -392,10 +392,6 @@ onion_skin_server_handshake(int type, relay_crypto_alg_t relay_alg = RELAY_CRYPTO_ALG_TOR1; size_t keys_out_needed = relay_crypto_key_material_len(relay_alg); - if (BUG(*keys_len_out < keys_out_needed)) { - return -1; - } - *keys_len_out = keys_out_needed; circuit_params_init(params_out); @@ -407,6 +403,9 @@ onion_skin_server_handshake(int type, return -1; if (onionskin_len != CREATE_FAST_LEN) return -1; + if (BUG(*keys_len_out < keys_out_needed)) { + return -1; + } if (fast_server_handshake(onion_skin, reply_out, keys_out, keys_out_needed)<0) return -1; @@ -418,6 +417,9 @@ onion_skin_server_handshake(int type, return -1; if (onionskin_len < NTOR_ONIONSKIN_LEN) return -1; + if (BUG(*keys_len_out < keys_out_needed)) { + return -1; + } { size_t keys_tmp_len = keys_out_needed + DIGEST_LEN; tor_assert(keys_tmp_len <= MAX_KEYS_TMP_LEN); @@ -439,8 +441,6 @@ onion_skin_server_handshake(int type, } break; case ONION_HANDSHAKE_TYPE_NTOR_V3: { - size_t keys_tmp_len = keys_out_needed + DIGEST_LEN; - tor_assert(keys_tmp_len <= MAX_KEYS_TMP_LEN); uint8_t keys_tmp[MAX_KEYS_TMP_LEN]; uint8_t *client_msg = NULL; size_t client_msg_len = 0; @@ -471,6 +471,16 @@ onion_skin_server_handshake(int type, return -1; } tor_free(client_msg); + /* Now we know what we negotiated, + so we can use the right lengths. */ + relay_alg = params_out->crypto_alg; + keys_out_needed = relay_crypto_key_material_len(relay_alg); + + if (BUG(*keys_len_out < keys_out_needed)) { + return -1; + } + size_t keys_tmp_len = keys_out_needed + DIGEST_LEN; + tor_assert(keys_tmp_len <= MAX_KEYS_TMP_LEN); uint8_t *server_handshake = NULL; size_t server_handshake_len = 0; @@ -511,6 +521,7 @@ onion_skin_server_handshake(int type, return -1; /* LCOV_EXCL_STOP */ } + *keys_len_out = keys_out_needed; return r; } @@ -588,16 +599,17 @@ onion_skin_client_handshake(int type, if (handshake_state->tag != type) return -1; - relay_crypto_alg_t relay_alg = RELAY_CRYPTO_ALG_TOR1; + memcpy(params_out, &handshake_state->chosen_params, + sizeof(circuit_params_t)); + + // at this point, we know the crypto algorithm we want to use + relay_crypto_alg_t relay_alg = params_out->crypto_alg; size_t keys_out_needed = relay_crypto_key_material_len(relay_alg); if (BUG(*keys_len_out < keys_out_needed)) { return -1; } *keys_len_out = keys_out_needed; - memcpy(params_out, &handshake_state->chosen_params, - sizeof(circuit_params_t)); - switch (type) { case ONION_HANDSHAKE_TYPE_TAP: return -1;