[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [tor] 57/77: hs_pow: Don't require uint128_t



This is an automated email from the git hooks/post-receive script.

dgoulet pushed a commit to branch main
in repository tor.

commit 209a59face791159e167837214e22b6eaa3375b4
Author: Micah Elizabeth Scott <beth@xxxxxxxxxxxxxx>
AuthorDate: Tue Mar 14 16:16:27 2023 -0700

    hs_pow: Don't require uint128_t
    
    We were using a native uint128_t to represent the hs_pow nonce,
    but as the comments note it's more portable and more flexible to
    use a byte array. Indeed the uint128_t was a problem for 32-bit
    platforms. This swaps in a new implementation that uses multiple
    machine words to implement the nonce incrementation.
    
    Signed-off-by: Micah Elizabeth Scott <beth@xxxxxxxxxxxxxx>
---
 src/feature/hs/hs_pow.c     | 34 +++++++++++++++++++---------------
 src/feature/hs/hs_pow.h     |  6 +-----
 src/test/test_hs_pow_slow.c |  2 +-
 3 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/src/feature/hs/hs_pow.c b/src/feature/hs/hs_pow.c
index 1fc9de1268..e41f271fec 100644
--- a/src/feature/hs/hs_pow.c
+++ b/src/feature/hs/hs_pow.c
@@ -7,8 +7,6 @@
  * when a hidden service is defending against DoS attacks.
  **/
 
-typedef unsigned __int128 uint128_t;
-
 #include <stdio.h>
 
 #include "ext/ht.h"
@@ -20,6 +18,7 @@ typedef unsigned __int128 uint128_t;
 #include "feature/hs/hs_client.h"
 #include "feature/hs/hs_pow.h"
 #include "lib/crypt_ops/crypto_rand.h"
+#include "lib/cc/ctassert.h"
 #include "core/mainloop/cpuworker.h"
 #include "lib/evloop/workqueue.h"
 
@@ -27,7 +26,7 @@ typedef unsigned __int128 uint128_t;
 /** Cache entry for (nonce, seed) replay protection. */
 typedef struct nonce_cache_entry_t {
   HT_ENTRY(nonce_cache_entry_t) node;
-  uint128_t nonce;
+  uint8_t nonce[HS_POW_NONCE_LEN];
   uint32_t seed_head;
 } nonce_cache_entry_t;
 
@@ -36,7 +35,7 @@ static inline int
 nonce_cache_entries_eq_(const struct nonce_cache_entry_t *entry1,
                         const struct nonce_cache_entry_t *entry2)
 {
-  return entry1->nonce == entry2->nonce &&
+  return fast_memeq(entry1->nonce, entry2->nonce, HS_POW_NONCE_LEN) &&
          entry1->seed_head == entry2->seed_head;
 }
 
@@ -44,7 +43,7 @@ nonce_cache_entries_eq_(const struct nonce_cache_entry_t *entry1,
 static inline unsigned
 nonce_cache_entry_hash_(const struct nonce_cache_entry_t *ent)
 {
-  return (unsigned)siphash24g(&ent->nonce, HS_POW_NONCE_LEN) + ent->seed_head;
+  return (unsigned)siphash24g(ent->nonce, HS_POW_NONCE_LEN) + ent->seed_head;
 }
 
 static HT_HEAD(nonce_cache_table_ht, nonce_cache_entry_t)
@@ -69,9 +68,14 @@ nonce_cache_entry_has_seed(nonce_cache_entry_t *ent, void *data)
 /** Helper: Increment a given nonce and set it in the challenge at the right
  * offset. Use by the solve function. */
 static inline void
-increment_and_set_nonce(uint128_t *nonce, uint8_t *challenge)
+increment_and_set_nonce(uint8_t *nonce, uint8_t *challenge)
 {
-  (*nonce)++;
+  for (unsigned i = 0; i < HS_POW_NONCE_LEN; i++) {
+    uint8_t prev = nonce[i];
+    if (++nonce[i] > prev) {
+      break;
+    }
+  }
   memcpy(challenge + HS_POW_SEED_LEN, nonce, HS_POW_NONCE_LEN);
 }
 
@@ -95,7 +99,7 @@ build_equix_ctx(equix_ctx_flags flags)
 /* Helper: Build EquiX challenge (C || N || INT_32(E)) and return a newly
  * allocated buffer containing it. */
 static uint8_t *
-build_equix_challenge(const uint8_t *seed, const uint128_t nonce,
+build_equix_challenge(const uint8_t *seed, const uint8_t *nonce,
                       const uint32_t effort)
 {
   /* Build EquiX challenge (C || N || INT_32(E)). */
@@ -104,7 +108,7 @@ build_equix_challenge(const uint8_t *seed, const uint128_t nonce,
 
   memcpy(challenge, seed, HS_POW_SEED_LEN);
   offset += HS_POW_SEED_LEN;
-  memcpy(challenge + offset, &nonce, HS_POW_NONCE_LEN);
+  memcpy(challenge + offset, nonce, HS_POW_NONCE_LEN);
   offset += HS_POW_NONCE_LEN;
   set_uint32(challenge + offset, tor_htonl(effort));
   offset += HS_POW_EFFORT_LEN;
@@ -146,7 +150,7 @@ hs_pow_solve(const hs_pow_desc_params_t *pow_params,
              hs_pow_solution_t *pow_solution_out)
 {
   int ret = -1;
-  uint128_t nonce;
+  uint8_t nonce[HS_POW_NONCE_LEN];
   uint8_t *challenge = NULL;
   equix_ctx *ctx = NULL;
 
@@ -157,7 +161,7 @@ hs_pow_solve(const hs_pow_desc_params_t *pow_params,
   uint32_t effort = pow_params->suggested_effort;
 
   /* Generate a random nonce N. */
-  crypto_rand((char *)&nonce, sizeof(uint128_t));
+  crypto_rand((char *)nonce, sizeof nonce);
 
   /* Build EquiX challenge (C || N || INT_32(E)). */
   challenge = build_equix_challenge(pow_params->seed, nonce, effort);
@@ -178,7 +182,7 @@ hs_pow_solve(const hs_pow_desc_params_t *pow_params,
       /* Check an Equi-X solution against the effort threshold */
       if (validate_equix_challenge(challenge, sol, effort)) {
         /* Store the nonce N. */
-        pow_solution_out->nonce = nonce;
+        memcpy(pow_solution_out->nonce, nonce, HS_POW_NONCE_LEN);
         /* Store the effort E. */
         pow_solution_out->effort = effort;
         /* We only store the first 4 bytes of the seed C. */
@@ -195,7 +199,7 @@ hs_pow_solve(const hs_pow_desc_params_t *pow_params,
 
     /* No solutions for this nonce and/or none that passed the effort
      * threshold, increment and try again. */
-    increment_and_set_nonce(&nonce, challenge);
+    increment_and_set_nonce(nonce, challenge);
   }
 
  end:
@@ -243,7 +247,7 @@ hs_pow_verify(const hs_pow_service_state_t *pow_state,
   }
 
   /* Fail if N = POW_NONCE is present in the replay cache. */
-  search.nonce = pow_solution->nonce;
+  memcpy(search.nonce, pow_solution->nonce, HS_POW_NONCE_LEN);
   search.seed_head = pow_solution->seed_head;
   entry = HT_FIND(nonce_cache_table_ht, &nonce_cache_table, &search);
   if (entry) {
@@ -279,7 +283,7 @@ hs_pow_verify(const hs_pow_service_state_t *pow_state,
 
   /* Add the (nonce, seed) tuple to the replay cache. */
   entry = tor_malloc_zero(sizeof(nonce_cache_entry_t));
-  entry->nonce = pow_solution->nonce;
+  memcpy(entry->nonce, pow_solution->nonce, HS_POW_NONCE_LEN);
   entry->seed_head = pow_solution->seed_head;
   HT_INSERT(nonce_cache_table_ht, &nonce_cache_table, entry);
 
diff --git a/src/feature/hs/hs_pow.h b/src/feature/hs/hs_pow.h
index b27bd7441c..6eb03ef64e 100644
--- a/src/feature/hs/hs_pow.h
+++ b/src/feature/hs/hs_pow.h
@@ -10,8 +10,6 @@
 #ifndef TOR_HS_POW_H
 #define TOR_HS_POW_H
 
-typedef unsigned __int128 uint128_t;
-
 #include "ext/equix/include/equix.h"
 
 #include "lib/evloop/compat_libevent.h"
@@ -112,10 +110,8 @@ typedef struct hs_pow_service_state_t {
 
 /* Struct to store a solution to the PoW challenge. */
 typedef struct hs_pow_solution_t {
-  /** HRPR TODO are we best off storing this as a byte array, as trunnel doesnt
-   * support uint128 (?) */
   /* The 16 byte nonce used in the solution. */
-  uint128_t nonce;
+  uint8_t nonce[HS_POW_NONCE_LEN];
 
   /* The effort used in the solution. */
   uint32_t effort;
diff --git a/src/test/test_hs_pow_slow.c b/src/test/test_hs_pow_slow.c
index 8ccbf8025c..716501dffd 100644
--- a/src/test/test_hs_pow_slow.c
+++ b/src/test/test_hs_pow_slow.c
@@ -48,7 +48,7 @@ testing_one_hs_pow_solution(const hs_pow_solution_t *ref_solution,
           expected = 0;
         }
       } else if (variant & 1) {
-        sol_buffer.nonce += variant;
+        sol_buffer.nonce[variant % HS_POW_NONCE_LEN]++;
       } else {
         sol_buffer.equix_solution.idx[variant % EQUIX_NUM_IDX]++;
       }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits