#include "lib/crypt_ops/crypto_util.h"
#include "feature/relay/routerkeys.h"
#include "core/or/congestion_control_common.h"
+#include "core/crypto/relay_crypto.h"
#include "core/or/circuitbuild.h"
}
/* This is the maximum value for keys_out_len passed to
- * onion_skin_server_handshake, plus 16. We can make it bigger if needed:
+ * onion_skin_server_handshake, plus 20 for the rend_nonce.
+ * We can make it bigger if needed:
* It just defines how many bytes to stack-allocate. */
-#define MAX_KEYS_TMP_LEN 128
+#define MAX_KEYS_TMP_LEN (MAX_RELAY_KEY_MATERIAL_LEN + DIGEST_LEN)
/** Perform the second (server-side) step of a circuit-creation handshake of
* type <b>type</b>, responding to the client request in <b>onion_skin</b>
const circuit_params_t *our_ns_params,
uint8_t *reply_out,
size_t reply_out_maxlen,
+ // XXXX keys_out_len will depend on the algorithm we're negotiating.
uint8_t *keys_out, size_t keys_out_len,
uint8_t *rend_nonce_out,
circuit_params_t *params_out)
return tor1_crypt_init(crypto, key_data, key_data_len, reverse, is_hs_v3);
}
+/** Return the amount of key material we need to initialize
+ * the given relay crypto algorithm.
+ *
+ * Return -1 if the algorithm is unrecognized.
+ */
+ssize_t
+relay_crypto_key_material_len(relay_crypto_alg_t alg)
+{
+ switch (alg) {
+ case RELAY_CRYPTO_ALG_TOR1:
+ return tor1_key_material_len(false);
+ case RELAY_CRYPTO_ALG_TOR1_HS:
+ return tor1_key_material_len(true);
+ }
+ return -1;
+}
+
/** Assert that <b>crypto</b> is valid and set. */
void
relay_crypto_assert_ok(const relay_crypto_t *crypto)
#ifndef TOR_RELAY_CRYPTO_H
#define TOR_RELAY_CRYPTO_H
+typedef enum relay_crypto_alg_t {
+ RELAY_CRYPTO_ALG_TOR1,
+ RELAY_CRYPTO_ALG_TOR1_HS,
+} relay_crypto_alg_t;
+
+#define relay_crypto_alg_bitfield_t ENUM_BF(relay_crypto_alg_t)
+
+/** Largest possible return value for relay_crypto_key_material_len. */
+/* This is 2x the length needed for a single cgo direction with 256-bit AES
+ */
+#define MAX_RELAY_KEY_MATERIAL_LEN 224
+
+ssize_t relay_crypto_key_material_len(relay_crypto_alg_t alg);
+
int relay_crypto_init(relay_crypto_t *crypto,
const char *key_data, size_t key_data_len,
int reverse, int is_hs_v3);
#include "lib/arch/bytes.h"
#include "ext/polyval/polyval.h"
#include "core/crypto/relay_crypto_cgo.h"
+#include "core/crypto/relay_crypto.h"
#include "core/or/cell_st.h"
#if 0
cgo_key_material_len(int aesbits)
{
tor_assert(aesbits == 128 || aesbits == 192 || aesbits == 256);
- return (cgo_uiv_keylen(aesbits) + CGO_TAG_LEN);
+ size_t r = (cgo_uiv_keylen(aesbits) + CGO_TAG_LEN);
+ tor_assert(r * 2 <= MAX_RELAY_KEY_MATERIAL_LEN);
+ return r;
}
/**
return false;
}
+/** Return the number of bytes that tor1_crypt_init expects. */
+size_t
+tor1_key_material_len(bool is_hs)
+{
+ if (is_hs)
+ return HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN;
+ else
+ return CPATH_KEY_MATERIAL_LEN;
+}
+
/** Initialize <b>crypto</b> 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
+ * service circuits and <b>key_data</b> must be
* 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_LEN
bool tor1_crypt_client_backward(tor1_crypt_t *tor1, cell_t *cell);
void tor1_crypt_client_forward(tor1_crypt_t *tor1, cell_t *cell);
+size_t tor1_key_material_len(bool is_hs);
int tor1_crypt_init(relay_crypto_t *crypto,
const char *key_data, size_t key_data_len,
int reverse, int is_hs_v3);