Tor 0.4.9.0-alpha-dev
hs_pow.h
Go to the documentation of this file.
1/* Copyright (c) 2019-2020, The Tor Project, Inc. */
2/* See LICENSE for licensing information */
3
4/**
5 * \file hs_pow.h
6 * \brief Header file containing PoW denial of service defenses for the HS
7 * subsystem for all versions.
8 **/
9
10#ifndef TOR_HS_POW_H
11#define TOR_HS_POW_H
12
17
18/* Service updates the suggested effort every HS_UPDATE_PERIOD seconds.
19 * This parameter controls how often we can change hs descriptor data to
20 * update suggested_effort, but it also controls the frequency of our
21 * opportunities to increase or decrease effort. Lower values react to
22 * attacks faster, higher values may be more stable.
23 * Can this move to torrc? (Or the consensus?) The hs_cache timings are
24 * related, and they're also hardcoded.
25*/
26#define HS_UPDATE_PERIOD 300
27
28/** Length of random nonce (N) used in the PoW scheme. */
29#define HS_POW_NONCE_LEN 16
30/** Length of an E-quiX solution (S) in bytes. */
31#define HS_POW_EQX_SOL_LEN 16
32/** Length of blake2b hash result (R) used in the PoW scheme. */
33#define HS_POW_HASH_LEN 4
34/** Length of algorithm personalization string (P) used in the PoW scheme */
35#define HS_POW_PSTRING_LEN 16
36/** Algorithm personalization string (P) */
37#define HS_POW_PSTRING "Tor hs intro v1\0"
38/** Length of the blinded public ID for the onion service (ID) */
39#define HS_POW_ID_LEN 32
40/** Length of random seed used in the PoW scheme. */
41#define HS_POW_SEED_LEN 32
42/** Length of seed identification heading in the PoW scheme. */
43#define HS_POW_SEED_HEAD_LEN 4
44/** Length of an effort value */
45#define HS_POW_EFFORT_LEN sizeof(uint32_t)
46/** Offset of the nonce value within the challenge string */
47#define HS_POW_NONCE_OFFSET \
48 (HS_POW_PSTRING_LEN + HS_POW_ID_LEN + HS_POW_SEED_LEN)
49/** Length of a PoW challenge. Construction as per prop327 is:
50 * (P || ID || C || N || INT_32(E))
51 */
52#define HS_POW_CHALLENGE_LEN \
53 (HS_POW_PSTRING_LEN + HS_POW_ID_LEN + \
54 HS_POW_SEED_LEN + HS_POW_NONCE_LEN + HS_POW_EFFORT_LEN)
55
56/** Type of PoW in the descriptor. */
57typedef enum {
58 HS_POW_DESC_V1 = 1,
60
61/** Proof-of-Work parameters for DoS defense located in a descriptor. */
62typedef struct hs_pow_desc_params_t {
63 /** Type of PoW system being used. */
65
66 /** Random 32-byte seed used as input the the PoW hash function */
68
69 /** Specifies effort value that clients should aim for when contacting the
70 * service. */
72
73 /** Timestamp after which the above seed expires. */
76
77/** The inputs to the PoW solver, derived from the descriptor data and the
78 * client's per-connection effort choices. */
79typedef struct hs_pow_solver_inputs_t {
80 /** Seed value from a current descriptor */
82 /** Blinded public ID for the onion service this puzzle is bound to */
84 /** Effort chosen by the client. May be higher or lower than
85 * suggested_effort in the descriptor. */
86 uint32_t effort;
87 /** Configuration option, choice of hash implementation. AUTOBOOL. */
90
91/** State and parameters of PoW defenses, stored in the service state. */
92typedef struct hs_pow_service_state_t {
93 /* If PoW defenses are enabled this is a priority queue containing acceptable
94 * requests that are awaiting rendezvous circuits to built, where priority is
95 * based on the amount of effort that was exerted in the PoW. */
96 smartlist_t *rend_request_pqueue;
97
98 /* Low level mark for pqueue size. Below this length it's considered to be
99 * effectively empty when calculating effort adjustments. */
100 int pqueue_low_level;
101
102 /* High level mark for pqueue size. When the queue is this length we will
103 * trim it down to pqueue_high_level/2. */
104 int pqueue_high_level;
105
106 /* Event callback for dequeueing rend requests, paused when the queue is
107 * empty or rate limited. */
108 mainloop_event_t *pop_pqueue_ev;
109
110 /* Token bucket for rate limiting the priority queue */
111 token_bucket_ctr_t pqueue_bucket;
112
113 /* The current seed being used in the PoW defenses. */
114 uint8_t seed_current[HS_POW_SEED_LEN];
115
116 /* The previous seed that was used in the PoW defenses. We accept solutions
117 * for both the current and previous seed. */
118 uint8_t seed_previous[HS_POW_SEED_LEN];
119
120 /* The time at which the current seed expires and rotates for a new one. */
121 time_t expiration_time;
122
123 /* The suggested effort that clients should use in order for their request to
124 * be serviced in a timely manner. */
125 uint32_t suggested_effort;
126
127 /* The maximum effort of a request we've had to trim, this update period */
128 uint32_t max_trimmed_effort;
129
130 /* The following values are used when calculating and updating the suggested
131 * effort every HS_UPDATE_PERIOD seconds. */
132
133 /* Number of intro requests the service handled since last update. */
134 uint32_t rend_handled;
135 /* The next time at which to update the suggested effort. */
136 time_t next_effort_update;
137 /* Sum of effort of all valid requests received since the last update. */
138 uint64_t total_effort;
139
140 /* Did we have elements waiting in the queue during this period? */
141 bool had_queue;
142 /* Are we using pqueue_bucket to rate limit the pqueue? */
143 bool using_pqueue_bucket;
144
146
147/* Struct to store a solution to the PoW challenge. */
148typedef struct hs_pow_solution_t {
149 /* The nonce chosen to satisfy the PoW challenge's conditions. */
150 uint8_t nonce[HS_POW_NONCE_LEN];
151
152 /* The effort used in this solution. */
153 uint32_t effort;
154
155 /* A prefix of the seed used in this solution, so it can be identified. */
156 uint8_t seed_head[HS_POW_SEED_HEAD_LEN];
157
158 /* The Equi-X solution used in this PoW solution. */
161
162#ifdef HAVE_MODULE_POW
163#define have_module_pow() (1)
164
165/* API */
166int hs_pow_solve(const hs_pow_solver_inputs_t *pow_inputs,
167 hs_pow_solution_t *pow_solution_out);
168
169int hs_pow_verify(const ed25519_public_key_t *service_blinded_id,
170 const hs_pow_service_state_t *pow_state,
171 const hs_pow_solution_t *pow_solution);
172
173void hs_pow_remove_seed_from_cache(const uint8_t *seed_head);
175
176int hs_pow_queue_work(uint32_t intro_circ_identifier,
177 const uint8_t *rend_circ_cookie,
178 const hs_pow_solver_inputs_t *pow_inputs);
179
180#else /* !defined(HAVE_MODULE_POW) */
181#define have_module_pow() (0)
182
183static inline int
184hs_pow_solve(const hs_pow_solver_inputs_t *pow_inputs,
185 hs_pow_solution_t *pow_solution_out)
186{
187 (void)pow_inputs;
188 (void)pow_solution_out;
189 return -1;
190}
191
192static inline int
193hs_pow_verify(const ed25519_public_key_t *service_blinded_id,
194 const hs_pow_service_state_t *pow_state,
195 const hs_pow_solution_t *pow_solution)
196{
197 (void)service_blinded_id;
198 (void)pow_state;
199 (void)pow_solution;
200 return -1;
201}
202
203static inline void
204hs_pow_remove_seed_from_cache(const uint8_t *seed_head)
205{
206 (void)seed_head;
207}
208
209static inline void
211{
212 (void)state;
213}
214
215static inline int
216hs_pow_queue_work(uint32_t intro_circ_identifier,
217 const uint8_t *rend_circ_cookie,
218 const hs_pow_solver_inputs_t *pow_inputs)
219{
220 (void)intro_circ_identifier;
221 (void)rend_circ_cookie;
222 (void)pow_inputs;
223 return -1;
224}
225
226#endif /* defined(HAVE_MODULE_POW) */
227
228#endif /* !defined(TOR_HS_POW_H) */
Header for compat_libevent.c.
Header for crypto_ed25519.c.
int hs_pow_verify(const ed25519_public_key_t *service_blinded_id, const hs_pow_service_state_t *pow_state, const hs_pow_solution_t *pow_solution)
Definition: hs_pow.c:312
int hs_pow_solve(const hs_pow_solver_inputs_t *pow_inputs, hs_pow_solution_t *pow_solution_out)
Definition: hs_pow.c:197
int hs_pow_queue_work(uint32_t intro_circ_identifier, const uint8_t *rend_circ_cookie, const hs_pow_solver_inputs_t *pow_inputs)
Definition: hs_pow.c:543
void hs_pow_remove_seed_from_cache(const uint8_t *seed_head)
Definition: hs_pow.c:395
void hs_pow_free_service_state(hs_pow_service_state_t *state)
Definition: hs_pow.c:404
#define HS_POW_EQX_SOL_LEN
Definition: hs_pow.h:31
#define HS_POW_SEED_LEN
Definition: hs_pow.h:41
#define HS_POW_NONCE_LEN
Definition: hs_pow.h:29
#define HS_POW_SEED_HEAD_LEN
Definition: hs_pow.h:43
hs_pow_desc_type_t
Definition: hs_pow.h:57
Top-level declarations for the smartlist_t dynamic array type.
uint8_t seed[HS_POW_SEED_LEN]
Definition: hs_pow.h:67
uint32_t suggested_effort
Definition: hs_pow.h:71
time_t expiration_time
Definition: hs_pow.h:74
hs_pow_desc_type_t type
Definition: hs_pow.h:64
uint8_t seed[HS_POW_SEED_LEN]
Definition: hs_pow.h:81
ed25519_public_key_t service_blinded_id
Definition: hs_pow.h:83
int CompiledProofOfWorkHash
Definition: hs_pow.h:88
Headers for token_bucket.c.