[tor-commits] [tor/master] Compute OPE cipher structure only when needed.

nickm at torproject.org nickm at torproject.org
Tue Jul 17 20:19:40 UTC 2018


commit d8b71609cb9c2ce15b6a26d11b2bcdedf15b915e
Author: George Kadianakis <desnacked at riseup.net>
Date:   Tue Jul 17 12:03:18 2018 -0400

    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).
---
 src/or/hs_service.c | 62 +++++++++++++++++++++++++++++++----------------------
 src/or/hs_service.h |  4 ++++
 2 files changed, 40 insertions(+), 26 deletions(-)

diff --git a/src/or/hs_service.c b/src/or/hs_service.c
index dd91e97bb..d6416ebcd 100644
--- a/src/or/hs_service.c
+++ b/src/or/hs_service.c
@@ -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);
diff --git a/src/or/hs_service.h b/src/or/hs_service.h
index a5f49ffef..e1f125d76 100644
--- a/src/or/hs_service.h
+++ b/src/or/hs_service.h
@@ -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. */





More information about the tor-commits mailing list