Line data Source code
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-2021, The Tor Project, Inc. */
5 : /* See LICENSE for licensing information */
6 :
7 : /**
8 : * \file onion_fast.c
9 : * \brief Functions implement the CREATE_FAST circuit handshake.
10 : *
11 : * The "CREATE_FAST" handshake is an unauthenticated, non-forward-secure
12 : * key derivation mechanism based on SHA1. We used to use it for the
13 : * first hop of each circuit, since the TAP handshake provided no
14 : * additional security beyond the security already provided by the TLS
15 : * handshake [*].
16 : *
17 : * When we switched to ntor, we deprecated CREATE_FAST, since ntor is
18 : * stronger than our TLS handshake was, and fast enough to not be worrisome.
19 : *
20 : * This handshake, like the other circuit-extension handshakes, is
21 : * invoked from onion.c.
22 : *
23 : * [*]Actually, it's possible that TAP _was_ a little better than TLS with
24 : * RSA1024 certificates and EDH1024 for forward secrecy, if you
25 : * hypothesize an adversary who can compute discrete logarithms on a
26 : * small number of targeted DH1024 fields, but who can't break all that
27 : * many RSA1024 keys.
28 : **/
29 :
30 : #include "core/or/or.h"
31 : #include "core/crypto/onion_fast.h"
32 : #include "lib/crypt_ops/crypto_hkdf.h"
33 : #include "lib/crypt_ops/crypto_rand.h"
34 : #include "lib/crypt_ops/crypto_util.h"
35 :
36 : /** Release all state held in <b>victim</b>. */
37 : void
38 1 : fast_handshake_state_free_(fast_handshake_state_t *victim)
39 : {
40 1 : if (! victim)
41 : return;
42 1 : memwipe(victim, 0, sizeof(fast_handshake_state_t));
43 1 : tor_free(victim);
44 : }
45 :
46 : /** Create the state needed to perform a CREATE_FAST handshake. Return 0
47 : * on success, -1 on failure. */
48 : int
49 3 : fast_onionskin_create(fast_handshake_state_t **handshake_state_out,
50 : uint8_t *handshake_out)
51 : {
52 3 : fast_handshake_state_t *s;
53 3 : *handshake_state_out = s = tor_malloc(sizeof(fast_handshake_state_t));
54 3 : crypto_rand((char*)s->state, sizeof(s->state));
55 3 : memcpy(handshake_out, s->state, DIGEST_LEN);
56 3 : return 0;
57 : }
58 :
59 : /** Implement the server side of the CREATE_FAST abbreviated handshake. The
60 : * client has provided DIGEST_LEN key bytes in <b>key_in</b> ("x"). We
61 : * generate a reply of DIGEST_LEN*2 bytes in <b>key_out</b>, consisting of a
62 : * new random "y", followed by H(x|y) to check for correctness. We set
63 : * <b>key_out_len</b> bytes of key material in <b>key_out</b>.
64 : * Return 0 on success, <0 on failure.
65 : **/
66 : int
67 1 : fast_server_handshake(const uint8_t *key_in, /* DIGEST_LEN bytes */
68 : uint8_t *handshake_reply_out, /* DIGEST_LEN*2 bytes */
69 : uint8_t *key_out,
70 : size_t key_out_len)
71 : {
72 1 : uint8_t tmp[DIGEST_LEN+DIGEST_LEN];
73 1 : uint8_t *out = NULL;
74 1 : size_t out_len;
75 1 : int r = -1;
76 :
77 1 : crypto_rand((char*)handshake_reply_out, DIGEST_LEN);
78 :
79 1 : memcpy(tmp, key_in, DIGEST_LEN);
80 1 : memcpy(tmp+DIGEST_LEN, handshake_reply_out, DIGEST_LEN);
81 1 : out_len = key_out_len+DIGEST_LEN;
82 1 : out = tor_malloc(out_len);
83 1 : if (BUG(crypto_expand_key_material_TAP(tmp, sizeof(tmp), out, out_len))) {
84 : goto done; // LCOV_EXCL_LINE
85 : }
86 1 : memcpy(handshake_reply_out+DIGEST_LEN, out, DIGEST_LEN);
87 1 : memcpy(key_out, out+DIGEST_LEN, key_out_len);
88 1 : r = 0;
89 1 : done:
90 1 : memwipe(tmp, 0, sizeof(tmp));
91 1 : memwipe(out, 0, out_len);
92 1 : tor_free(out);
93 1 : return r;
94 : }
95 :
96 : /** Implement the second half of the client side of the CREATE_FAST handshake.
97 : * We sent the server <b>handshake_state</b> ("x") already, and the server
98 : * told us <b>handshake_reply_out</b> (y|H(x|y)). Make sure that the hash is
99 : * correct, and generate key material in <b>key_out</b>. Return 0 on success,
100 : * true on failure.
101 : *
102 : * NOTE: The "CREATE_FAST" handshake path is distinguishable from regular
103 : * "onionskin" handshakes, and is not secure if an adversary can see or modify
104 : * the messages. Therefore, it should only be used by clients, and only as
105 : * the first hop of a circuit (since the first hop is already authenticated
106 : * and protected by TLS).
107 : */
108 : int
109 2 : fast_client_handshake(const fast_handshake_state_t *handshake_state,
110 : const uint8_t *handshake_reply_out,/*DIGEST_LEN*2 bytes*/
111 : uint8_t *key_out,
112 : size_t key_out_len,
113 : const char **msg_out)
114 : {
115 2 : uint8_t tmp[DIGEST_LEN+DIGEST_LEN];
116 2 : uint8_t *out;
117 2 : size_t out_len;
118 2 : int r = -1;
119 :
120 2 : memcpy(tmp, handshake_state->state, DIGEST_LEN);
121 2 : memcpy(tmp+DIGEST_LEN, handshake_reply_out, DIGEST_LEN);
122 2 : out_len = key_out_len+DIGEST_LEN;
123 2 : out = tor_malloc(out_len);
124 2 : if (BUG(crypto_expand_key_material_TAP(tmp, sizeof(tmp), out, out_len))) {
125 : /* LCOV_EXCL_START */
126 : if (msg_out)
127 : *msg_out = "Failed to expand key material";
128 : goto done;
129 : /* LCOV_EXCL_STOP */
130 : }
131 2 : if (tor_memneq(out, handshake_reply_out+DIGEST_LEN, DIGEST_LEN)) {
132 : /* H(K) does *not* match. Something fishy. */
133 1 : if (msg_out)
134 1 : *msg_out = "Digest DOES NOT MATCH on fast handshake. Bug or attack.";
135 1 : goto done;
136 : }
137 1 : memcpy(key_out, out+DIGEST_LEN, key_out_len);
138 1 : r = 0;
139 2 : done:
140 2 : memwipe(tmp, 0, sizeof(tmp));
141 2 : memwipe(out, 0, out_len);
142 2 : tor_free(out);
143 2 : return r;
144 : }
|