hs_service.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /* Copyright (c) 2016, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file hs_service.c
  5. * \brief Implement next generation hidden service functionality
  6. **/
  7. #define HS_SERVICE_PRIVATE
  8. #include "or.h"
  9. #include "relay.h"
  10. #include "rendservice.h"
  11. #include "circuitlist.h"
  12. #include "circpathbias.h"
  13. #include "hs_service.h"
  14. #include "hs_common.h"
  15. #include "hs/cell_establish_intro.h"
  16. #include "hs/cell_common.h"
  17. /* XXX We don't currently use these functions, apart from generating unittest
  18. data. When we start implementing the service-side support for prop224 we
  19. should revisit these functions and use them. For now we mark them as
  20. unittest-only code: */
  21. #ifdef TOR_UNIT_TESTS
  22. /** Given an ESTABLISH_INTRO <b>cell</b>, encode it and place its payload in
  23. * <b>buf_out</b> which has size <b>buf_out_len</b>. Return the number of
  24. * bytes written, or a negative integer if there was an error. */
  25. STATIC ssize_t
  26. get_establish_intro_payload(uint8_t *buf_out, size_t buf_out_len,
  27. const hs_cell_establish_intro_t *cell)
  28. {
  29. ssize_t bytes_used = 0;
  30. if (buf_out_len < RELAY_PAYLOAD_SIZE) {
  31. return -1;
  32. }
  33. bytes_used = hs_cell_establish_intro_encode(buf_out, buf_out_len,
  34. cell);
  35. return bytes_used;
  36. }
  37. /* Set the cell extensions of <b>cell</b>. */
  38. static void
  39. set_cell_extensions(hs_cell_establish_intro_t *cell)
  40. {
  41. cell_extension_t *cell_extensions = cell_extension_new();
  42. /* For now, we don't use extensions at all. */
  43. cell_extensions->num = 0; /* It's already zeroed, but be explicit. */
  44. hs_cell_establish_intro_set_extensions(cell, cell_extensions);
  45. }
  46. /** Given the circuit handshake info in <b>circuit_key_material</b>, create and
  47. * return an ESTABLISH_INTRO cell. Return NULL if something went wrong. The
  48. * returned cell is allocated on the heap and it's the responsibility of the
  49. * caller to free it. */
  50. STATIC hs_cell_establish_intro_t *
  51. generate_establish_intro_cell(const uint8_t *circuit_key_material,
  52. size_t circuit_key_material_len)
  53. {
  54. hs_cell_establish_intro_t *cell = NULL;
  55. ssize_t encoded_len;
  56. log_warn(LD_GENERAL,
  57. "Generating ESTABLISH_INTRO cell (key_material_len: %u)",
  58. (unsigned) circuit_key_material_len);
  59. /* Generate short-term keypair for use in ESTABLISH_INTRO */
  60. ed25519_keypair_t key_struct;
  61. if (ed25519_keypair_generate(&key_struct, 0) < 0) {
  62. goto err;
  63. }
  64. cell = hs_cell_establish_intro_new();
  65. /* Set AUTH_KEY_TYPE: 2 means ed25519 */
  66. hs_cell_establish_intro_set_auth_key_type(cell, AUTH_KEY_ED25519);
  67. /* Set AUTH_KEY_LEN field */
  68. /* Must also set byte-length of AUTH_KEY to match */
  69. int auth_key_len = ED25519_PUBKEY_LEN;
  70. hs_cell_establish_intro_set_auth_key_len(cell, auth_key_len);
  71. hs_cell_establish_intro_setlen_auth_key(cell, auth_key_len);
  72. /* Set AUTH_KEY field */
  73. uint8_t *auth_key_ptr = hs_cell_establish_intro_getarray_auth_key(cell);
  74. memcpy(auth_key_ptr, key_struct.pubkey.pubkey, auth_key_len);
  75. /* No cell extensions needed */
  76. set_cell_extensions(cell);
  77. /* Set signature size.
  78. We need to do this up here, because _encode() needs it and we need to call
  79. _encode() to calculate the MAC and signature.
  80. */
  81. int sig_len = ED25519_SIG_LEN;
  82. hs_cell_establish_intro_set_sig_len(cell, sig_len);
  83. hs_cell_establish_intro_setlen_sig(cell, sig_len);
  84. /* XXX How to make this process easier and nicer? */
  85. /* Calculate the cell MAC (aka HANDSHAKE_AUTH). */
  86. {
  87. /* To calculate HANDSHAKE_AUTH, we dump the cell in bytes, and then derive
  88. the MAC from it. */
  89. uint8_t cell_bytes_tmp[RELAY_PAYLOAD_SIZE] = {0};
  90. uint8_t mac[TRUNNEL_SHA3_256_LEN];
  91. encoded_len = hs_cell_establish_intro_encode(cell_bytes_tmp,
  92. sizeof(cell_bytes_tmp),
  93. cell);
  94. if (encoded_len < 0) {
  95. log_warn(LD_OR, "Unable to pre-encode ESTABLISH_INTRO cell.");
  96. goto err;
  97. }
  98. /* sanity check */
  99. tor_assert(encoded_len > ED25519_SIG_LEN + 2 + TRUNNEL_SHA3_256_LEN);
  100. /* Calculate MAC of all fields before HANDSHAKE_AUTH */
  101. crypto_mac_sha3_256(mac, sizeof(mac),
  102. circuit_key_material, circuit_key_material_len,
  103. cell_bytes_tmp,
  104. encoded_len - (ED25519_SIG_LEN + 2 + TRUNNEL_SHA3_256_LEN));
  105. /* Write the MAC to the cell */
  106. uint8_t *handshake_ptr =
  107. hs_cell_establish_intro_getarray_handshake_mac(cell);
  108. memcpy(handshake_ptr, mac, sizeof(mac));
  109. }
  110. /* Calculate the cell signature */
  111. {
  112. /* To calculate the sig we follow the same procedure as above. We first
  113. dump the cell up to the sig, and then calculate the sig */
  114. uint8_t cell_bytes_tmp[RELAY_PAYLOAD_SIZE] = {0};
  115. ed25519_signature_t sig;
  116. encoded_len = hs_cell_establish_intro_encode(cell_bytes_tmp,
  117. sizeof(cell_bytes_tmp),
  118. cell);
  119. if (encoded_len < 0) {
  120. log_warn(LD_OR, "Unable to pre-encode ESTABLISH_INTRO cell (2).");
  121. goto err;
  122. }
  123. tor_assert(encoded_len > ED25519_SIG_LEN);
  124. if (ed25519_sign_prefixed(&sig,
  125. (uint8_t*) cell_bytes_tmp,
  126. encoded_len - ED25519_SIG_LEN,
  127. ESTABLISH_INTRO_SIG_PREFIX,
  128. &key_struct)) {
  129. log_warn(LD_BUG, "Unable to gen signature for ESTABLISH_INTRO cell.");
  130. goto err;
  131. }
  132. /* And write the signature to the cell */
  133. uint8_t *sig_ptr = hs_cell_establish_intro_getarray_sig(cell);
  134. memcpy(sig_ptr, sig.sig, sig_len);
  135. }
  136. /* We are done! Return the cell! */
  137. return cell;
  138. err:
  139. hs_cell_establish_intro_free(cell);
  140. return NULL;
  141. }
  142. #endif /* TOR_UNIT_TESTS */