1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
7 #define ONION_NTOR_V3_PRIVATE
8 #include "core/or/or.h"
10 #include "lib/crypt_ops/crypto_curve25519.h"
11 #include "lib/crypt_ops/crypto_ed25519.h"
12 #include "core/crypto/onion_ntor_v3.h"
13 #include "core/crypto/onion_crypto.h"
14 #include "core/or/extend_info_st.h"
15 #include "core/or/crypt_path_st.h"
16 #define TOR_CONGESTION_CONTROL_PRIVATE
17 #define TOR_CONGESTION_CONTROL_COMMON_PRIVATE
18 #include "core/or/congestion_control_st.h"
19 #include "core/or/congestion_control_common.h"
20 #include "app/config/config.h"
22 #define unhex(arry, s) \
23 { tt_int_op(sizeof(arry), OP_EQ, \
24 base16_decode((char*)arry, sizeof(arry), s, strlen(s))); \
28 test_ntor3_testvecs(void *arg
)
31 char *mem_op_hex_tmp
= NULL
; // temp val to make test_memeq_hex work.
33 ntor3_server_handshake_state_t
*relay_state
= NULL
;
34 uint8_t *onion_skin
= NULL
;
35 size_t onion_skin_len
;
36 ntor3_handshake_state_t
*client_state
= NULL
;
37 uint8_t *cm
= NULL
, *sm
= NULL
;
38 size_t cm_len
, sm_len
;
39 di_digest256_map_t
*private_keys
= NULL
;
40 uint8_t *server_handshake
= NULL
;
41 size_t server_handshake_len
;
43 // Test vectors from python implementation, confirmed with rust
45 curve25519_keypair_t relay_keypair_b
;
46 curve25519_keypair_t client_keypair_x
;
47 curve25519_keypair_t relay_keypair_y
;
48 ed25519_public_key_t relay_id
;
50 unhex(relay_keypair_b
.seckey
.secret_key
,
51 "4051daa5921cfa2a1c27b08451324919538e79e788a81b38cbed097a5dff454a");
52 unhex(relay_keypair_b
.pubkey
.public_key
,
53 "f8307a2bc1870b00b828bb74dbb8fd88e632a6375ab3bcd1ae706aaa8b6cdd1d");
54 unhex(relay_id
.pubkey
,
55 "9fad2af287ef942632833d21f946c6260c33fae6172b60006e86e4a6911753a2");
56 unhex(client_keypair_x
.seckey
.secret_key
,
57 "b825a3719147bcbe5fb1d0b0fcb9c09e51948048e2e3283d2ab7b45b5ef38b49");
58 unhex(client_keypair_x
.pubkey
.public_key
,
59 "252fe9ae91264c91d4ecb8501f79d0387e34ad8ca0f7c995184f7d11d5da4f46");
60 unhex(relay_keypair_y
.seckey
.secret_key
,
61 "4865a5b7689dafd978f529291c7171bc159be076b92186405d13220b80e2a053");
62 unhex(relay_keypair_y
.pubkey
.public_key
,
63 "4bf4814326fdab45ad5184f5518bd7fae25dc59374062698201a50a22954246d");
65 uint8_t client_message
[11];
66 uint8_t verification
[5];
67 unhex(client_message
, "68656c6c6f20776f726c64");
68 unhex(verification
, "78797a7a79");
70 // ========= Client handshake 1.
72 onion_skin_ntor3_create_nokeygen(
75 &relay_keypair_b
.pubkey
,
79 sizeof(client_message
),
84 const char expect_client_handshake
[] = "9fad2af287ef942632833d21f946c6260c"
85 "33fae6172b60006e86e4a6911753a2f8307a2bc1870b00b828bb74dbb8fd88e632a6375"
86 "ab3bcd1ae706aaa8b6cdd1d252fe9ae91264c91d4ecb8501f79d0387e34ad8ca0f7c995"
87 "184f7d11d5da4f463bebd9151fd3b47c180abc9e044d53565f04d82bbb3bebed3d06cea"
88 "65db8be9c72b68cd461942088502f67";
90 tt_int_op(onion_skin_len
, OP_EQ
, strlen(expect_client_handshake
)/2);
91 test_memeq_hex(onion_skin
, expect_client_handshake
);
93 // ========= Relay handshake.
95 dimap_add_entry(&private_keys
,
96 relay_keypair_b
.pubkey
.public_key
,
99 int r
= onion_skin_ntor3_server_handshake_part1(
106 sizeof(verification
),
110 tt_int_op(r
, OP_EQ
, 0);
111 tt_int_op(cm_len
, OP_EQ
, sizeof(client_message
));
112 tt_mem_op(cm
, OP_EQ
, client_message
, cm_len
);
114 uint8_t server_message
[10];
115 unhex(server_message
, "486f6c61204d756e646f");
117 uint8_t server_keys
[256];
118 onion_skin_ntor3_server_handshake_part2_nokeygen(
122 sizeof(verification
),
124 sizeof(server_message
),
126 &server_handshake_len
,
128 sizeof(server_keys
));
130 const char expect_server_handshake
[] = "4bf4814326fdab45ad5184f5518bd7fae25"
131 "dc59374062698201a50a22954246d2fc5f8773ca824542bc6cf6f57c7c29bbf4e5476461"
132 "ab130c5b18ab0a91276651202c3e1e87c0d32054c";
133 tt_int_op(server_handshake_len
, OP_EQ
, strlen(expect_server_handshake
)/2);
134 test_memeq_hex(server_handshake
, expect_server_handshake
);
136 uint8_t expect_keys
[256];
137 unhex(expect_keys
, "9c19b631fd94ed86a817e01f6c80b0743a43f5faebd39cfaa8b00f"
138 "a8bcc65c3bfeaa403d91acbd68a821bf6ee8504602b094a254392a07737d5662768"
139 "c7a9fb1b2814bb34780eaee6e867c773e28c212ead563e98a1cd5d5b4576f5ee61c"
140 "59bde025ff2851bb19b721421694f263818e3531e43a9e4e3e2c661e2ad547d8984"
141 "caa28ebecd3e4525452299be26b9185a20a90ce1eac20a91f2832d731b54502b097"
142 "49b5a2a2949292f8cfcbeffb790c7790ed935a9d251e7e336148ea83b063a5618fc"
143 "ff674a44581585fd22077ca0e52c59a24347a38d1a1ceebddbf238541f226b8f88d"
144 "0fb9c07a1bcd2ea764bbbb5dacdaf5312a14c0b9e4f06309b0333b4a");
145 tt_mem_op(server_keys
, OP_EQ
, expect_keys
, 256);
147 // ===== Client handshake 2
149 uint8_t client_keys
[256];
150 r
= onion_ntor3_client_handshake(
153 server_handshake_len
,
155 sizeof(verification
),
161 tt_int_op(r
, OP_EQ
, 0);
162 tt_int_op(sm_len
, OP_EQ
, sizeof(server_message
));
163 tt_mem_op(sm
, OP_EQ
, server_message
, sizeof(server_message
));
164 tt_mem_op(client_keys
, OP_EQ
, server_keys
, 256);
167 tor_free(onion_skin
);
168 tor_free(server_handshake
);
169 tor_free(mem_op_hex_tmp
);
170 ntor3_handshake_state_free(client_state
);
171 ntor3_server_handshake_state_free(relay_state
);
174 dimap_free(private_keys
, NULL
);
178 run_full_handshake(circuit_params_t
*serv_params_in
,
179 circuit_params_t
*client_params_out
,
180 circuit_params_t
*serv_params_out
)
182 extend_info_t info
= {0};
183 uint8_t onionskin
[CELL_PAYLOAD_SIZE
];
184 int onionskin_len
= 0;
186 onion_handshake_state_t handshake_state
= {0};
187 server_onion_keys_t server_keys
= {0};
188 curve25519_keypair_t relay_onion_key
;
189 uint8_t serv_reply
[CELL_PAYLOAD_SIZE
];
190 uint8_t serv_keys
[100];
191 uint8_t rend_nonce
[DIGEST_LEN
];
192 uint8_t client_keys
[CELL_PAYLOAD_SIZE
];
193 uint8_t rend_auth
[DIGEST_LEN
];
195 info
.exit_supports_congestion_control
= 1;
197 unhex(relay_onion_key
.seckey
.secret_key
,
198 "4051daa5921cfa2a1c27b08451324919538e79e788a81b38cbed097a5dff454a");
199 unhex(relay_onion_key
.pubkey
.public_key
,
200 "f8307a2bc1870b00b828bb74dbb8fd88e632a6375ab3bcd1ae706aaa8b6cdd1d");
202 memcpy(&info
.curve25519_onion_key
,
203 &relay_onion_key
.pubkey
, sizeof(info
.curve25519_onion_key
));
204 unhex(info
.ed_identity
.pubkey
,
205 "9fad2af287ef942632833d21f946c6260c33fae6172b60006e86e4a6911753a2");
207 memcpy(&server_keys
.my_ed_identity
, &info
.ed_identity
,
208 sizeof(server_keys
.my_ed_identity
));
210 dimap_add_entry(&server_keys
.curve25519_key_map
,
211 relay_onion_key
.pubkey
.public_key
,
214 onionskin_len
= onion_skin_create(ONION_HANDSHAKE_TYPE_NTOR_V3
, &info
,
215 &handshake_state
, onionskin
,
217 tt_int_op(onionskin_len
, OP_NE
, -1);
219 server_keys
.junk_keypair
= &handshake_state
.u
.ntor3
->client_keypair
;
221 reply_len
= onion_skin_server_handshake(ONION_HANDSHAKE_TYPE_NTOR_V3
,
222 onionskin
, onionskin_len
,
223 &server_keys
, serv_params_in
,
224 serv_reply
, sizeof(serv_reply
),
225 serv_keys
, sizeof(serv_keys
),
226 rend_nonce
, serv_params_out
);
227 tt_int_op(reply_len
, OP_NE
, -1);
229 tt_int_op(onion_skin_client_handshake(ONION_HANDSHAKE_TYPE_NTOR_V3
,
231 serv_reply
, reply_len
,
232 client_keys
, sizeof(client_keys
),
233 rend_auth
, client_params_out
,
237 dimap_free(server_keys
.curve25519_key_map
, NULL
);
238 ntor3_handshake_state_free(handshake_state
.u
.ntor3
);
244 * Test congestion control negotiation logic.
246 * This tests that congestion control is only enabled when both
247 * client and server agree, via consensus param or torrc.
249 * It also tests that when they agree, they agree on the server's
250 * version of sendme_inc.
253 test_ntor3_handshake(void *arg
)
256 circuit_params_t client_params
, serv_params
, serv_ns_params
;
258 serv_ns_params
.sendme_inc_cells
= congestion_control_sendme_inc();
260 /* client off, serv off -> off */
261 serv_ns_params
.cc_enabled
= 0;
262 run_full_handshake(&serv_ns_params
, &client_params
, &serv_params
);
263 tt_int_op(client_params
.cc_enabled
, OP_EQ
, 0);
264 tt_int_op(serv_params
.cc_enabled
, OP_EQ
, 0);
266 /* client off, serv on -> off */
267 congestion_control_set_cc_disabled();
268 serv_ns_params
.cc_enabled
= 1;
269 run_full_handshake(&serv_ns_params
, &client_params
, &serv_params
);
270 tt_int_op(client_params
.cc_enabled
, OP_EQ
, 0);
271 tt_int_op(serv_params
.cc_enabled
, OP_EQ
, 0);
273 /* client off + param, serv on -> on */
274 serv_ns_params
.cc_enabled
= 1;
275 get_options_mutable()->AlwaysCongestionControl
= 1;
276 run_full_handshake(&serv_ns_params
, &client_params
, &serv_params
);
277 tt_int_op(client_params
.cc_enabled
, OP_EQ
, 1);
278 tt_int_op(serv_params
.cc_enabled
, OP_EQ
, 1);
280 /* client on, serv off -> off */
281 serv_ns_params
.cc_enabled
= 0;
282 congestion_control_set_cc_enabled();
283 run_full_handshake(&serv_ns_params
, &client_params
, &serv_params
);
284 tt_int_op(client_params
.cc_enabled
, OP_EQ
, 0);
285 tt_int_op(serv_params
.cc_enabled
, OP_EQ
, 0);
287 /* client on, serv on -> on */
288 serv_ns_params
.cc_enabled
= 1;
289 run_full_handshake(&serv_ns_params
, &client_params
, &serv_params
);
290 tt_int_op(client_params
.cc_enabled
, OP_EQ
, 1);
291 tt_int_op(serv_params
.cc_enabled
, OP_EQ
, 1);
293 /* client on, serv on, sendme_inc diff -> serv sendme_inc */
294 serv_ns_params
.cc_enabled
= 1;
295 serv_ns_params
.sendme_inc_cells
+= 1;
296 run_full_handshake(&serv_ns_params
, &client_params
, &serv_params
);
297 tt_int_op(client_params
.cc_enabled
, OP_EQ
, 1);
298 tt_int_op(serv_params
.cc_enabled
, OP_EQ
, 1);
299 tt_int_op(serv_params
.sendme_inc_cells
, OP_EQ
,
300 client_params
.sendme_inc_cells
);
301 tt_int_op(client_params
.sendme_inc_cells
, OP_EQ
,
302 serv_ns_params
.sendme_inc_cells
);
303 tt_int_op(client_params
.sendme_inc_cells
, OP_NE
,
304 congestion_control_sendme_inc());
310 struct testcase_t ntor_v3_tests
[] = {
311 { "testvecs", test_ntor3_testvecs
, 0, NULL
, NULL
, },
312 { "handshake_negtotiation", test_ntor3_handshake
, 0, NULL
, NULL
, },