tor  0.4.2.0-alpha-dev
onion_crypto.c
Go to the documentation of this file.
1 /* Copyright (c) 2001 Matej Pfajfar.
2  * Copyright (c) 2001-2004, Roger Dingledine.
3  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4  * Copyright (c) 2007-2019, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
6 
33 #include "core/or/or.h"
34 #include "core/or/circuitbuild.h"
36 #include "core/crypto/onion_fast.h"
37 #include "core/crypto/onion_ntor.h"
38 #include "core/crypto/onion_tap.h"
39 #include "feature/relay/router.h"
42 
43 #include "core/or/crypt_path_st.h"
44 #include "core/or/extend_info_st.h"
45 
52 {
53  server_onion_keys_t *keys = tor_malloc_zero(sizeof(server_onion_keys_t));
54  memcpy(keys->my_identity, router_get_my_id_digest(), DIGEST_LEN);
55  dup_onion_keys(&keys->onion_key, &keys->last_onion_key);
56  keys->curve25519_key_map = construct_ntor_key_map();
57  keys->junk_keypair = tor_malloc_zero(sizeof(curve25519_keypair_t));
58  curve25519_keypair_generate(keys->junk_keypair, 0);
59  return keys;
60 }
62 void
64 {
65  if (! keys)
66  return;
67 
68  crypto_pk_free(keys->onion_key);
69  crypto_pk_free(keys->last_onion_key);
70  ntor_key_map_free(keys->curve25519_key_map);
71  tor_free(keys->junk_keypair);
72  memwipe(keys, 0, sizeof(server_onion_keys_t));
73  tor_free(keys);
74 }
75 
78 void
80 {
81  switch (state->tag) {
82  case ONION_HANDSHAKE_TYPE_TAP:
83  crypto_dh_free(state->u.tap);
84  state->u.tap = NULL;
85  break;
86  case ONION_HANDSHAKE_TYPE_FAST:
87  fast_handshake_state_free(state->u.fast);
88  state->u.fast = NULL;
89  break;
90  case ONION_HANDSHAKE_TYPE_NTOR:
91  ntor_handshake_state_free(state->u.ntor);
92  state->u.ntor = NULL;
93  break;
94  default:
95  /* LCOV_EXCL_START
96  * This state should not even exist. */
97  log_warn(LD_BUG, "called with unknown handshake state type %d",
98  (int)state->tag);
100  /* LCOV_EXCL_STOP */
101  }
102 }
103 
109 int
111  const extend_info_t *node,
112  onion_handshake_state_t *state_out,
113  uint8_t *onion_skin_out)
114 {
115  int r = -1;
116 
117  switch (type) {
118  case ONION_HANDSHAKE_TYPE_TAP:
119  if (!node->onion_key)
120  return -1;
121 
123  &state_out->u.tap,
124  (char*)onion_skin_out) < 0)
125  return -1;
126 
127  r = TAP_ONIONSKIN_CHALLENGE_LEN;
128  break;
129  case ONION_HANDSHAKE_TYPE_FAST:
130  if (fast_onionskin_create(&state_out->u.fast, onion_skin_out) < 0)
131  return -1;
132 
133  r = CREATE_FAST_LEN;
134  break;
135  case ONION_HANDSHAKE_TYPE_NTOR:
136  if (!extend_info_supports_ntor(node))
137  return -1;
138  if (onion_skin_ntor_create((const uint8_t*)node->identity_digest,
139  &node->curve25519_onion_key,
140  &state_out->u.ntor,
141  onion_skin_out) < 0)
142  return -1;
143 
144  r = NTOR_ONIONSKIN_LEN;
145  break;
146  default:
147  /* LCOV_EXCL_START
148  * We should never try to create an impossible handshake type. */
149  log_warn(LD_BUG, "called with unknown handshake state type %d", type);
151  r = -1;
152  /* LCOV_EXCL_STOP */
153  }
154 
155  if (r > 0)
156  state_out->tag = (uint16_t) type;
157 
158  return r;
159 }
160 
161 /* This is the maximum value for keys_out_len passed to
162  * onion_skin_server_handshake, plus 16. We can make it bigger if needed:
163  * It just defines how many bytes to stack-allocate. */
164 #define MAX_KEYS_TMP_LEN 128
165 
173 int
175  const uint8_t *onion_skin, size_t onionskin_len,
176  const server_onion_keys_t *keys,
177  uint8_t *reply_out,
178  uint8_t *keys_out, size_t keys_out_len,
179  uint8_t *rend_nonce_out)
180 {
181  int r = -1;
182 
183  switch (type) {
184  case ONION_HANDSHAKE_TYPE_TAP:
185  if (onionskin_len != TAP_ONIONSKIN_CHALLENGE_LEN)
186  return -1;
187  if (onion_skin_TAP_server_handshake((const char*)onion_skin,
188  keys->onion_key, keys->last_onion_key,
189  (char*)reply_out,
190  (char*)keys_out, keys_out_len)<0)
191  return -1;
192  r = TAP_ONIONSKIN_REPLY_LEN;
193  memcpy(rend_nonce_out, reply_out+DH1024_KEY_LEN, DIGEST_LEN);
194  break;
195  case ONION_HANDSHAKE_TYPE_FAST:
196  if (onionskin_len != CREATE_FAST_LEN)
197  return -1;
198  if (fast_server_handshake(onion_skin, reply_out, keys_out, keys_out_len)<0)
199  return -1;
200  r = CREATED_FAST_LEN;
201  memcpy(rend_nonce_out, reply_out+DIGEST_LEN, DIGEST_LEN);
202  break;
203  case ONION_HANDSHAKE_TYPE_NTOR:
204  if (onionskin_len < NTOR_ONIONSKIN_LEN)
205  return -1;
206  {
207  size_t keys_tmp_len = keys_out_len + DIGEST_LEN;
208  tor_assert(keys_tmp_len <= MAX_KEYS_TMP_LEN);
209  uint8_t keys_tmp[MAX_KEYS_TMP_LEN];
210 
212  onion_skin, keys->curve25519_key_map,
213  keys->junk_keypair,
214  keys->my_identity,
215  reply_out, keys_tmp, keys_tmp_len)<0) {
216  /* no need to memwipe here, since the output will never be used */
217  return -1;
218  }
219 
220  memcpy(keys_out, keys_tmp, keys_out_len);
221  memcpy(rend_nonce_out, keys_tmp+keys_out_len, DIGEST_LEN);
222  memwipe(keys_tmp, 0, sizeof(keys_tmp));
223  r = NTOR_REPLY_LEN;
224  }
225  break;
226  default:
227  /* LCOV_EXCL_START
228  * We should have rejected this far before this point */
229  log_warn(LD_BUG, "called with unknown handshake state type %d", type);
231  return -1;
232  /* LCOV_EXCL_STOP */
233  }
234 
235  return r;
236 }
237 
246 int
248  const onion_handshake_state_t *handshake_state,
249  const uint8_t *reply, size_t reply_len,
250  uint8_t *keys_out, size_t keys_out_len,
251  uint8_t *rend_authenticator_out,
252  const char **msg_out)
253 {
254  if (handshake_state->tag != type)
255  return -1;
256 
257  switch (type) {
258  case ONION_HANDSHAKE_TYPE_TAP:
259  if (reply_len != TAP_ONIONSKIN_REPLY_LEN) {
260  if (msg_out)
261  *msg_out = "TAP reply was not of the correct length.";
262  return -1;
263  }
264  if (onion_skin_TAP_client_handshake(handshake_state->u.tap,
265  (const char*)reply,
266  (char *)keys_out, keys_out_len,
267  msg_out) < 0)
268  return -1;
269 
270  memcpy(rend_authenticator_out, reply+DH1024_KEY_LEN, DIGEST_LEN);
271 
272  return 0;
273  case ONION_HANDSHAKE_TYPE_FAST:
274  if (reply_len != CREATED_FAST_LEN) {
275  if (msg_out)
276  *msg_out = "TAP reply was not of the correct length.";
277  return -1;
278  }
279  if (fast_client_handshake(handshake_state->u.fast, reply,
280  keys_out, keys_out_len, msg_out) < 0)
281  return -1;
282 
283  memcpy(rend_authenticator_out, reply+DIGEST_LEN, DIGEST_LEN);
284  return 0;
285  case ONION_HANDSHAKE_TYPE_NTOR:
286  if (reply_len < NTOR_REPLY_LEN) {
287  if (msg_out)
288  *msg_out = "ntor reply was not of the correct length.";
289  return -1;
290  }
291  {
292  size_t keys_tmp_len = keys_out_len + DIGEST_LEN;
293  uint8_t *keys_tmp = tor_malloc(keys_tmp_len);
294  if (onion_skin_ntor_client_handshake(handshake_state->u.ntor,
295  reply,
296  keys_tmp, keys_tmp_len, msg_out) < 0) {
297  tor_free(keys_tmp);
298  return -1;
299  }
300  memcpy(keys_out, keys_tmp, keys_out_len);
301  memcpy(rend_authenticator_out, keys_tmp + keys_out_len, DIGEST_LEN);
302  memwipe(keys_tmp, 0, keys_tmp_len);
303  tor_free(keys_tmp);
304  }
305  return 0;
306  default:
307  log_warn(LD_BUG, "called with unknown handshake state type %d", type);
309  return -1;
310  }
311 }
Headers for crypto_dh.c.
int fast_onionskin_create(fast_handshake_state_t **handshake_state_out, uint8_t *handshake_out)
Definition: onion_fast.c:49
int fast_server_handshake(const uint8_t *key_in, uint8_t *handshake_reply_out, uint8_t *key_out, size_t key_out_len)
Definition: onion_fast.c:67
di_digest256_map_t * construct_ntor_key_map(void)
Definition: router.c:283
void server_onion_keys_free_(server_onion_keys_t *keys)
Definition: onion_crypto.c:63
int onion_skin_ntor_create(const uint8_t *router_id, const curve25519_public_key_t *router_key, ntor_handshake_state_t **handshake_state_out, uint8_t *onion_skin_out)
Definition: onion_ntor.c:93
Header file for onion_tap.c.
server_onion_keys_t * server_onion_keys_new(void)
Definition: onion_crypto.c:51
int onion_skin_create(int type, const extend_info_t *node, onion_handshake_state_t *state_out, uint8_t *onion_skin_out)
Definition: onion_crypto.c:110
int onion_skin_ntor_client_handshake(const ntor_handshake_state_t *handshake_state, const uint8_t *handshake_reply, uint8_t *key_out, size_t key_out_len, const char **msg_out)
Definition: onion_ntor.c:254
int onion_skin_TAP_client_handshake(crypto_dh_t *handshake_state, const char *handshake_reply, char *key_out, size_t key_out_len, const char **msg_out)
Definition: onion_tap.c:207
#define tor_free(p)
Definition: malloc.h:52
#define tor_fragile_assert()
Definition: util_bug.h:241
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:57
const uint8_t * router_get_my_id_digest(void)
Definition: router.c:1600
int onion_skin_TAP_server_handshake(const char *onion_skin, crypto_pk_t *private_key, crypto_pk_t *prev_private_key, char *handshake_reply_out, char *key_out, size_t key_out_len)
Definition: onion_tap.c:105
crypto_pk_t * onion_key
Common functions for cryptographic routines.
tor_assert(buffer)
#define DIGEST_LEN
Definition: digest_sizes.h:20
void dup_onion_keys(crypto_pk_t **key, crypto_pk_t **last)
Definition: router.c:211
Master header file for Tor-specific functionality.
Header file for circuitbuild.c.
Header file for onion_fast.c.
int fast_client_handshake(const fast_handshake_state_t *handshake_state, const uint8_t *handshake_reply_out, uint8_t *key_out, size_t key_out_len, const char **msg_out)
Definition: onion_fast.c:109
#define DH1024_KEY_LEN
Definition: dh_sizes.h:20
int onion_skin_TAP_create(crypto_pk_t *dest_router_key, crypto_dh_t **handshake_state_out, char *onion_skin_out)
Definition: onion_tap.c:53
char identity_digest[DIGEST_LEN]
Header file for router.c.
int curve25519_keypair_generate(curve25519_keypair_t *keypair_out, int extra_strong)
int onion_skin_server_handshake(int type, const uint8_t *onion_skin, size_t onionskin_len, const server_onion_keys_t *keys, uint8_t *reply_out, uint8_t *keys_out, size_t keys_out_len, uint8_t *rend_nonce_out)
Definition: onion_crypto.c:174
void onion_handshake_state_release(onion_handshake_state_t *state)
Definition: onion_crypto.c:79
int onion_skin_ntor_server_handshake(const uint8_t *onion_skin, const di_digest256_map_t *private_keys, const curve25519_keypair_t *junk_keys, const uint8_t *my_node_id, uint8_t *handshake_reply_out, uint8_t *key_out, size_t key_out_len)
Definition: onion_ntor.c:149
int onion_skin_client_handshake(int type, const onion_handshake_state_t *handshake_state, const uint8_t *reply, size_t reply_len, uint8_t *keys_out, size_t keys_out_len, uint8_t *rend_authenticator_out, const char **msg_out)
Definition: onion_crypto.c:247
#define LD_BUG
Definition: log.h:84
Header file for onion_crypto.c.