summaryrefslogtreecommitdiff
path: root/src/or/onion.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2005-05-02 22:35:18 +0000
committerNick Mathewson <nickm@torproject.org>2005-05-02 22:35:18 +0000
commitab34901263c6593a56c039979e04bf9345932dd1 (patch)
tree5cc0591eb4f02fde0e441df1be5a678736f917aa /src/or/onion.c
parent16184f62dcb40fce82f1170b31a161d314dfc81f (diff)
downloadtor-ab34901263c6593a56c039979e04bf9345932dd1.tar.gz
tor-ab34901263c6593a56c039979e04bf9345932dd1.zip
New and frightening code to implement fast-path first-hop CREATE_FAST cells. Watch out when we bump the version to 0.1.0.6-rc!
svn:r4162
Diffstat (limited to 'src/or/onion.c')
-rw-r--r--src/or/onion.c71
1 files changed, 67 insertions, 4 deletions
diff --git a/src/or/onion.c b/src/or/onion.c
index 4d354abbd7..c24612957f 100644
--- a/src/or/onion.c
+++ b/src/or/onion.c
@@ -199,7 +199,7 @@ onion_skin_create(crypto_pk_env_t *dest_router_key,
* next key_out_len bytes of key material in key_out.
*/
int
-onion_skin_server_handshake(char *onion_skin, /* ONIONSKIN_CHALLENGE_LEN bytes */
+onion_skin_server_handshake(const char *onion_skin, /* ONIONSKIN_CHALLENGE_LEN bytes */
crypto_pk_env_t *private_key,
crypto_pk_env_t *prev_private_key,
char *handshake_reply_out, /* ONIONSKIN_REPLY_LEN bytes */
@@ -287,9 +287,9 @@ onion_skin_server_handshake(char *onion_skin, /* ONIONSKIN_CHALLENGE_LEN bytes *
*/
int
onion_skin_client_handshake(crypto_dh_env_t *handshake_state,
- char *handshake_reply, /* Must be ONIONSKIN_REPLY_LEN bytes */
- char *key_out,
- size_t key_out_len)
+ const char *handshake_reply, /* Must be ONIONSKIN_REPLY_LEN bytes */
+ char *key_out,
+ size_t key_out_len)
{
int len;
char *key_material=NULL;
@@ -329,6 +329,69 @@ onion_skin_client_handshake(crypto_dh_env_t *handshake_state,
return 0;
}
+int
+fast_server_handshake(const char *key_in, /* DIGEST_LEN bytes */
+ char *handshake_reply_out, /* DIGEST_LEN*2 bytes */
+ char *key_out,
+ size_t key_out_len)
+{
+ char tmp[DIGEST_LEN+DIGEST_LEN+1];
+ char digest[DIGEST_LEN];
+ int i;
+
+ if (crypto_rand(handshake_reply_out, DIGEST_LEN)<0)
+ return -1;
+
+ memcpy(tmp, key_in, DIGEST_LEN);
+ memcpy(tmp+DIGEST_LEN, handshake_reply_out, DIGEST_LEN);
+ tmp[DIGEST_LEN+DIGEST_LEN] = 0;
+ crypto_digest(handshake_reply_out+DIGEST_LEN, tmp, sizeof(tmp));
+
+ for (i = 0; i*DIGEST_LEN < key_out_len; ++i) {
+ size_t len;
+ tmp[DIGEST_LEN+DIGEST_LEN] = i+1;
+ crypto_digest(digest, tmp, sizeof(tmp));
+ len = key_out_len - i*DIGEST_LEN;
+ if (len > DIGEST_LEN) len = DIGEST_LEN;
+ memcpy(key_out+i*DIGEST_LEN, digest, len);
+ }
+
+ return 0;
+}
+
+int
+fast_client_handshake(const char *handshake_state, /* DIGEST_LEN bytes */
+ const char *handshake_reply_out, /* DIGEST_LEN*2 bytes */
+ char *key_out,
+ size_t key_out_len)
+{
+ char tmp[DIGEST_LEN+DIGEST_LEN+1];
+ char digest[DIGEST_LEN];
+ int i;
+
+ memcpy(tmp, handshake_state, DIGEST_LEN);
+ memcpy(tmp+DIGEST_LEN, handshake_reply_out, DIGEST_LEN);
+ tmp[DIGEST_LEN+DIGEST_LEN] = 0;
+ crypto_digest(digest, tmp, sizeof(tmp));
+
+ if (memcmp(digest, handshake_reply_out+DIGEST_LEN, DIGEST_LEN)) {
+ /* H(K) does *not* match. Something fishy. */
+ log_fn(LOG_WARN,"Digest DOES NOT MATCH on fast handshake. Bug or attack.");
+ return -1;
+ }
+
+ for (i = 0; i*DIGEST_LEN < key_out_len; ++i) {
+ size_t len;
+ tmp[DIGEST_LEN+DIGEST_LEN] = i+1;
+ crypto_digest(digest, tmp, sizeof(tmp));
+ len = key_out_len - i*DIGEST_LEN;
+ if (len > DIGEST_LEN) len = DIGEST_LEN;
+ memcpy(key_out+i*DIGEST_LEN, digest, len);
+ }
+
+ return 0;
+}
+
/** Remove all circuits from the pending list. Called from tor_free_all. */
void
clear_pending_onions(void)