commit 4575a9637b902dbf835e96b5d245a6d53f33a868 Author: Zack Weinberg zackw@cmu.edu Date: Wed Jun 20 22:49:56 2012 -0700
Add another testing option to turn off all encryption in the chopper. --- src/crypt.cc | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/crypt.h | 20 +++++++++++ src/protocol/chop.cc | 68 +++++++++++++++++++++++++------------ 3 files changed, 157 insertions(+), 22 deletions(-)
diff --git a/src/crypt.cc b/src/crypt.cc index 1110d0b..6d7e0d4 100644 --- a/src/crypt.cc +++ b/src/crypt.cc @@ -156,6 +156,13 @@ namespace { virtual void encrypt(uint8_t *out, const uint8_t *in); };
+ struct ecb_encryptor_noop_impl : ecb_encryptor + { + ecb_encryptor_noop_impl() {} + virtual ~ecb_encryptor_noop_impl(); + virtual void encrypt(uint8_t *out, const uint8_t *in); + }; + struct ecb_decryptor_impl : ecb_decryptor { EVP_CIPHER_CTX ctx; @@ -163,6 +170,13 @@ namespace { virtual ~ecb_decryptor_impl(); virtual void decrypt(uint8_t *out, const uint8_t *in); }; + + struct ecb_decryptor_noop_impl : ecb_decryptor + { + ecb_decryptor_noop_impl() {} + virtual ~ecb_decryptor_noop_impl(); + virtual void decrypt(uint8_t *out, const uint8_t *in); + }; }
ecb_encryptor * @@ -197,6 +211,12 @@ ecb_encryptor::create(key_generator *gen, size_t keylen) return enc; }
+ecb_encryptor * +ecb_encryptor::create_noop() +{ + return new ecb_encryptor_noop_impl; +} + ecb_decryptor * ecb_decryptor::create(const uint8_t *key, size_t keylen) { @@ -229,13 +249,23 @@ ecb_decryptor::create(key_generator *gen, size_t keylen) return dec; }
+ecb_decryptor * +ecb_decryptor::create_noop() +{ + return new ecb_decryptor_noop_impl; +} + ecb_encryptor::~ecb_encryptor() {} ecb_encryptor_impl::~ecb_encryptor_impl() { EVP_CIPHER_CTX_cleanup(&ctx); } +ecb_encryptor_noop_impl::~ecb_encryptor_noop_impl() +{}
ecb_decryptor::~ecb_decryptor() {} ecb_decryptor_impl::~ecb_decryptor_impl() { EVP_CIPHER_CTX_cleanup(&ctx); } +ecb_decryptor_noop_impl::~ecb_decryptor_noop_impl() +{}
void ecb_encryptor_impl::encrypt(uint8_t *out, const uint8_t *in) @@ -247,6 +277,12 @@ ecb_encryptor_impl::encrypt(uint8_t *out, const uint8_t *in) }
void +ecb_encryptor_noop_impl::encrypt(uint8_t *out, const uint8_t *in) +{ + memcpy(out, in, AES_BLOCK_LEN); +} + +void ecb_decryptor_impl::decrypt(uint8_t *out, const uint8_t *in) { int olen; @@ -255,6 +291,12 @@ ecb_decryptor_impl::decrypt(uint8_t *out, const uint8_t *in) log_crypto_abort("ecb_decryptor::decrypt"); }
+void +ecb_decryptor_noop_impl::decrypt(uint8_t *out, const uint8_t *in) +{ + memcpy(out, in, AES_BLOCK_LEN); +} + namespace { struct gcm_encryptor_impl : gcm_encryptor { @@ -265,6 +307,14 @@ namespace { const uint8_t *nonce, size_t nlen); };
+ struct gcm_encryptor_noop_impl : gcm_encryptor + { + gcm_encryptor_noop_impl() {} + virtual ~gcm_encryptor_noop_impl(); + virtual void encrypt(uint8_t *out, const uint8_t *in, size_t inlen, + const uint8_t *nonce, size_t nlen); + }; + struct gcm_decryptor_impl : gcm_decryptor { EVP_CIPHER_CTX ctx; @@ -273,6 +323,14 @@ namespace { virtual int decrypt(uint8_t *out, const uint8_t *in, size_t inlen, const uint8_t *nonce, size_t nlen); }; + + struct gcm_decryptor_noop_impl : gcm_decryptor + { + gcm_decryptor_noop_impl() {} + virtual ~gcm_decryptor_noop_impl(); + virtual int decrypt(uint8_t *out, const uint8_t *in, size_t inlen, + const uint8_t *nonce, size_t nlen); + }; }
// It *appears* (from inspecting the guts of libcrypto, *not* from the @@ -320,6 +378,12 @@ gcm_encryptor::create(key_generator *gen, size_t keylen) return enc; }
+gcm_encryptor * +gcm_encryptor::create_noop() +{ + return new gcm_encryptor_noop_impl; +} + gcm_decryptor * gcm_decryptor::create(const uint8_t *key, size_t keylen) { @@ -348,12 +412,23 @@ gcm_decryptor::create(key_generator *gen, size_t keylen) return dec; }
+gcm_decryptor * +gcm_decryptor::create_noop() +{ + return new gcm_decryptor_noop_impl; +} + gcm_encryptor::~gcm_encryptor() {} gcm_encryptor_impl::~gcm_encryptor_impl() { EVP_CIPHER_CTX_cleanup(&ctx); } +gcm_encryptor_noop_impl::~gcm_encryptor_noop_impl() +{} + gcm_decryptor::~gcm_decryptor() {} gcm_decryptor_impl::~gcm_decryptor_impl() { EVP_CIPHER_CTX_cleanup(&ctx); } +gcm_decryptor_noop_impl::~gcm_decryptor_noop_impl() +{}
void gcm_encryptor_impl::encrypt(uint8_t *out, const uint8_t *in, size_t inlen, @@ -382,6 +457,14 @@ gcm_encryptor_impl::encrypt(uint8_t *out, const uint8_t *in, size_t inlen, log_crypto_abort("gcm_encryptor::write tag"); }
+void +gcm_encryptor_noop_impl::encrypt(uint8_t *out, const uint8_t *in, size_t inlen, + const uint8_t *, size_t) +{ + memcpy(out, in, inlen); + memset(out + inlen, 0, 16); +} + int gcm_decryptor_impl::decrypt(uint8_t *out, const uint8_t *in, size_t inlen, const uint8_t *nonce, size_t nlen) @@ -417,6 +500,14 @@ gcm_decryptor_impl::decrypt(uint8_t *out, const uint8_t *in, size_t inlen, return 0; }
+int +gcm_decryptor_noop_impl::decrypt(uint8_t *out, const uint8_t *in, size_t inlen, + const uint8_t *, size_t) +{ + memcpy(out, in, inlen - 16); + return 0; +} + // We use the slightly lower-level EC_* / ECDH_* routines for // ecdh_message, instead of the EVP_PKEY_* routines, because we don't // need algorithmic agility, and it means we only have to puzzle out diff --git a/src/crypt.h b/src/crypt.h index 869107a..bd6087d 100644 --- a/src/crypt.h +++ b/src/crypt.h @@ -51,6 +51,11 @@ struct ecb_encryptor 16, 24, or 32 bytes. */ static ecb_encryptor *create(key_generator *gen, size_t keylen);
+ /** Return a new AES/ECB encryption state that doesn't actually + encrypt anything -- it just copies its input to its output. + For testing purposes only. */ + static ecb_encryptor *create_noop(); + /** Encrypt exactly AES_BLOCK_LEN bytes of data in the buffer 'in' and write the result to 'out'. */ virtual void encrypt(uint8_t *out, const uint8_t *in) = 0; @@ -74,6 +79,11 @@ struct ecb_decryptor 16, 24, or 32 bytes. */ static ecb_decryptor *create(key_generator *gen, size_t keylen);
+ /** Return a new AES/ECB decryption state that doesn't actually + decrypt anything -- it just copies its input to its output. + For testing purposes only. */ + static ecb_decryptor *create_noop(); + /** Decrypt exactly AES_BLOCK_LEN bytes of data in the buffer 'in' and write the result to 'out'. */ virtual void decrypt(uint8_t *out, const uint8_t *in) = 0; @@ -98,6 +108,11 @@ struct gcm_encryptor 16, 24, or 32 bytes. */ static gcm_encryptor *create(key_generator *gen, size_t keylen);
+ /** Return a new AES/GCM encryption state that doesn't actually + encrypt anything -- it just copies its input to its output. + For testing purposes only. */ + static gcm_encryptor *create_noop(); + /** Encrypt 'inlen' bytes of data in the buffer 'in', writing the result plus an authentication tag to the buffer 'out', whose length must be at least 'inlen'+16 bytes. Use 'nonce' @@ -125,6 +140,11 @@ struct gcm_decryptor 16, 24, or 32 bytes. */ static gcm_decryptor *create(key_generator *gen, size_t keylen);
+ /** Return a new AES/GCM decryption state that doesn't actually + decrypt anything -- it just copies its input to its output. + For testing purposes only. */ + static gcm_decryptor *create_noop(); + /** Decrypt 'inlen' bytes of data in the buffer 'in'; the last 16 bytes of this buffer are assumed to be the authentication tag. Write the result to the buffer 'out', whose length must be at diff --git a/src/protocol/chop.cc b/src/protocol/chop.cc index c865c9b..bb8e906 100644 --- a/src/protocol/chop.cc +++ b/src/protocol/chop.cc @@ -388,6 +388,7 @@ struct chop_config_t : config_t vector<steg_config_t *> steg_targets; chop_circuit_table circuits; bool trace_packets; + bool encryption;
CONFIG_DECLARE_METHODS(chop); }; @@ -398,6 +399,7 @@ chop_config_t::chop_config_t() { ignore_socks_destination = true; trace_packets = false; + encryption = true; }
chop_config_t::~chop_config_t() @@ -445,18 +447,24 @@ chop_config_t::init(int n_options, const char *const *options) } else goto usage;
- // if in client mode, accept and ignore --server-key= - if (mode != LSN_SIMPLE_SERVER && - !strncmp(options[1], "--server-key=", 13)) { - options++; - n_options--; - } - - if (!strcmp(options[1], "--trace-packets")) { + while (options[1][0] == '-') { + if (!strncmp(options[1], "--server-key=", 13)) { + // accept and ignore (for now) client only + if (mode == LSN_SIMPLE_SERVER) { + log_warn("chop: --server-key option is not valid in server mode"); + goto usage; + } + } else if (!strcmp(options[1], "--trace-packets")) { + trace_packets = true; + log_enable_timestamps(); + } else if (!strcmp(options[1], "--disable-encryption")) { + encryption = false; + } else { + log_warn("chop: unrecognized option '%s'", options[1]); + goto usage; + } options++; n_options--; - trace_packets = true; - log_enable_timestamps(); }
up_address = resolve_address_port(options[1], 1, listen_up, defport); @@ -550,21 +558,37 @@ chop_config_t::circuit_create(size_t) chop_circuit_t *ckt = new chop_circuit_t; ckt->config = this;
- key_generator *kgen = - key_generator::from_passphrase((const uint8_t *)passphrase, - sizeof(passphrase) - 1, - 0, 0, 0, 0); + key_generator *kgen = 0; + + if (encryption) + kgen = key_generator::from_passphrase((const uint8_t *)passphrase, + sizeof(passphrase) - 1, + 0, 0, 0, 0);
if (mode == LSN_SIMPLE_SERVER) { - ckt->send_crypt = gcm_encryptor::create(kgen, 16); - ckt->send_hdr_crypt = ecb_encryptor::create(kgen, 16); - ckt->recv_crypt = gcm_decryptor::create(kgen, 16); - ckt->recv_hdr_crypt = ecb_decryptor::create(kgen, 16); + if (encryption) { + ckt->send_crypt = gcm_encryptor::create(kgen, 16); + ckt->send_hdr_crypt = ecb_encryptor::create(kgen, 16); + ckt->recv_crypt = gcm_decryptor::create(kgen, 16); + ckt->recv_hdr_crypt = ecb_decryptor::create(kgen, 16); + } else { + ckt->send_crypt = gcm_encryptor::create_noop(); + ckt->send_hdr_crypt = ecb_encryptor::create_noop(); + ckt->recv_crypt = gcm_decryptor::create_noop(); + ckt->recv_hdr_crypt = ecb_decryptor::create_noop(); + } } else { - ckt->recv_crypt = gcm_decryptor::create(kgen, 16); - ckt->recv_hdr_crypt = ecb_decryptor::create(kgen, 16); - ckt->send_crypt = gcm_encryptor::create(kgen, 16); - ckt->send_hdr_crypt = ecb_encryptor::create(kgen, 16); + if (encryption) { + ckt->recv_crypt = gcm_decryptor::create(kgen, 16); + ckt->recv_hdr_crypt = ecb_decryptor::create(kgen, 16); + ckt->send_crypt = gcm_encryptor::create(kgen, 16); + ckt->send_hdr_crypt = ecb_encryptor::create(kgen, 16); + } else { + ckt->recv_crypt = gcm_decryptor::create_noop(); + ckt->recv_hdr_crypt = ecb_decryptor::create_noop(); + ckt->send_crypt = gcm_encryptor::create_noop(); + ckt->send_hdr_crypt = ecb_encryptor::create_noop(); + }
std::pair<chop_circuit_table::iterator, bool> out; do {
tor-commits@lists.torproject.org