crypt_path.c 6.7 KB

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