|
@@ -1325,9 +1325,14 @@ circuit_extend(cell_t *cell, circuit_t *circ)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/** Initialize cpath-\>{f|b}_{crypto|digest} from the key material in
|
|
|
- * key_data. key_data must contain CPATH_KEY_MATERIAL bytes, which are
|
|
|
- * used as follows:
|
|
|
+/** Initialize cpath-\>{f|b}_{crypto|digest} from the key material in key_data.
|
|
|
+ *
|
|
|
+ * If <b>is_hs_v3</b> is set, this cpath will be used for next gen hidden
|
|
|
+ * service circuits and <b>key_data</b> must be at least
|
|
|
+ * HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN bytes in length.
|
|
|
+ *
|
|
|
+ * If <b>is_hs_v3</b> is not set, key_data must contain CPATH_KEY_MATERIAL
|
|
|
+ * bytes, which are used as follows:
|
|
|
* - 20 to initialize f_digest
|
|
|
* - 20 to initialize b_digest
|
|
|
* - 16 to key f_crypto
|
|
@@ -1337,28 +1342,49 @@ circuit_extend(cell_t *cell, circuit_t *circ)
|
|
|
*/
|
|
|
int
|
|
|
circuit_init_cpath_crypto(crypt_path_t *cpath, const char *key_data,
|
|
|
- int reverse)
|
|
|
+ int reverse, int is_hs_v3)
|
|
|
{
|
|
|
crypto_digest_t *tmp_digest;
|
|
|
crypto_cipher_t *tmp_crypto;
|
|
|
+ size_t digest_len = 0;
|
|
|
+ size_t cipher_key_len = 0;
|
|
|
|
|
|
tor_assert(cpath);
|
|
|
tor_assert(key_data);
|
|
|
tor_assert(!(cpath->f_crypto || cpath->b_crypto ||
|
|
|
cpath->f_digest || cpath->b_digest));
|
|
|
|
|
|
- cpath->f_digest = crypto_digest_new();
|
|
|
- crypto_digest_add_bytes(cpath->f_digest, key_data, DIGEST_LEN);
|
|
|
- cpath->b_digest = crypto_digest_new();
|
|
|
- crypto_digest_add_bytes(cpath->b_digest, key_data+DIGEST_LEN, DIGEST_LEN);
|
|
|
+ /* If we are using this cpath for next gen onion services use SHA3-256,
|
|
|
+ otherwise use good ol' SHA1 */
|
|
|
+ if (is_hs_v3) {
|
|
|
+ digest_len = DIGEST256_LEN;
|
|
|
+ cipher_key_len = CIPHER256_KEY_LEN;
|
|
|
+ cpath->f_digest = crypto_digest256_new(DIGEST_SHA3_256);
|
|
|
+ cpath->b_digest = crypto_digest256_new(DIGEST_SHA3_256);
|
|
|
+ } else {
|
|
|
+ digest_len = DIGEST_LEN;
|
|
|
+ cipher_key_len = CIPHER_KEY_LEN;
|
|
|
+ cpath->f_digest = crypto_digest_new();
|
|
|
+ cpath->b_digest = crypto_digest_new();
|
|
|
+ }
|
|
|
|
|
|
- if (!(cpath->f_crypto =
|
|
|
- crypto_cipher_new(key_data+(2*DIGEST_LEN)))) {
|
|
|
+ tor_assert(digest_len != 0);
|
|
|
+ tor_assert(cipher_key_len != 0);
|
|
|
+
|
|
|
+ crypto_digest_add_bytes(cpath->f_digest, key_data, digest_len);
|
|
|
+ crypto_digest_add_bytes(cpath->b_digest, key_data+digest_len, digest_len);
|
|
|
+
|
|
|
+ cpath->f_crypto = crypto_cipher_new_with_bits(key_data+(2*digest_len),
|
|
|
+ cipher_key_len*8);
|
|
|
+ if (!cpath->f_crypto) {
|
|
|
log_warn(LD_BUG,"Forward cipher initialization failed.");
|
|
|
return -1;
|
|
|
}
|
|
|
- if (!(cpath->b_crypto =
|
|
|
- crypto_cipher_new(key_data+(2*DIGEST_LEN)+CIPHER_KEY_LEN))) {
|
|
|
+
|
|
|
+ cpath->b_crypto = crypto_cipher_new_with_bits(
|
|
|
+ key_data+(2*digest_len)+cipher_key_len,
|
|
|
+ cipher_key_len*8);
|
|
|
+ if (!cpath->b_crypto) {
|
|
|
log_warn(LD_BUG,"Backward cipher initialization failed.");
|
|
|
return -1;
|
|
|
}
|
|
@@ -1424,7 +1450,7 @@ circuit_finish_handshake(origin_circuit_t *circ,
|
|
|
|
|
|
onion_handshake_state_release(&hop->handshake_state);
|
|
|
|
|
|
- if (circuit_init_cpath_crypto(hop, keys, 0)<0) {
|
|
|
+ if (circuit_init_cpath_crypto(hop, keys, 0, 0)<0) {
|
|
|
return -END_CIRC_REASON_TORPROTOCOL;
|
|
|
}
|
|
|
|
|
@@ -1512,7 +1538,7 @@ onionskin_answer(or_circuit_t *circ,
|
|
|
log_debug(LD_CIRC,"init digest forward 0x%.8x, backward 0x%.8x.",
|
|
|
(unsigned int)get_uint32(keys),
|
|
|
(unsigned int)get_uint32(keys+20));
|
|
|
- if (circuit_init_cpath_crypto(tmp_cpath, keys, 0)<0) {
|
|
|
+ if (circuit_init_cpath_crypto(tmp_cpath, keys, 0, 0)<0) {
|
|
|
log_warn(LD_BUG,"Circuit initialization failed");
|
|
|
tor_free(tmp_cpath);
|
|
|
return -1;
|