crypt_path.c (6013B)
1 /* 2 * Copyright (c) 2019-2021, The Tor Project, Inc. */ 3 /* See LICENSE for licensing information */ 4 5 /** 6 * \file crypt_path.c 7 * 8 * \brief Functions dealing with layered circuit encryption. This file aims to 9 * provide an API around the crypt_path_t structure which holds crypto 10 * information about a specific hop of a circuit. 11 * 12 * TODO: We should eventually move all functions dealing and manipulating 13 * crypt_path_t to this file, so that eventually we encapsulate more and more 14 * of crypt_path_t. Here are some more functions that can be moved here with 15 * some more effort: 16 * 17 * - circuit_list_path_impl() 18 **/ 19 20 #define CRYPT_PATH_PRIVATE 21 22 #include "core/or/or.h" 23 #include "core/or/crypt_path.h" 24 25 #include "core/crypto/relay_crypto.h" 26 #include "core/crypto/onion_crypto.h" 27 #include "core/or/circuitbuild.h" 28 #include "core/or/circuitlist.h" 29 #include "core/or/extendinfo.h" 30 #include "core/or/congestion_control_common.h" 31 32 #include "lib/crypt_ops/crypto_dh.h" 33 #include "lib/crypt_ops/crypto_util.h" 34 35 #include "core/or/crypt_path_st.h" 36 #include "core/or/cell_st.h" 37 38 /** Add <b>new_hop</b> to the end of the doubly-linked-list <b>head_ptr</b>. 39 * This function is used to extend cpath by another hop. 40 */ 41 void 42 cpath_extend_linked_list(crypt_path_t **head_ptr, crypt_path_t *new_hop) 43 { 44 if (*head_ptr) { 45 new_hop->next = (*head_ptr); 46 new_hop->prev = (*head_ptr)->prev; 47 (*head_ptr)->prev->next = new_hop; 48 (*head_ptr)->prev = new_hop; 49 } else { 50 *head_ptr = new_hop; 51 new_hop->prev = new_hop->next = new_hop; 52 } 53 } 54 55 /** Create a new hop, annotate it with information about its 56 * corresponding router <b>choice</b>, and append it to the 57 * end of the cpath <b>head_ptr</b>. */ 58 int 59 cpath_append_hop(crypt_path_t **head_ptr, extend_info_t *choice) 60 { 61 crypt_path_t *hop = tor_malloc_zero(sizeof(crypt_path_t)); 62 63 /* link hop into the cpath, at the end. */ 64 cpath_extend_linked_list(head_ptr, hop); 65 66 hop->magic = CRYPT_PATH_MAGIC; 67 hop->state = CPATH_STATE_CLOSED; 68 69 hop->extend_info = extend_info_dup(choice); 70 71 hop->package_window = circuit_initial_package_window(); 72 hop->deliver_window = CIRCWINDOW_START; 73 74 // This can get changed later on by circuit negotiation. 75 hop->relay_cell_format = RELAY_CELL_FORMAT_V0; 76 77 return 0; 78 } 79 80 /** Verify that cpath <b>cp</b> has all of its invariants 81 * correct. Trigger an assert if anything is invalid. 82 */ 83 void 84 cpath_assert_ok(const crypt_path_t *cp) 85 { 86 const crypt_path_t *start = cp; 87 88 do { 89 cpath_assert_layer_ok(cp); 90 /* layers must be in sequence of: "open* awaiting? closed*" */ 91 if (cp != start) { 92 if (cp->state == CPATH_STATE_AWAITING_KEYS) { 93 tor_assert(cp->prev->state == CPATH_STATE_OPEN); 94 } else if (cp->state == CPATH_STATE_OPEN) { 95 tor_assert(cp->prev->state == CPATH_STATE_OPEN); 96 } 97 } 98 cp = cp->next; 99 tor_assert(cp); 100 } while (cp != start); 101 } 102 103 /** Verify that cpath layer <b>cp</b> has all of its invariants 104 * correct. Trigger an assert if anything is invalid. 105 */ 106 void 107 cpath_assert_layer_ok(const crypt_path_t *cp) 108 { 109 // tor_assert(cp->addr); /* these are zero for rendezvous extra-hops */ 110 // tor_assert(cp->port); 111 tor_assert(cp); 112 tor_assert(cp->magic == CRYPT_PATH_MAGIC); 113 switch (cp->state) 114 { 115 case CPATH_STATE_OPEN: 116 relay_crypto_assert_ok(&cp->pvt_crypto); 117 FALLTHROUGH; 118 case CPATH_STATE_CLOSED: 119 break; 120 case CPATH_STATE_AWAITING_KEYS: 121 break; 122 default: 123 log_fn(LOG_ERR, LD_BUG, "Unexpected state %d", cp->state); 124 tor_assert(0); 125 } 126 tor_assert(cp->package_window >= 0); 127 tor_assert(cp->deliver_window >= 0); 128 } 129 130 /** Initialize cpath-\>{f|b}_{crypto|digest} from the key material in key_data. 131 * 132 * If <b>is_hs_v3</b> is set, this cpath will be used for next gen hidden 133 * service circuits and <b>key_data</b> must be at least 134 * HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN bytes in length. 135 * 136 * If <b>is_hs_v3</b> is not set, key_data must contain CPATH_KEY_MATERIAL_LEN 137 * bytes, which are used as follows: 138 * - 20 to initialize f_digest 139 * - 20 to initialize b_digest 140 * - 16 to key f_crypto 141 * - 16 to key b_crypto 142 * 143 * (If 'reverse' is true, then f_XX and b_XX are swapped.) 144 * 145 * Return 0 if init was successful, else -1 if it failed. 146 */ 147 int 148 cpath_init_circuit_crypto(relay_crypto_alg_t alg, 149 crypt_path_t *cpath, 150 const char *key_data, size_t key_data_len) 151 { 152 153 tor_assert(cpath); 154 return relay_crypto_init(alg, &cpath->pvt_crypto, key_data, key_data_len); 155 } 156 157 /** Deallocate space associated with the cpath node <b>victim</b>. */ 158 void 159 cpath_free(crypt_path_t *victim) 160 { 161 if (!victim) 162 return; 163 164 relay_crypto_clear(&victim->pvt_crypto); 165 onion_handshake_state_release(&victim->handshake_state); 166 extend_info_free(victim->extend_info); 167 congestion_control_free(victim->ccontrol); 168 169 memwipe(victim, 0xBB, sizeof(crypt_path_t)); /* poison memory */ 170 tor_free(victim); 171 } 172 173 /************ cpath sendme API ***************************/ 174 175 /** Return the sendme tag of this <b>cpath</b>, 176 * along with its length. */ 177 const uint8_t * 178 cpath_get_sendme_tag(crypt_path_t *cpath, size_t *len_out) 179 { 180 return relay_crypto_get_sendme_tag(&cpath->pvt_crypto, len_out); 181 } 182 183 /************ other cpath functions ***************************/ 184 185 /** Return the first non-open hop in cpath, or return NULL if all 186 * hops are open. */ 187 crypt_path_t * 188 cpath_get_next_non_open_hop(crypt_path_t *cpath) 189 { 190 crypt_path_t *hop = cpath; 191 do { 192 if (hop->state != CPATH_STATE_OPEN) 193 return hop; 194 hop = hop->next; 195 } while (hop != cpath); 196 return NULL; 197 } 198 199 #ifdef TOR_UNIT_TESTS 200 201 /** Unittest helper function: Count number of hops in cpath linked list. */ 202 unsigned int 203 cpath_get_n_hops(crypt_path_t **head_ptr) 204 { 205 unsigned int n_hops = 0; 206 crypt_path_t *tmp; 207 208 if (!*head_ptr) { 209 return 0; 210 } 211 212 tmp = *head_ptr; 213 do { 214 n_hops++; 215 tmp = tmp->next; 216 } while (tmp != *head_ptr); 217 218 return n_hops; 219 } 220 221 #endif /* defined(TOR_UNIT_TESTS) */