mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
Compute OPE cipher structure only when needed.
The OPE cipher is tied to the current blinded key which is tied to the current time period. Hence create the OPE cipher structure when we create a new descriptor (and build its blinded key).
This commit is contained in:
parent
f00b7a7faa
commit
d8b71609cb
@ -1074,6 +1074,7 @@ service_descriptor_free_(hs_service_descriptor_t *desc)
|
||||
SMARTLIST_FOREACH(desc->previous_hsdirs, char *, s, tor_free(s));
|
||||
smartlist_free(desc->previous_hsdirs);
|
||||
}
|
||||
crypto_ope_free(desc->ope_cipher);
|
||||
tor_free(desc);
|
||||
}
|
||||
|
||||
@ -1378,13 +1379,30 @@ build_service_desc_plaintext(const hs_service_t *service,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Compute the descriptor's OPE cipher for encrypting revision counters. */
|
||||
static crypto_ope_t *
|
||||
generate_ope_cipher_for_desc(const hs_service_descriptor_t *hs_desc)
|
||||
{
|
||||
/* Compute OPE key as H("rev-counter-generation" | blinded privkey) */
|
||||
uint8_t key[DIGEST256_LEN];
|
||||
crypto_digest_t *digest = crypto_digest256_new(DIGEST_SHA3_256);
|
||||
const char ope_key_prefix[] = "rev-counter-generation";
|
||||
const ed25519_secret_key_t *eph_privkey = &hs_desc->blinded_kp.seckey;
|
||||
crypto_digest_add_bytes(digest, ope_key_prefix, sizeof(ope_key_prefix));
|
||||
crypto_digest_add_bytes(digest, (char*)eph_privkey->seckey,
|
||||
sizeof(eph_privkey->seckey));
|
||||
crypto_digest_get_digest(digest, (char *)key, sizeof(key));
|
||||
crypto_digest_free(digest);
|
||||
|
||||
return crypto_ope_new(key);
|
||||
}
|
||||
|
||||
/* For the given service and descriptor object, create the key material which
|
||||
* is the blinded keypair and the descriptor signing keypair. Return 0 on
|
||||
* success else -1 on error where the generated keys MUST be ignored. */
|
||||
static int
|
||||
build_service_desc_keys(const hs_service_t *service,
|
||||
hs_service_descriptor_t *desc,
|
||||
uint64_t time_period_num)
|
||||
hs_service_descriptor_t *desc)
|
||||
{
|
||||
int ret = 0;
|
||||
ed25519_keypair_t kp;
|
||||
@ -1400,10 +1418,17 @@ build_service_desc_keys(const hs_service_t *service,
|
||||
memcpy(&kp.pubkey, &service->keys.identity_pk, sizeof(kp.pubkey));
|
||||
memcpy(&kp.seckey, &service->keys.identity_sk, sizeof(kp.seckey));
|
||||
/* Build blinded keypair for this time period. */
|
||||
hs_build_blinded_keypair(&kp, NULL, 0, time_period_num, &desc->blinded_kp);
|
||||
hs_build_blinded_keypair(&kp, NULL, 0, desc->time_period_num,
|
||||
&desc->blinded_kp);
|
||||
/* Let's not keep too much traces of our keys in memory. */
|
||||
memwipe(&kp, 0, sizeof(kp));
|
||||
|
||||
/* Compute the OPE cipher struct (it's tied to the current blinded key) */
|
||||
log_info(LD_GENERAL,
|
||||
"Getting OPE for TP#%u", (unsigned) desc->time_period_num);
|
||||
tor_assert_nonfatal(!desc->ope_cipher);
|
||||
desc->ope_cipher = generate_ope_cipher_for_desc(desc);
|
||||
|
||||
/* No need for extra strong, this is a temporary key only for this
|
||||
* descriptor. Nothing long term. */
|
||||
if (ed25519_keypair_generate(&desc->signing_kp, 0) < 0) {
|
||||
@ -1438,10 +1463,12 @@ build_service_descriptor(hs_service_t *service, time_t now,
|
||||
tor_assert(desc_out);
|
||||
|
||||
desc = service_descriptor_new();
|
||||
|
||||
/* Set current time period */
|
||||
desc->time_period_num = time_period_num;
|
||||
|
||||
/* Create the needed keys so we can setup the descriptor content. */
|
||||
if (build_service_desc_keys(service, desc, time_period_num) < 0) {
|
||||
if (build_service_desc_keys(service, desc) < 0) {
|
||||
goto err;
|
||||
}
|
||||
/* Setup plaintext descriptor content. */
|
||||
@ -2395,28 +2422,11 @@ set_descriptor_revision_counter(hs_service_descriptor_t *hs_desc, time_t now,
|
||||
seconds_since_start_of_srv = OPE_INPUT_MAX;
|
||||
}
|
||||
|
||||
/* Now we compute the actual revision counter value by encrypting the
|
||||
plaintext using an OPE construction: */
|
||||
|
||||
/* First, compute OPE key as: K = H("rev-counter-generation" | S) */
|
||||
uint8_t key[DIGEST256_LEN];
|
||||
{
|
||||
crypto_digest_t *digest = crypto_digest256_new(DIGEST_SHA3_256);
|
||||
const char ope_key_prefix[] = "rev-counter-generation";
|
||||
ed25519_secret_key_t *eph_privkey = &hs_desc->blinded_kp.seckey;
|
||||
crypto_digest_add_bytes(digest, ope_key_prefix, sizeof(ope_key_prefix));
|
||||
crypto_digest_add_bytes(digest, (char*)eph_privkey->seckey,
|
||||
sizeof(eph_privkey->seckey));
|
||||
crypto_digest_get_digest(digest, (char *)key, sizeof(key));
|
||||
crypto_digest_free(digest);
|
||||
}
|
||||
|
||||
{ /* Now encrypt the revision counter! */
|
||||
crypto_ope_t *ope = NULL;
|
||||
ope = crypto_ope_new(key);
|
||||
rev_counter = crypto_ope_encrypt(ope, (int) seconds_since_start_of_srv);
|
||||
crypto_ope_free(ope);
|
||||
}
|
||||
/* Now we compute the final revision counter value by encrypting the
|
||||
plaintext using our OPE cipher: */
|
||||
tor_assert(hs_desc->ope_cipher);
|
||||
rev_counter = crypto_ope_encrypt(hs_desc->ope_cipher,
|
||||
(int) seconds_since_start_of_srv);
|
||||
|
||||
/* The OPE module returns UINT64_MAX in case of errors. */
|
||||
tor_assert_nonfatal(rev_counter < UINT64_MAX);
|
||||
|
@ -131,6 +131,10 @@ typedef struct hs_service_descriptor_t {
|
||||
* from this list, this means we received new dirinfo and we need to
|
||||
* reupload our descriptor. */
|
||||
smartlist_t *previous_hsdirs;
|
||||
|
||||
/** The OPE cipher for encrypting revision counters for this descriptor.
|
||||
* Tied to the descriptor blinded key. */
|
||||
crypto_ope_t *ope_cipher;
|
||||
} hs_service_descriptor_t;
|
||||
|
||||
/* Service key material. */
|
||||
|
Loading…
Reference in New Issue
Block a user