static void bench_onion_ntor_impl(void) { const int iters = 1<<10; int i; curve25519_keypair_t keypair1, keypair2; uint64_t start, end; uint8_t os[NTOR_ONIONSKIN_LEN]; uint8_t or[NTOR_REPLY_LEN]; ntor_handshake_state_t *state = NULL; uint8_t nodeid[DIGEST_LEN]; di_digest256_map_t *keymap = NULL; curve25519_secret_key_generate(&keypair1.seckey, 0); curve25519_public_key_generate(&keypair1.pubkey, &keypair1.seckey); curve25519_secret_key_generate(&keypair2.seckey, 0); curve25519_public_key_generate(&keypair2.pubkey, &keypair2.seckey); dimap_add_entry(&keymap, keypair1.pubkey.public_key, &keypair1); dimap_add_entry(&keymap, keypair2.pubkey.public_key, &keypair2); reset_perftime(); start = perftime(); for (i = 0; i < iters; ++i) { onion_skin_ntor_create(nodeid, &keypair1.pubkey, &state, os); ntor_handshake_state_free(state); state = NULL; } end = perftime(); printf("Client-side, part 1: %f usec.\n", NANOCOUNT(start, end, iters)/1e3); state = NULL; onion_skin_ntor_create(nodeid, &keypair1.pubkey, &state, os); start = perftime(); for (i = 0; i < iters; ++i) { uint8_t key_out[CPATH_KEY_MATERIAL_LEN]; onion_skin_ntor_server_handshake(os, keymap, NULL, nodeid, or, key_out, sizeof(key_out)); } end = perftime(); printf("Server-side: %f usec\n", NANOCOUNT(start, end, iters)/1e3); start = perftime(); for (i = 0; i < iters; ++i) { uint8_t key_out[CPATH_KEY_MATERIAL_LEN]; int s; s = onion_skin_ntor_client_handshake(state, or, key_out, sizeof(key_out), NULL); tor_assert(s == 0); } end = perftime(); printf("Client-side, part 2: %f usec.\n", NANOCOUNT(start, end, iters)/1e3); ntor_handshake_state_free(state); dimap_free(keymap, NULL); }
static int client1(int argc, char **argv) { /* client1 nodeID B -> msg state */ curve25519_public_key_t B; uint8_t node_id[DIGEST_LEN]; ntor_handshake_state_t *state = NULL; uint8_t msg[NTOR_ONIONSKIN_LEN]; char buf[1024]; N_ARGS(4); BASE16(2, node_id, DIGEST_LEN); BASE16(3, B.public_key, CURVE25519_PUBKEY_LEN); if (onion_skin_ntor_create(node_id, &B, &state, msg)<0) { fprintf(stderr, "handshake failed"); return 2; } base16_encode(buf, sizeof(buf), (const char*)msg, sizeof(msg)); printf("%s\n", buf); base16_encode(buf, sizeof(buf), (void*)state, sizeof(*state)); printf("%s\n", buf); ntor_handshake_state_free(state); return 0; }
static void test_ntor_handshake(void *arg) { /* client-side */ ntor_handshake_state_t *c_state = NULL; uint8_t c_buf[NTOR_ONIONSKIN_LEN]; uint8_t c_keys[400]; /* server-side */ di_digest256_map_t *s_keymap=NULL; curve25519_keypair_t s_keypair; uint8_t s_buf[NTOR_REPLY_LEN]; uint8_t s_keys[400]; /* shared */ const curve25519_public_key_t *server_pubkey; uint8_t node_id[20] = "abcdefghijklmnopqrst"; (void) arg; /* Make the server some keys */ curve25519_secret_key_generate(&s_keypair.seckey, 0); curve25519_public_key_generate(&s_keypair.pubkey, &s_keypair.seckey); dimap_add_entry(&s_keymap, s_keypair.pubkey.public_key, &s_keypair); server_pubkey = &s_keypair.pubkey; /* client handshake 1. */ memset(c_buf, 0, NTOR_ONIONSKIN_LEN); tt_int_op(0, OP_EQ, onion_skin_ntor_create(node_id, server_pubkey, &c_state, c_buf)); /* server handshake */ memset(s_buf, 0, NTOR_REPLY_LEN); memset(s_keys, 0, 40); tt_int_op(0, OP_EQ, onion_skin_ntor_server_handshake(c_buf, s_keymap, NULL, node_id, s_buf, s_keys, 400)); /* client handshake 2 */ memset(c_keys, 0, 40); tt_int_op(0, OP_EQ, onion_skin_ntor_client_handshake(c_state, s_buf, c_keys, 400, NULL)); tt_mem_op(c_keys,OP_EQ, s_keys, 400); memset(s_buf, 0, 40); tt_mem_op(c_keys,OP_NE, s_buf, 40); /* Now try with a bogus server response. Zero input should trigger * All The Problems. */ memset(c_keys, 0, 400); memset(s_buf, 0, NTOR_REPLY_LEN); const char *msg = NULL; tt_int_op(-1, OP_EQ, onion_skin_ntor_client_handshake(c_state, s_buf, c_keys, 400, &msg)); tt_str_op(msg, OP_EQ, "Zero output from curve25519 handshake"); done: ntor_handshake_state_free(c_state); dimap_free(s_keymap, NULL); }
/** Release whatever storage is held in <b>state</b>, depending on its * type, and clear its pointer. */ void onion_handshake_state_release(onion_handshake_state_t *state) { switch (state->tag) { case ONION_HANDSHAKE_TYPE_TAP: crypto_dh_free(state->u.tap); state->u.tap = NULL; break; case ONION_HANDSHAKE_TYPE_FAST: fast_handshake_state_free(state->u.fast); state->u.fast = NULL; break; case ONION_HANDSHAKE_TYPE_NTOR: ntor_handshake_state_free(state->u.ntor); state->u.ntor = NULL; break; default: /* LCOV_EXCL_START * This state should not even exist. */ log_warn(LD_BUG, "called with unknown handshake state type %d", (int)state->tag); tor_fragile_assert(); /* LCOV_EXCL_STOP */ } }
/** Release whatever storage is held in <b>state</b>, depending on its * type, and clear its pointer. */ void onion_handshake_state_release(onion_handshake_state_t *state) { switch (state->tag) { case ONION_HANDSHAKE_TYPE_TAP: crypto_dh_free(state->u.tap); state->u.tap = NULL; break; case ONION_HANDSHAKE_TYPE_FAST: fast_handshake_state_free(state->u.fast); state->u.fast = NULL; break; case ONION_HANDSHAKE_TYPE_NTOR: ntor_handshake_state_free(state->u.ntor); state->u.ntor = NULL; break; default: log_warn(LD_BUG, "called with unknown handshake state type %d", (int)state->tag); tor_fragile_assert(); } }