Cache control file
[tor/appveyor.git] / src / or / hs_cell.c
blobad92521d34376649e12e05b234080ae06ece8e4b
1 /* Copyright (c) 2017, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 /**
5 * \file hs_cell.c
6 * \brief Hidden service API for cell creation and handling.
7 **/
9 #include "or.h"
10 #include "config.h"
11 #include "rendservice.h"
12 #include "replaycache.h"
13 #include "util.h"
15 #include "hs_cell.h"
16 #include "hs_ntor.h"
18 /* Trunnel. */
19 #include "ed25519_cert.h"
20 #include "hs/cell_common.h"
21 #include "hs/cell_establish_intro.h"
22 #include "hs/cell_introduce1.h"
23 #include "hs/cell_rendezvous.h"
25 /* Compute the MAC of an INTRODUCE cell in mac_out. The encoded_cell param is
26 * the cell content up to the ENCRYPTED section of length encoded_cell_len.
27 * The encrypted param is the start of the ENCRYPTED section of length
28 * encrypted_len. The mac_key is the key needed for the computation of the MAC
29 * derived from the ntor handshake of length mac_key_len.
31 * The length mac_out_len must be at least DIGEST256_LEN. */
32 static void
33 compute_introduce_mac(const uint8_t *encoded_cell, size_t encoded_cell_len,
34 const uint8_t *encrypted, size_t encrypted_len,
35 const uint8_t *mac_key, size_t mac_key_len,
36 uint8_t *mac_out, size_t mac_out_len)
38 size_t offset = 0;
39 size_t mac_msg_len;
40 uint8_t mac_msg[RELAY_PAYLOAD_SIZE] = {0};
42 tor_assert(encoded_cell);
43 tor_assert(encrypted);
44 tor_assert(mac_key);
45 tor_assert(mac_out);
46 tor_assert(mac_out_len >= DIGEST256_LEN);
48 /* Compute the size of the message which is basically the entire cell until
49 * the MAC field of course. */
50 mac_msg_len = encoded_cell_len + (encrypted_len - DIGEST256_LEN);
51 tor_assert(mac_msg_len <= sizeof(mac_msg));
53 /* First, put the encoded cell in the msg. */
54 memcpy(mac_msg, encoded_cell, encoded_cell_len);
55 offset += encoded_cell_len;
56 /* Second, put the CLIENT_PK + ENCRYPTED_DATA but ommit the MAC field (which
57 * is junk at this point). */
58 memcpy(mac_msg + offset, encrypted, (encrypted_len - DIGEST256_LEN));
59 offset += (encrypted_len - DIGEST256_LEN);
60 tor_assert(offset == mac_msg_len);
62 crypto_mac_sha3_256(mac_out, mac_out_len,
63 mac_key, mac_key_len,
64 mac_msg, mac_msg_len);
65 memwipe(mac_msg, 0, sizeof(mac_msg));
68 /* From a set of keys, subcredential and the ENCRYPTED section of an
69 * INTRODUCE2 cell, return a newly allocated intro cell keys structure.
70 * Finally, the client public key is copied in client_pk. On error, return
71 * NULL. */
72 static hs_ntor_intro_cell_keys_t *
73 get_introduce2_key_material(const ed25519_public_key_t *auth_key,
74 const curve25519_keypair_t *enc_key,
75 const uint8_t *subcredential,
76 const uint8_t *encrypted_section,
77 curve25519_public_key_t *client_pk)
79 hs_ntor_intro_cell_keys_t *keys;
81 tor_assert(auth_key);
82 tor_assert(enc_key);
83 tor_assert(subcredential);
84 tor_assert(encrypted_section);
85 tor_assert(client_pk);
87 keys = tor_malloc_zero(sizeof(*keys));
89 /* First bytes of the ENCRYPTED section are the client public key. */
90 memcpy(client_pk->public_key, encrypted_section, CURVE25519_PUBKEY_LEN);
92 if (hs_ntor_service_get_introduce1_keys(auth_key, enc_key, client_pk,
93 subcredential, keys) < 0) {
94 /* Don't rely on the caller to wipe this on error. */
95 memwipe(client_pk, 0, sizeof(curve25519_public_key_t));
96 tor_free(keys);
97 keys = NULL;
99 return keys;
102 /* Using the given encryption key, decrypt the encrypted_section of length
103 * encrypted_section_len of an INTRODUCE2 cell and return a newly allocated
104 * buffer containing the decrypted data. On decryption failure, NULL is
105 * returned. */
106 static uint8_t *
107 decrypt_introduce2(const uint8_t *enc_key, const uint8_t *encrypted_section,
108 size_t encrypted_section_len)
110 uint8_t *decrypted = NULL;
111 crypto_cipher_t *cipher = NULL;
113 tor_assert(enc_key);
114 tor_assert(encrypted_section);
116 /* Decrypt ENCRYPTED section. */
117 cipher = crypto_cipher_new_with_bits((char *) enc_key,
118 CURVE25519_PUBKEY_LEN * 8);
119 tor_assert(cipher);
121 /* This is symmetric encryption so can't be bigger than the encrypted
122 * section length. */
123 decrypted = tor_malloc_zero(encrypted_section_len);
124 if (crypto_cipher_decrypt(cipher, (char *) decrypted,
125 (const char *) encrypted_section,
126 encrypted_section_len) < 0) {
127 tor_free(decrypted);
128 decrypted = NULL;
129 goto done;
132 done:
133 crypto_cipher_free(cipher);
134 return decrypted;
137 /* Given a pointer to the decrypted data of the ENCRYPTED section of an
138 * INTRODUCE2 cell of length decrypted_len, parse and validate the cell
139 * content. Return a newly allocated cell structure or NULL on error. The
140 * circuit and service object are only used for logging purposes. */
141 static trn_cell_introduce_encrypted_t *
142 parse_introduce2_encrypted(const uint8_t *decrypted_data,
143 size_t decrypted_len, const origin_circuit_t *circ,
144 const hs_service_t *service)
146 trn_cell_introduce_encrypted_t *enc_cell = NULL;
148 tor_assert(decrypted_data);
149 tor_assert(circ);
150 tor_assert(service);
152 if (trn_cell_introduce_encrypted_parse(&enc_cell, decrypted_data,
153 decrypted_len) < 0) {
154 log_info(LD_REND, "Unable to parse the decrypted ENCRYPTED section of "
155 "the INTRODUCE2 cell on circuit %u for service %s",
156 TO_CIRCUIT(circ)->n_circ_id,
157 safe_str_client(service->onion_address));
158 goto err;
161 if (trn_cell_introduce_encrypted_get_onion_key_type(enc_cell) !=
162 HS_CELL_ONION_KEY_TYPE_NTOR) {
163 log_info(LD_REND, "INTRODUCE2 onion key type is invalid. Got %u but "
164 "expected %u on circuit %u for service %s",
165 trn_cell_introduce_encrypted_get_onion_key_type(enc_cell),
166 HS_CELL_ONION_KEY_TYPE_NTOR, TO_CIRCUIT(circ)->n_circ_id,
167 safe_str_client(service->onion_address));
168 goto err;
171 if (trn_cell_introduce_encrypted_getlen_onion_key(enc_cell) !=
172 CURVE25519_PUBKEY_LEN) {
173 log_info(LD_REND, "INTRODUCE2 onion key length is invalid. Got %u but "
174 "expected %d on circuit %u for service %s",
175 (unsigned)trn_cell_introduce_encrypted_getlen_onion_key(enc_cell),
176 CURVE25519_PUBKEY_LEN, TO_CIRCUIT(circ)->n_circ_id,
177 safe_str_client(service->onion_address));
178 goto err;
180 /* XXX: Validate NSPEC field as well. */
182 return enc_cell;
183 err:
184 trn_cell_introduce_encrypted_free(enc_cell);
185 return NULL;
188 /* Build a legacy ESTABLISH_INTRO cell with the given circuit nonce and RSA
189 * encryption key. The encoded cell is put in cell_out that MUST at least be
190 * of the size of RELAY_PAYLOAD_SIZE. Return the encoded cell length on
191 * success else a negative value and cell_out is untouched. */
192 static ssize_t
193 build_legacy_establish_intro(const char *circ_nonce, crypto_pk_t *enc_key,
194 uint8_t *cell_out)
196 ssize_t cell_len;
198 tor_assert(circ_nonce);
199 tor_assert(enc_key);
200 tor_assert(cell_out);
202 memwipe(cell_out, 0, RELAY_PAYLOAD_SIZE);
204 cell_len = rend_service_encode_establish_intro_cell((char*)cell_out,
205 RELAY_PAYLOAD_SIZE,
206 enc_key, circ_nonce);
207 return cell_len;
210 /* Parse an INTRODUCE2 cell from payload of size payload_len for the given
211 * service and circuit which are used only for logging purposes. The resulting
212 * parsed cell is put in cell_ptr_out.
214 * This function only parses prop224 INTRODUCE2 cells even when the intro point
215 * is a legacy intro point. That's because intro points don't actually care
216 * about the contents of the introduce cell. Legacy INTRODUCE cells are only
217 * used by the legacy system now.
219 * Return 0 on success else a negative value and cell_ptr_out is untouched. */
220 static int
221 parse_introduce2_cell(const hs_service_t *service,
222 const origin_circuit_t *circ, const uint8_t *payload,
223 size_t payload_len,
224 trn_cell_introduce1_t **cell_ptr_out)
226 trn_cell_introduce1_t *cell = NULL;
228 tor_assert(service);
229 tor_assert(circ);
230 tor_assert(payload);
231 tor_assert(cell_ptr_out);
233 /* Parse the cell so we can start cell validation. */
234 if (trn_cell_introduce1_parse(&cell, payload, payload_len) < 0) {
235 log_info(LD_PROTOCOL, "Unable to parse INTRODUCE2 cell on circuit %u "
236 "for service %s",
237 TO_CIRCUIT(circ)->n_circ_id,
238 safe_str_client(service->onion_address));
239 goto err;
242 /* Success. */
243 *cell_ptr_out = cell;
244 return 0;
245 err:
246 return -1;
249 /* Set the onion public key onion_pk in cell, the encrypted section of an
250 * INTRODUCE1 cell. */
251 static void
252 introduce1_set_encrypted_onion_key(trn_cell_introduce_encrypted_t *cell,
253 const uint8_t *onion_pk)
255 tor_assert(cell);
256 tor_assert(onion_pk);
257 /* There is only one possible key type for a non legacy cell. */
258 trn_cell_introduce_encrypted_set_onion_key_type(cell,
259 HS_CELL_ONION_KEY_TYPE_NTOR);
260 trn_cell_introduce_encrypted_set_onion_key_len(cell, CURVE25519_PUBKEY_LEN);
261 trn_cell_introduce_encrypted_setlen_onion_key(cell, CURVE25519_PUBKEY_LEN);
262 memcpy(trn_cell_introduce_encrypted_getarray_onion_key(cell), onion_pk,
263 trn_cell_introduce_encrypted_getlen_onion_key(cell));
266 /* Set the link specifiers in lspecs in cell, the encrypted section of an
267 * INTRODUCE1 cell. */
268 static void
269 introduce1_set_encrypted_link_spec(trn_cell_introduce_encrypted_t *cell,
270 const smartlist_t *lspecs)
272 tor_assert(cell);
273 tor_assert(lspecs);
274 tor_assert(smartlist_len(lspecs) > 0);
275 tor_assert(smartlist_len(lspecs) <= UINT8_MAX);
277 uint8_t lspecs_num = (uint8_t) smartlist_len(lspecs);
278 trn_cell_introduce_encrypted_set_nspec(cell, lspecs_num);
279 /* We aren't duplicating the link specifiers object here which means that
280 * the ownership goes to the trn_cell_introduce_encrypted_t cell and those
281 * object will be freed when the cell is. */
282 SMARTLIST_FOREACH(lspecs, link_specifier_t *, ls,
283 trn_cell_introduce_encrypted_add_nspecs(cell, ls));
286 /* Set padding in the enc_cell only if needed that is the total length of both
287 * sections are below the mininum required for an INTRODUCE1 cell. */
288 static void
289 introduce1_set_encrypted_padding(const trn_cell_introduce1_t *cell,
290 trn_cell_introduce_encrypted_t *enc_cell)
292 tor_assert(cell);
293 tor_assert(enc_cell);
294 /* This is the length we expect to have once encoded of the whole cell. */
295 ssize_t full_len = trn_cell_introduce1_encoded_len(cell) +
296 trn_cell_introduce_encrypted_encoded_len(enc_cell);
297 tor_assert(full_len > 0);
298 if (full_len < HS_CELL_INTRODUCE1_MIN_SIZE) {
299 size_t padding = HS_CELL_INTRODUCE1_MIN_SIZE - full_len;
300 trn_cell_introduce_encrypted_setlen_pad(enc_cell, padding);
301 memset(trn_cell_introduce_encrypted_getarray_pad(enc_cell), 0,
302 trn_cell_introduce_encrypted_getlen_pad(enc_cell));
306 /* Encrypt the ENCRYPTED payload and encode it in the cell using the enc_cell
307 * and the INTRODUCE1 data.
309 * This can't fail but it is very important that the caller sets every field
310 * in data so the computation of the INTRODUCE1 keys doesn't fail. */
311 static void
312 introduce1_encrypt_and_encode(trn_cell_introduce1_t *cell,
313 const trn_cell_introduce_encrypted_t *enc_cell,
314 const hs_cell_introduce1_data_t *data)
316 size_t offset = 0;
317 ssize_t encrypted_len;
318 ssize_t encoded_cell_len, encoded_enc_cell_len;
319 uint8_t encoded_cell[RELAY_PAYLOAD_SIZE] = {0};
320 uint8_t encoded_enc_cell[RELAY_PAYLOAD_SIZE] = {0};
321 uint8_t *encrypted = NULL;
322 uint8_t mac[DIGEST256_LEN];
323 crypto_cipher_t *cipher = NULL;
324 hs_ntor_intro_cell_keys_t keys;
326 tor_assert(cell);
327 tor_assert(enc_cell);
328 tor_assert(data);
330 /* Encode the cells up to now of what we have to we can perform the MAC
331 * computation on it. */
332 encoded_cell_len = trn_cell_introduce1_encode(encoded_cell,
333 sizeof(encoded_cell), cell);
334 /* We have a much more serious issue if this isn't true. */
335 tor_assert(encoded_cell_len > 0);
337 encoded_enc_cell_len =
338 trn_cell_introduce_encrypted_encode(encoded_enc_cell,
339 sizeof(encoded_enc_cell), enc_cell);
340 /* We have a much more serious issue if this isn't true. */
341 tor_assert(encoded_enc_cell_len > 0);
343 /* Get the key material for the encryption. */
344 if (hs_ntor_client_get_introduce1_keys(data->auth_pk, data->enc_pk,
345 data->client_kp,
346 data->subcredential, &keys) < 0) {
347 tor_assert_unreached();
350 /* Prepare cipher with the encryption key just computed. */
351 cipher = crypto_cipher_new_with_bits((const char *) keys.enc_key,
352 sizeof(keys.enc_key) * 8);
353 tor_assert(cipher);
355 /* Compute the length of the ENCRYPTED section which is the CLIENT_PK,
356 * ENCRYPTED_DATA and MAC length. */
357 encrypted_len = sizeof(data->client_kp->pubkey) + encoded_enc_cell_len +
358 sizeof(mac);
359 tor_assert(encrypted_len < RELAY_PAYLOAD_SIZE);
360 encrypted = tor_malloc_zero(encrypted_len);
362 /* Put the CLIENT_PK first. */
363 memcpy(encrypted, data->client_kp->pubkey.public_key,
364 sizeof(data->client_kp->pubkey.public_key));
365 offset += sizeof(data->client_kp->pubkey.public_key);
366 /* Then encrypt and set the ENCRYPTED_DATA. This can't fail. */
367 crypto_cipher_encrypt(cipher, (char *) encrypted + offset,
368 (const char *) encoded_enc_cell, encoded_enc_cell_len);
369 crypto_cipher_free(cipher);
370 offset += encoded_enc_cell_len;
371 /* Compute MAC from the above and put it in the buffer. This function will
372 * make the adjustment to the encrypted_len to omit the MAC length. */
373 compute_introduce_mac(encoded_cell, encoded_cell_len,
374 encrypted, encrypted_len,
375 keys.mac_key, sizeof(keys.mac_key),
376 mac, sizeof(mac));
377 memcpy(encrypted + offset, mac, sizeof(mac));
378 offset += sizeof(mac);
379 tor_assert(offset == (size_t) encrypted_len);
381 /* Set the ENCRYPTED section in the cell. */
382 trn_cell_introduce1_setlen_encrypted(cell, encrypted_len);
383 memcpy(trn_cell_introduce1_getarray_encrypted(cell),
384 encrypted, encrypted_len);
386 /* Cleanup. */
387 memwipe(&keys, 0, sizeof(keys));
388 memwipe(mac, 0, sizeof(mac));
389 memwipe(encrypted, 0, sizeof(encrypted_len));
390 memwipe(encoded_enc_cell, 0, sizeof(encoded_enc_cell));
391 tor_free(encrypted);
394 /* Using the INTRODUCE1 data, setup the ENCRYPTED section in cell. This means
395 * set it, encrypt it and encode it. */
396 static void
397 introduce1_set_encrypted(trn_cell_introduce1_t *cell,
398 const hs_cell_introduce1_data_t *data)
400 trn_cell_introduce_encrypted_t *enc_cell;
401 trn_cell_extension_t *ext;
403 tor_assert(cell);
404 tor_assert(data);
406 enc_cell = trn_cell_introduce_encrypted_new();
407 tor_assert(enc_cell);
409 /* Set extension data. None are used. */
410 ext = trn_cell_extension_new();
411 tor_assert(ext);
412 trn_cell_extension_set_num(ext, 0);
413 trn_cell_introduce_encrypted_set_extensions(enc_cell, ext);
415 /* Set the rendezvous cookie. */
416 memcpy(trn_cell_introduce_encrypted_getarray_rend_cookie(enc_cell),
417 data->rendezvous_cookie, REND_COOKIE_LEN);
419 /* Set the onion public key. */
420 introduce1_set_encrypted_onion_key(enc_cell, data->onion_pk->public_key);
422 /* Set the link specifiers. */
423 introduce1_set_encrypted_link_spec(enc_cell, data->link_specifiers);
425 /* Set padding. */
426 introduce1_set_encrypted_padding(cell, enc_cell);
428 /* Encrypt and encode it in the cell. */
429 introduce1_encrypt_and_encode(cell, enc_cell, data);
431 /* Cleanup. */
432 trn_cell_introduce_encrypted_free(enc_cell);
435 /* Set the authentication key in the INTRODUCE1 cell from the given data. */
436 static void
437 introduce1_set_auth_key(trn_cell_introduce1_t *cell,
438 const hs_cell_introduce1_data_t *data)
440 tor_assert(cell);
441 tor_assert(data);
442 /* There is only one possible type for a non legacy cell. */
443 trn_cell_introduce1_set_auth_key_type(cell, HS_INTRO_AUTH_KEY_TYPE_ED25519);
444 trn_cell_introduce1_set_auth_key_len(cell, ED25519_PUBKEY_LEN);
445 trn_cell_introduce1_setlen_auth_key(cell, ED25519_PUBKEY_LEN);
446 memcpy(trn_cell_introduce1_getarray_auth_key(cell),
447 data->auth_pk->pubkey, trn_cell_introduce1_getlen_auth_key(cell));
450 /* Set the legacy ID field in the INTRODUCE1 cell from the given data. */
451 static void
452 introduce1_set_legacy_id(trn_cell_introduce1_t *cell,
453 const hs_cell_introduce1_data_t *data)
455 tor_assert(cell);
456 tor_assert(data);
458 if (data->is_legacy) {
459 uint8_t digest[DIGEST_LEN];
460 if (BUG(crypto_pk_get_digest(data->legacy_key, (char *) digest) < 0)) {
461 return;
463 memcpy(trn_cell_introduce1_getarray_legacy_key_id(cell),
464 digest, trn_cell_introduce1_getlen_legacy_key_id(cell));
465 } else {
466 /* We have to zeroed the LEGACY_KEY_ID field. */
467 memset(trn_cell_introduce1_getarray_legacy_key_id(cell), 0,
468 trn_cell_introduce1_getlen_legacy_key_id(cell));
472 /* ========== */
473 /* Public API */
474 /* ========== */
476 /* Build an ESTABLISH_INTRO cell with the given circuit nonce and intro point
477 * object. The encoded cell is put in cell_out that MUST at least be of the
478 * size of RELAY_PAYLOAD_SIZE. Return the encoded cell length on success else
479 * a negative value and cell_out is untouched. This function also supports
480 * legacy cell creation. */
481 ssize_t
482 hs_cell_build_establish_intro(const char *circ_nonce,
483 const hs_service_intro_point_t *ip,
484 uint8_t *cell_out)
486 ssize_t cell_len = -1;
487 uint16_t sig_len = ED25519_SIG_LEN;
488 trn_cell_extension_t *ext;
489 trn_cell_establish_intro_t *cell = NULL;
491 tor_assert(circ_nonce);
492 tor_assert(ip);
494 /* Quickly handle the legacy IP. */
495 if (ip->base.is_only_legacy) {
496 tor_assert(ip->legacy_key);
497 cell_len = build_legacy_establish_intro(circ_nonce, ip->legacy_key,
498 cell_out);
499 tor_assert(cell_len <= RELAY_PAYLOAD_SIZE);
500 /* Success or not we are done here. */
501 goto done;
504 /* Set extension data. None used here. */
505 ext = trn_cell_extension_new();
506 trn_cell_extension_set_num(ext, 0);
507 cell = trn_cell_establish_intro_new();
508 trn_cell_establish_intro_set_extensions(cell, ext);
509 /* Set signature size. Array is then allocated in the cell. We need to do
510 * this early so we can use trunnel API to get the signature length. */
511 trn_cell_establish_intro_set_sig_len(cell, sig_len);
512 trn_cell_establish_intro_setlen_sig(cell, sig_len);
514 /* Set AUTH_KEY_TYPE: 2 means ed25519 */
515 trn_cell_establish_intro_set_auth_key_type(cell,
516 HS_INTRO_AUTH_KEY_TYPE_ED25519);
518 /* Set AUTH_KEY and AUTH_KEY_LEN field. Must also set byte-length of
519 * AUTH_KEY to match */
521 uint16_t auth_key_len = ED25519_PUBKEY_LEN;
522 trn_cell_establish_intro_set_auth_key_len(cell, auth_key_len);
523 trn_cell_establish_intro_setlen_auth_key(cell, auth_key_len);
524 /* We do this call _after_ setting the length because it's reallocated at
525 * that point only. */
526 uint8_t *auth_key_ptr = trn_cell_establish_intro_getarray_auth_key(cell);
527 memcpy(auth_key_ptr, ip->auth_key_kp.pubkey.pubkey, auth_key_len);
530 /* Calculate HANDSHAKE_AUTH field (MAC). */
532 ssize_t tmp_cell_enc_len = 0;
533 ssize_t tmp_cell_mac_offset =
534 sig_len + sizeof(cell->sig_len) +
535 trn_cell_establish_intro_getlen_handshake_mac(cell);
536 uint8_t tmp_cell_enc[RELAY_PAYLOAD_SIZE] = {0};
537 uint8_t mac[TRUNNEL_SHA3_256_LEN], *handshake_ptr;
539 /* We first encode the current fields we have in the cell so we can
540 * compute the MAC using the raw bytes. */
541 tmp_cell_enc_len = trn_cell_establish_intro_encode(tmp_cell_enc,
542 sizeof(tmp_cell_enc),
543 cell);
544 if (BUG(tmp_cell_enc_len < 0)) {
545 goto done;
547 /* Sanity check. */
548 tor_assert(tmp_cell_enc_len > tmp_cell_mac_offset);
550 /* Circuit nonce is always DIGEST_LEN according to tor-spec.txt. */
551 crypto_mac_sha3_256(mac, sizeof(mac),
552 (uint8_t *) circ_nonce, DIGEST_LEN,
553 tmp_cell_enc, tmp_cell_enc_len - tmp_cell_mac_offset);
554 handshake_ptr = trn_cell_establish_intro_getarray_handshake_mac(cell);
555 memcpy(handshake_ptr, mac, sizeof(mac));
557 memwipe(mac, 0, sizeof(mac));
558 memwipe(tmp_cell_enc, 0, sizeof(tmp_cell_enc));
561 /* Calculate the cell signature SIG. */
563 ssize_t tmp_cell_enc_len = 0;
564 ssize_t tmp_cell_sig_offset = (sig_len + sizeof(cell->sig_len));
565 uint8_t tmp_cell_enc[RELAY_PAYLOAD_SIZE] = {0}, *sig_ptr;
566 ed25519_signature_t sig;
568 /* We first encode the current fields we have in the cell so we can
569 * compute the signature from the raw bytes of the cell. */
570 tmp_cell_enc_len = trn_cell_establish_intro_encode(tmp_cell_enc,
571 sizeof(tmp_cell_enc),
572 cell);
573 if (BUG(tmp_cell_enc_len < 0)) {
574 goto done;
577 if (ed25519_sign_prefixed(&sig, tmp_cell_enc,
578 tmp_cell_enc_len - tmp_cell_sig_offset,
579 ESTABLISH_INTRO_SIG_PREFIX, &ip->auth_key_kp)) {
580 log_warn(LD_BUG, "Unable to make signature for ESTABLISH_INTRO cell.");
581 goto done;
583 /* Copy the signature into the cell. */
584 sig_ptr = trn_cell_establish_intro_getarray_sig(cell);
585 memcpy(sig_ptr, sig.sig, sig_len);
587 memwipe(tmp_cell_enc, 0, sizeof(tmp_cell_enc));
590 /* Encode the cell. Can't be bigger than a standard cell. */
591 cell_len = trn_cell_establish_intro_encode(cell_out, RELAY_PAYLOAD_SIZE,
592 cell);
594 done:
595 trn_cell_establish_intro_free(cell);
596 return cell_len;
599 /* Parse the INTRO_ESTABLISHED cell in the payload of size payload_len. If we
600 * are successful at parsing it, return the length of the parsed cell else a
601 * negative value on error. */
602 ssize_t
603 hs_cell_parse_intro_established(const uint8_t *payload, size_t payload_len)
605 ssize_t ret;
606 trn_cell_intro_established_t *cell = NULL;
608 tor_assert(payload);
610 /* Try to parse the payload into a cell making sure we do actually have a
611 * valid cell. */
612 ret = trn_cell_intro_established_parse(&cell, payload, payload_len);
613 if (ret >= 0) {
614 /* On success, we do not keep the cell, we just notify the caller that it
615 * was successfully parsed. */
616 trn_cell_intro_established_free(cell);
618 return ret;
621 /* Parsse the INTRODUCE2 cell using data which contains everything we need to
622 * do so and contains the destination buffers of information we extract and
623 * compute from the cell. Return 0 on success else a negative value. The
624 * service and circ are only used for logging purposes. */
625 ssize_t
626 hs_cell_parse_introduce2(hs_cell_introduce2_data_t *data,
627 const origin_circuit_t *circ,
628 const hs_service_t *service)
630 int ret = -1;
631 time_t elapsed;
632 uint8_t *decrypted = NULL;
633 size_t encrypted_section_len;
634 const uint8_t *encrypted_section;
635 trn_cell_introduce1_t *cell = NULL;
636 trn_cell_introduce_encrypted_t *enc_cell = NULL;
637 hs_ntor_intro_cell_keys_t *intro_keys = NULL;
639 tor_assert(data);
640 tor_assert(circ);
641 tor_assert(service);
643 /* Parse the cell into a decoded data structure pointed by cell_ptr. */
644 if (parse_introduce2_cell(service, circ, data->payload, data->payload_len,
645 &cell) < 0) {
646 goto done;
649 log_info(LD_REND, "Received a decodable INTRODUCE2 cell on circuit %u "
650 "for service %s. Decoding encrypted section...",
651 TO_CIRCUIT(circ)->n_circ_id,
652 safe_str_client(service->onion_address));
654 encrypted_section = trn_cell_introduce1_getconstarray_encrypted(cell);
655 encrypted_section_len = trn_cell_introduce1_getlen_encrypted(cell);
657 /* Encrypted section must at least contain the CLIENT_PK and MAC which is
658 * defined in section 3.3.2 of the specification. */
659 if (encrypted_section_len < (CURVE25519_PUBKEY_LEN + DIGEST256_LEN)) {
660 log_info(LD_REND, "Invalid INTRODUCE2 encrypted section length "
661 "for service %s. Dropping cell.",
662 safe_str_client(service->onion_address));
663 goto done;
666 /* Check our replay cache for this introduction point. */
667 if (replaycache_add_test_and_elapsed(data->replay_cache, encrypted_section,
668 encrypted_section_len, &elapsed)) {
669 log_warn(LD_REND, "Possible replay detected! An INTRODUCE2 cell with the"
670 "same ENCRYPTED section was seen %ld seconds ago. "
671 "Dropping cell.", (long int) elapsed);
672 goto done;
675 /* Build the key material out of the key material found in the cell. */
676 intro_keys = get_introduce2_key_material(data->auth_pk, data->enc_kp,
677 data->subcredential,
678 encrypted_section,
679 &data->client_pk);
680 if (intro_keys == NULL) {
681 log_info(LD_REND, "Invalid INTRODUCE2 encrypted data. Unable to "
682 "compute key material on circuit %u for service %s",
683 TO_CIRCUIT(circ)->n_circ_id,
684 safe_str_client(service->onion_address));
685 goto done;
688 /* Validate MAC from the cell and our computed key material. The MAC field
689 * in the cell is at the end of the encrypted section. */
691 uint8_t mac[DIGEST256_LEN];
692 /* The MAC field is at the very end of the ENCRYPTED section. */
693 size_t mac_offset = encrypted_section_len - sizeof(mac);
694 /* Compute the MAC. Use the entire encoded payload with a length up to the
695 * ENCRYPTED section. */
696 compute_introduce_mac(data->payload,
697 data->payload_len - encrypted_section_len,
698 encrypted_section, encrypted_section_len,
699 intro_keys->mac_key, sizeof(intro_keys->mac_key),
700 mac, sizeof(mac));
701 if (tor_memcmp(mac, encrypted_section + mac_offset, sizeof(mac))) {
702 log_info(LD_REND, "Invalid MAC validation for INTRODUCE2 cell on "
703 "circuit %u for service %s",
704 TO_CIRCUIT(circ)->n_circ_id,
705 safe_str_client(service->onion_address));
706 goto done;
711 /* The ENCRYPTED_DATA section starts just after the CLIENT_PK. */
712 const uint8_t *encrypted_data =
713 encrypted_section + sizeof(data->client_pk);
714 /* It's symmetric encryption so it's correct to use the ENCRYPTED length
715 * for decryption. Computes the length of ENCRYPTED_DATA meaning removing
716 * the CLIENT_PK and MAC length. */
717 size_t encrypted_data_len =
718 encrypted_section_len - (sizeof(data->client_pk) + DIGEST256_LEN);
720 /* This decrypts the ENCRYPTED_DATA section of the cell. */
721 decrypted = decrypt_introduce2(intro_keys->enc_key,
722 encrypted_data, encrypted_data_len);
723 if (decrypted == NULL) {
724 log_info(LD_REND, "Unable to decrypt the ENCRYPTED section of an "
725 "INTRODUCE2 cell on circuit %u for service %s",
726 TO_CIRCUIT(circ)->n_circ_id,
727 safe_str_client(service->onion_address));
728 goto done;
731 /* Parse this blob into an encrypted cell structure so we can then extract
732 * the data we need out of it. */
733 enc_cell = parse_introduce2_encrypted(decrypted, encrypted_data_len,
734 circ, service);
735 memwipe(decrypted, 0, encrypted_data_len);
736 if (enc_cell == NULL) {
737 goto done;
741 /* XXX: Implement client authorization checks. */
743 /* Extract onion key and rendezvous cookie from the cell used for the
744 * rendezvous point circuit e2e encryption. */
745 memcpy(data->onion_pk.public_key,
746 trn_cell_introduce_encrypted_getconstarray_onion_key(enc_cell),
747 CURVE25519_PUBKEY_LEN);
748 memcpy(data->rendezvous_cookie,
749 trn_cell_introduce_encrypted_getconstarray_rend_cookie(enc_cell),
750 sizeof(data->rendezvous_cookie));
752 /* Extract rendezvous link specifiers. */
753 for (size_t idx = 0;
754 idx < trn_cell_introduce_encrypted_get_nspec(enc_cell); idx++) {
755 link_specifier_t *lspec =
756 trn_cell_introduce_encrypted_get_nspecs(enc_cell, idx);
757 smartlist_add(data->link_specifiers, hs_link_specifier_dup(lspec));
760 /* Success. */
761 ret = 0;
762 log_info(LD_REND, "Valid INTRODUCE2 cell. Launching rendezvous circuit.");
764 done:
765 if (intro_keys) {
766 memwipe(intro_keys, 0, sizeof(hs_ntor_intro_cell_keys_t));
767 tor_free(intro_keys);
769 tor_free(decrypted);
770 trn_cell_introduce_encrypted_free(enc_cell);
771 trn_cell_introduce1_free(cell);
772 return ret;
775 /* Build a RENDEZVOUS1 cell with the given rendezvous cookie and handshake
776 * info. The encoded cell is put in cell_out and the length of the data is
777 * returned. This can't fail. */
778 ssize_t
779 hs_cell_build_rendezvous1(const uint8_t *rendezvous_cookie,
780 size_t rendezvous_cookie_len,
781 const uint8_t *rendezvous_handshake_info,
782 size_t rendezvous_handshake_info_len,
783 uint8_t *cell_out)
785 ssize_t cell_len;
786 trn_cell_rendezvous1_t *cell;
788 tor_assert(rendezvous_cookie);
789 tor_assert(rendezvous_handshake_info);
790 tor_assert(cell_out);
792 cell = trn_cell_rendezvous1_new();
793 /* Set the RENDEZVOUS_COOKIE. */
794 memcpy(trn_cell_rendezvous1_getarray_rendezvous_cookie(cell),
795 rendezvous_cookie, rendezvous_cookie_len);
796 /* Set the HANDSHAKE_INFO. */
797 trn_cell_rendezvous1_setlen_handshake_info(cell,
798 rendezvous_handshake_info_len);
799 memcpy(trn_cell_rendezvous1_getarray_handshake_info(cell),
800 rendezvous_handshake_info, rendezvous_handshake_info_len);
801 /* Encoding. */
802 cell_len = trn_cell_rendezvous1_encode(cell_out, RELAY_PAYLOAD_SIZE, cell);
803 tor_assert(cell_len > 0);
805 trn_cell_rendezvous1_free(cell);
806 return cell_len;
809 /* Build an INTRODUCE1 cell from the given data. The encoded cell is put in
810 * cell_out which must be of at least size RELAY_PAYLOAD_SIZE. On success, the
811 * encoded length is returned else a negative value and the content of
812 * cell_out should be ignored. */
813 ssize_t
814 hs_cell_build_introduce1(const hs_cell_introduce1_data_t *data,
815 uint8_t *cell_out)
817 ssize_t cell_len;
818 trn_cell_introduce1_t *cell;
819 trn_cell_extension_t *ext;
821 tor_assert(data);
822 tor_assert(cell_out);
824 cell = trn_cell_introduce1_new();
825 tor_assert(cell);
827 /* Set extension data. None are used. */
828 ext = trn_cell_extension_new();
829 tor_assert(ext);
830 trn_cell_extension_set_num(ext, 0);
831 trn_cell_introduce1_set_extensions(cell, ext);
833 /* Set the legacy ID field. */
834 introduce1_set_legacy_id(cell, data);
836 /* Set the authentication key. */
837 introduce1_set_auth_key(cell, data);
839 /* Set the encrypted section. This will set, encrypt and encode the
840 * ENCRYPTED section in the cell. After this, we'll be ready to encode. */
841 introduce1_set_encrypted(cell, data);
843 /* Final encoding. */
844 cell_len = trn_cell_introduce1_encode(cell_out, RELAY_PAYLOAD_SIZE, cell);
846 trn_cell_introduce1_free(cell);
847 return cell_len;
850 /* Build an ESTABLISH_RENDEZVOUS cell from the given rendezvous_cookie. The
851 * encoded cell is put in cell_out which must be of at least
852 * RELAY_PAYLOAD_SIZE. On success, the encoded length is returned and the
853 * caller should clear up the content of the cell.
855 * This function can't fail. */
856 ssize_t
857 hs_cell_build_establish_rendezvous(const uint8_t *rendezvous_cookie,
858 uint8_t *cell_out)
860 tor_assert(rendezvous_cookie);
861 tor_assert(cell_out);
863 memcpy(cell_out, rendezvous_cookie, HS_REND_COOKIE_LEN);
864 return HS_REND_COOKIE_LEN;
867 /* Handle an INTRODUCE_ACK cell encoded in payload of length payload_len.
868 * Return the status code on success else a negative value if the cell as not
869 * decodable. */
871 hs_cell_parse_introduce_ack(const uint8_t *payload, size_t payload_len)
873 int ret = -1;
874 trn_cell_introduce_ack_t *cell = NULL;
876 tor_assert(payload);
878 /* If it is a legacy IP, rend-spec.txt specifies that a ACK is 0 byte and a
879 * NACK is 1 byte. We can't use the legacy function for this so we have to
880 * do a special case. */
881 if (payload_len <= 1) {
882 if (payload_len == 0) {
883 ret = HS_CELL_INTRO_ACK_SUCCESS;
884 } else {
885 ret = HS_CELL_INTRO_ACK_FAILURE;
887 goto end;
890 if (trn_cell_introduce_ack_parse(&cell, payload, payload_len) < 0) {
891 log_info(LD_REND, "Invalid INTRODUCE_ACK cell. Unable to parse it.");
892 goto end;
895 ret = trn_cell_introduce_ack_get_status(cell);
897 end:
898 trn_cell_introduce_ack_free(cell);
899 return ret;
902 /* Handle a RENDEZVOUS2 cell encoded in payload of length payload_len. On
903 * success, handshake_info contains the data in the HANDSHAKE_INFO field, and
904 * 0 is returned. On error, a negative value is returned. */
906 hs_cell_parse_rendezvous2(const uint8_t *payload, size_t payload_len,
907 uint8_t *handshake_info, size_t handshake_info_len)
909 int ret = -1;
910 trn_cell_rendezvous2_t *cell = NULL;
912 tor_assert(payload);
913 tor_assert(handshake_info);
915 if (trn_cell_rendezvous2_parse(&cell, payload, payload_len) < 0) {
916 log_info(LD_REND, "Invalid RENDEZVOUS2 cell. Unable to parse it.");
917 goto end;
920 /* Static size, we should never have an issue with this else we messed up
921 * our code flow. */
922 tor_assert(trn_cell_rendezvous2_getlen_handshake_info(cell) ==
923 handshake_info_len);
924 memcpy(handshake_info,
925 trn_cell_rendezvous2_getconstarray_handshake_info(cell),
926 handshake_info_len);
927 ret = 0;
929 end:
930 trn_cell_rendezvous2_free(cell);
931 return ret;
934 /* Clear the given INTRODUCE1 data structure data. */
935 void
936 hs_cell_introduce1_data_clear(hs_cell_introduce1_data_t *data)
938 if (data == NULL) {
939 return;
941 /* Object in this list have been moved to the cell object when building it
942 * so they've been freed earlier. We do that in order to avoid duplicating
943 * them leading to more memory and CPU time being used for nothing. */
944 smartlist_free(data->link_specifiers);
945 /* The data object has no ownership of any members. */
946 memwipe(data, 0, sizeof(hs_cell_introduce1_data_t));