diff options
author | Nick Mathewson <nickm@torproject.org> | 2005-05-02 22:35:18 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2005-05-02 22:35:18 +0000 |
commit | ab34901263c6593a56c039979e04bf9345932dd1 (patch) | |
tree | 5cc0591eb4f02fde0e441df1be5a678736f917aa /src/or/onion.c | |
parent | 16184f62dcb40fce82f1170b31a161d314dfc81f (diff) | |
download | tor-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.c | 71 |
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) |