1 /* Copyright (c) 2017-2019, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 /** This is a wrapper over the little-t-tor HS ntor functions. The wrapper is
5 * used by src/test/hs_ntor_ref.py to conduct the HS ntor integration
8 * The logic of this wrapper is basically copied from src/test/test_ntor_cl.c
15 #define ONION_NTOR_PRIVATE
16 #include "core/or/or.h"
17 #include "lib/crypt_ops/crypto_cipher.h"
18 #include "lib/crypt_ops/crypto_curve25519.h"
19 #include "lib/crypt_ops/crypto_ed25519.h"
20 #include "lib/crypt_ops/crypto_format.h"
21 #include "lib/crypt_ops/crypto_init.h"
22 #include "core/crypto/hs_ntor.h"
23 #include "core/crypto/onion_ntor.h"
25 #define N_ARGS(n) STMT_BEGIN { \
27 fprintf(stderr, "%s needs %d arguments.\n",argv[1],n); \
31 #define BASE16(idx, var, n) STMT_BEGIN { \
32 const char *s = argv[(idx)]; \
33 if (base16_decode((char*)var, n, s, strlen(s)) < (int)n ) { \
34 fprintf(stderr, "couldn't decode argument %d (%s)\n",idx,s); \
38 #define INT(idx, var) STMT_BEGIN { \
39 var = atoi(argv[(idx)]); \
41 fprintf(stderr, "bad integer argument %d (%s)\n",idx,argv[(idx)]); \
45 /** The first part of the HS ntor protocol. The client-side computes all
46 necessary key material and sends the appropriate message to the service. */
48 client1(int argc
, char **argv
)
53 curve25519_public_key_t intro_enc_pubkey
;
54 ed25519_public_key_t intro_auth_pubkey
;
55 curve25519_keypair_t client_ephemeral_enc_keypair
;
56 uint8_t subcredential
[DIGEST256_LEN
];
59 hs_ntor_intro_cell_keys_t hs_ntor_intro_cell_keys
;
64 BASE16(2, intro_auth_pubkey
.pubkey
, ED25519_PUBKEY_LEN
);
65 BASE16(3, intro_enc_pubkey
.public_key
, CURVE25519_PUBKEY_LEN
);
66 BASE16(4, client_ephemeral_enc_keypair
.seckey
.secret_key
,
67 CURVE25519_SECKEY_LEN
);
68 BASE16(5, subcredential
, DIGEST256_LEN
);
70 /* Generate keypair */
71 curve25519_public_key_generate(&client_ephemeral_enc_keypair
.pubkey
,
72 &client_ephemeral_enc_keypair
.seckey
);
74 retval
= hs_ntor_client_get_introduce1_keys(&intro_auth_pubkey
,
76 &client_ephemeral_enc_keypair
,
78 &hs_ntor_intro_cell_keys
);
84 base16_encode(buf
, sizeof(buf
),
85 (const char*)hs_ntor_intro_cell_keys
.enc_key
,
86 sizeof(hs_ntor_intro_cell_keys
.enc_key
));
89 base16_encode(buf
, sizeof(buf
),
90 (const char*)hs_ntor_intro_cell_keys
.mac_key
,
91 sizeof(hs_ntor_intro_cell_keys
.mac_key
));
98 /** The second part of the HS ntor protocol. The service-side computes all
99 necessary key material and sends the appropriate message to the client */
101 server1(int argc
, char **argv
)
106 curve25519_keypair_t intro_enc_keypair
;
107 ed25519_public_key_t intro_auth_pubkey
;
108 curve25519_public_key_t client_ephemeral_enc_pubkey
;
109 uint8_t subcredential
[DIGEST256_LEN
];
112 hs_ntor_intro_cell_keys_t hs_ntor_intro_cell_keys
;
113 hs_ntor_rend_cell_keys_t hs_ntor_rend_cell_keys
;
114 curve25519_keypair_t service_ephemeral_rend_keypair
;
119 BASE16(2, intro_auth_pubkey
.pubkey
, ED25519_PUBKEY_LEN
);
120 BASE16(3, intro_enc_keypair
.seckey
.secret_key
, CURVE25519_SECKEY_LEN
);
121 BASE16(4, client_ephemeral_enc_pubkey
.public_key
, CURVE25519_PUBKEY_LEN
);
122 BASE16(5, subcredential
, DIGEST256_LEN
);
124 /* Generate keypair */
125 curve25519_public_key_generate(&intro_enc_keypair
.pubkey
,
126 &intro_enc_keypair
.seckey
);
127 curve25519_keypair_generate(&service_ephemeral_rend_keypair
, 0);
129 /* Get INTRODUCE1 keys */
130 retval
= hs_ntor_service_get_introduce1_keys(&intro_auth_pubkey
,
132 &client_ephemeral_enc_pubkey
,
134 &hs_ntor_intro_cell_keys
);
139 /* Get RENDEZVOUS1 keys */
140 retval
= hs_ntor_service_get_rendezvous1_keys(&intro_auth_pubkey
,
142 &service_ephemeral_rend_keypair
,
143 &client_ephemeral_enc_pubkey
,
144 &hs_ntor_rend_cell_keys
);
150 base16_encode(buf
, sizeof(buf
),
151 (const char*)hs_ntor_intro_cell_keys
.enc_key
,
152 sizeof(hs_ntor_intro_cell_keys
.enc_key
));
155 base16_encode(buf
, sizeof(buf
),
156 (const char*)hs_ntor_intro_cell_keys
.mac_key
,
157 sizeof(hs_ntor_intro_cell_keys
.mac_key
));
160 base16_encode(buf
, sizeof(buf
),
161 (const char*)hs_ntor_rend_cell_keys
.rend_cell_auth_mac
,
162 sizeof(hs_ntor_rend_cell_keys
.rend_cell_auth_mac
));
164 /* Send NTOR_KEY_SEED */
165 base16_encode(buf
, sizeof(buf
),
166 (const char*)hs_ntor_rend_cell_keys
.ntor_key_seed
,
167 sizeof(hs_ntor_rend_cell_keys
.ntor_key_seed
));
169 /* Send service ephemeral pubkey (Y) */
170 base16_encode(buf
, sizeof(buf
),
171 (const char*)service_ephemeral_rend_keypair
.pubkey
.public_key
,
172 sizeof(service_ephemeral_rend_keypair
.pubkey
.public_key
));
179 /** The final step of the ntor protocol, the client computes and returns the
180 * rendezvous key material. */
182 client2(int argc
, char **argv
)
187 curve25519_public_key_t intro_enc_pubkey
;
188 ed25519_public_key_t intro_auth_pubkey
;
189 curve25519_keypair_t client_ephemeral_enc_keypair
;
190 curve25519_public_key_t service_ephemeral_rend_pubkey
;
191 uint8_t subcredential
[DIGEST256_LEN
];
194 hs_ntor_rend_cell_keys_t hs_ntor_rend_cell_keys
;
199 BASE16(2, intro_auth_pubkey
.pubkey
, ED25519_PUBKEY_LEN
);
200 BASE16(3, client_ephemeral_enc_keypair
.seckey
.secret_key
,
201 CURVE25519_SECKEY_LEN
);
202 BASE16(4, intro_enc_pubkey
.public_key
, CURVE25519_PUBKEY_LEN
);
203 BASE16(5, service_ephemeral_rend_pubkey
.public_key
, CURVE25519_PUBKEY_LEN
);
204 BASE16(6, subcredential
, DIGEST256_LEN
);
206 /* Generate keypair */
207 curve25519_public_key_generate(&client_ephemeral_enc_keypair
.pubkey
,
208 &client_ephemeral_enc_keypair
.seckey
);
210 /* Get RENDEZVOUS1 keys */
211 retval
= hs_ntor_client_get_rendezvous1_keys(&intro_auth_pubkey
,
212 &client_ephemeral_enc_keypair
,
214 &service_ephemeral_rend_pubkey
,
215 &hs_ntor_rend_cell_keys
);
221 base16_encode(buf
, sizeof(buf
),
222 (const char*)hs_ntor_rend_cell_keys
.rend_cell_auth_mac
,
223 sizeof(hs_ntor_rend_cell_keys
.rend_cell_auth_mac
));
225 /* Send NTOR_KEY_SEED */
226 base16_encode(buf
, sizeof(buf
),
227 (const char*)hs_ntor_rend_cell_keys
.ntor_key_seed
,
228 sizeof(hs_ntor_rend_cell_keys
.ntor_key_seed
));
235 /** Perform a different part of the protocol depdning on the argv used. */
237 main(int argc
, char **argv
)
240 fprintf(stderr
, "I need arguments. Read source for more info.\n");
246 if (crypto_global_init(0, NULL
, NULL
) < 0)
249 if (!strcmp(argv
[1], "client1")) {
250 return client1(argc
, argv
);
251 } else if (!strcmp(argv
[1], "server1")) {
252 return server1(argc
, argv
);
253 } else if (!strcmp(argv
[1], "client2")) {
254 return client2(argc
, argv
);
256 fprintf(stderr
, "What's a %s?\n", argv
[1]);