From d97760a781a793d35dfe75367dd8d80ab59bbb49 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Wed, 18 Feb 2009 13:08:59 +0000 Subject: added anytun02 compat runtime switch --- cmd-option-letters | 2 +- src/anytun-config.cpp | 2 +- src/anytun.cpp | 11 +++++++---- src/cipher.cpp | 20 ++++++++++++++++---- src/cipher.h | 9 +++++++-- src/cipherFactory.cpp | 10 +++++----- src/cipherFactory.h | 2 +- src/configure | 10 ---------- src/connectionList.cpp | 2 +- src/keyDerivation.cpp | 26 ++++++++++++++++++++++++-- src/keyDerivation.h | 14 ++++++++------ src/keyDerivationFactory.cpp | 10 +++++----- src/keyDerivationFactory.h | 2 +- src/options.cpp | 17 +++++++++++++++++ src/options.h | 3 +++ 15 files changed, 97 insertions(+), 43 deletions(-) diff --git a/cmd-option-letters b/cmd-option-letters index 841a06d..86294ea 100644 --- a/cmd-option-letters +++ b/cmd-option-letters @@ -39,7 +39,7 @@ K: master key L: M: remote sync hosts N: -O: +O: anytun 0.2 compat mode P: write pid file Q: R: route diff --git a/src/anytun-config.cpp b/src/anytun-config.cpp index 9b94af9..650c75b 100644 --- a/src/anytun-config.cpp +++ b/src/anytun-config.cpp @@ -53,7 +53,7 @@ void createConnection(const PacketSourceEndpoint & remote_end, ConnectionList & { SeqWindow * seq = new SeqWindow(seqSize); seq_nr_t seq_nr_ = 0; - KeyDerivation * kd = KeyDerivationFactory::create( gOpt.getKdPrf() ); + KeyDerivation * kd = KeyDerivationFactory::create( gOpt.getKdPrf() , gOpt.getAnytun02Compat() ); kd->init( gOpt.getKey(), gOpt.getSalt() ); // cLog.msg(Log::PRIO_NOTICE) << "added connection remote host " << remote_end; ConnectionParam connparam ( (*kd), (*seq), seq_nr_, remote_end ); diff --git a/src/anytun.cpp b/src/anytun.cpp index ab847a8..cfe80d1 100644 --- a/src/anytun.cpp +++ b/src/anytun.cpp @@ -83,7 +83,7 @@ void createConnection(const PacketSourceEndpoint & remote_end, window_size_t seq { SeqWindow* seq = new SeqWindow(seqSize); seq_nr_t seq_nr_=0; - KeyDerivation * kd = KeyDerivationFactory::create(gOpt.getKdPrf()); + KeyDerivation * kd = KeyDerivationFactory::create(gOpt.getKdPrf(), gOpt.getAnytun02Compat()); kd->init(gOpt.getKey(), gOpt.getSalt(), gOpt.getPassphrase()); kd->setLogKDRate(gOpt.getLdKdr()); cLog.msg(Log::PRIO_NOTICE) << "added connection remote host " << remote_end; @@ -143,7 +143,7 @@ void sender(void* p) { ThreadParam* param = reinterpret_cast(p); - std::auto_ptr c(CipherFactory::create(gOpt.getCipher(), KD_OUTBOUND)); + std::auto_ptr c(CipherFactory::create(gOpt.getCipher(), KD_OUTBOUND, gOpt.getAnytun02Compat())); std::auto_ptr a(AuthAlgoFactory::create(gOpt.getAuthAlgo(), KD_OUTBOUND) ); PlainPacket plain_packet(MAX_PACKET_LENGTH); @@ -225,8 +225,8 @@ void receiver(void* p) { ThreadParam* param = reinterpret_cast(p); - std::auto_ptr c( CipherFactory::create(gOpt.getCipher(), KD_INBOUND) ); - std::auto_ptr a( AuthAlgoFactory::create(gOpt.getAuthAlgo(), KD_INBOUND) ); + std::auto_ptr c(CipherFactory::create(gOpt.getCipher(), KD_INBOUND, gOpt.getAnytun02Compat())); + std::auto_ptr a(AuthAlgoFactory::create(gOpt.getAuthAlgo(), KD_INBOUND)); EncryptedPacket encrypted_packet(MAX_PACKET_LENGTH); PlainPacket plain_packet(MAX_PACKET_LENGTH); @@ -352,6 +352,9 @@ int main(int argc, char* argv[]) #endif #ifndef NO_CRYPT + if(gOpt.getAnytun02Compat()) + cLog.msg(Log::PRIO_NOTICE) << "enabling anytun 0.2.x crypto compatiblity mode"; + #ifndef USE_SSL_CRYPTO // this must be called before any other libgcrypt call if(!initLibGCrypt()) diff --git a/src/cipher.cpp b/src/cipher.cpp index 46865ab..e14860c 100644 --- a/src/cipher.cpp +++ b/src/cipher.cpp @@ -78,11 +78,22 @@ AesIcmCipher::AesIcmCipher(kd_dir_t d) : Cipher(d), key_(u_int32_t(DEFAULT_KEY_L init(); } + +AesIcmCipher::AesIcmCipher(kd_dir_t d, bool a) : Cipher(d, a), key_(u_int32_t(DEFAULT_KEY_LENGTH/8)), salt_(u_int32_t(SALT_LENGTH)) +{ + init(); +} + AesIcmCipher::AesIcmCipher(kd_dir_t d, u_int16_t key_length) : Cipher(d), key_(u_int32_t(key_length/8)), salt_(u_int32_t(SALT_LENGTH)) { init(key_length); } +AesIcmCipher::AesIcmCipher(kd_dir_t d, bool a, u_int16_t key_length) : Cipher(d, a), key_(u_int32_t(key_length/8)), salt_(u_int32_t(SALT_LENGTH)) +{ + init(key_length); +} + void AesIcmCipher::init(u_int16_t key_length) { #ifndef USE_SSL_CRYPTO @@ -130,10 +141,11 @@ void AesIcmCipher::calcCtr(KeyDerivation& kd, seq_nr_t seq_nr, sender_id_t sende { kd.generate(dir_, LABEL_SATP_SALT, seq_nr, salt_); -#ifdef ANYTUN_02_COMPAT - if(!salt_[u_int32_t(0)]) - salt_[u_int32_t(0)] = 1; -#endif + + if(anytun02_compat_) { + if(!salt_[u_int32_t(0)]) + salt_[u_int32_t(0)] = 1; + } std::memcpy(ctr_.salt_.buf_, salt_.getBuf(), SALT_LENGTH); ctr_.salt_.zero_ = 0; diff --git a/src/cipher.h b/src/cipher.h index 628e6e7..7ea8166 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -49,8 +49,10 @@ class Cipher { public: - Cipher() : dir_(KD_INBOUND) {}; - Cipher(kd_dir_t d) : dir_(d) {}; + Cipher() : dir_(KD_INBOUND), anytun02_compat_(false) {}; + Cipher(kd_dir_t d) : dir_(d), anytun02_compat_(false) {}; + Cipher(bool a) : dir_(KD_INBOUND), anytun02_compat_(a) {}; + Cipher(kd_dir_t d, bool a) : dir_(d), anytun02_compat_(a) {}; virtual ~Cipher() {}; void encrypt(KeyDerivation& kd, PlainPacket & in, EncryptedPacket & out, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux); @@ -61,6 +63,7 @@ protected: virtual u_int32_t decipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux) = 0; kd_dir_t dir_; + bool anytun02_compat_; }; //****** NullCipher ****** @@ -79,7 +82,9 @@ class AesIcmCipher : public Cipher { public: AesIcmCipher(kd_dir_t d); + AesIcmCipher(kd_dir_t d, bool a); AesIcmCipher(kd_dir_t d, u_int16_t key_length); + AesIcmCipher(kd_dir_t d, bool a, u_int16_t key_length); ~AesIcmCipher(); static const u_int16_t DEFAULT_KEY_LENGTH = 128; diff --git a/src/cipherFactory.cpp b/src/cipherFactory.cpp index e53620e..f6f383b 100644 --- a/src/cipherFactory.cpp +++ b/src/cipherFactory.cpp @@ -36,19 +36,19 @@ #include "cipher.h" -Cipher* CipherFactory::create(std::string const& type, kd_dir_t dir) +Cipher* CipherFactory::create(std::string const& type, kd_dir_t dir, bool anytun02_compat) { if( type == "null" ) return new NullCipher(); #ifndef NO_CRYPT else if( type == "aes-ctr" ) - return new AesIcmCipher(dir); + return new AesIcmCipher(dir, anytun02_compat); else if( type == "aes-ctr-128" ) - return new AesIcmCipher(dir, 128); + return new AesIcmCipher(dir, anytun02_compat, 128); else if( type == "aes-ctr-192" ) - return new AesIcmCipher(dir, 192); + return new AesIcmCipher(dir, anytun02_compat, 192); else if( type == "aes-ctr-256" ) - return new AesIcmCipher(dir, 256); + return new AesIcmCipher(dir, anytun02_compat, 256); #endif else throw std::invalid_argument("cipher not available"); diff --git a/src/cipherFactory.h b/src/cipherFactory.h index 23d3b92..91fc2fd 100644 --- a/src/cipherFactory.h +++ b/src/cipherFactory.h @@ -40,7 +40,7 @@ class CipherFactory { public: - static Cipher* create(std::string const& type, kd_dir_t dir); + static Cipher* create(std::string const& type, kd_dir_t dir, bool anytun02_compat=false); private: CipherFactory(); diff --git a/src/configure b/src/configure index 1e8786f..892241b 100755 --- a/src/configure +++ b/src/configure @@ -36,7 +36,6 @@ CXXFLAGS='-g -Wall -O2' LDFLAGS='-g -Wall -O2 -lboost_thread -lboost_serialization -lboost_system' CRYPTO_LIB='gcrypt' -ANYTUN_02_COMPAT=0 PASSPHRASE=1 ROUTING=1 @@ -44,7 +43,6 @@ print_usage() { echo "configure --help print this" echo " --use-ssl-crypto use ssl crypto library instead of libgcrypt" echo " --disable-crypto disable crypto at all (only NULL cipher)" - echo " --enable-anytun02-compat enable compatiblity mode for anytun 0.2.x and prior" echo " --disable-passphrase disable master key and salt passphrase" echo " --disable-routing disable built-in routing capability" } @@ -58,9 +56,6 @@ do --disable-crypto) CRYPTO_LIB='none' ;; - --enable-anytun02-compat) - ANYTUN_02_COMPAT=1 - ;; --disable-passphrase) PASSPHRASE=0 ;; @@ -116,11 +111,6 @@ case $CRYPTO_LIB in ;; esac -if [ $ANYTUN_02_COMPAT -eq 1 ]; then - CXXFLAGS=$CXXFLAGS' -DANYTUN_02_COMPAT' - echo "enabling anytun 0.2.x crypto compatiblity mode" -fi - if [ $PASSPHRASE -eq 0 ]; then CXXFLAGS=$CXXFLAGS' -DNO_PASSPHRASE' echo "disabling master key and salt passphrase" diff --git a/src/connectionList.cpp b/src/connectionList.cpp index d6b373f..dd3fa6c 100644 --- a/src/connectionList.cpp +++ b/src/connectionList.cpp @@ -128,7 +128,7 @@ ConnectionParam & ConnectionList::getOrNewConnectionUnlocked(u_int16_t mux) SeqWindow * seq= new SeqWindow(0); seq_nr_t seq_nr_=0; - KeyDerivation * kd = KeyDerivationFactory::create(gOpt.getKdPrf()); + KeyDerivation * kd = KeyDerivationFactory::create(gOpt.getKdPrf(), gOpt.getAnytun02Compat()); kd->init(Buffer(key, sizeof(key)), Buffer(salt, sizeof(salt))); ConnectionParam conn ( (*kd), (*seq), seq_nr_, PacketSourceEndpoint()); connections_.insert(ConnectionMap::value_type(mux, conn)); diff --git a/src/keyDerivation.cpp b/src/keyDerivation.cpp index db8cc1b..bfdef3f 100644 --- a/src/keyDerivation.cpp +++ b/src/keyDerivation.cpp @@ -138,6 +138,14 @@ AesIcmKeyDerivation::AesIcmKeyDerivation() : KeyDerivation(DEFAULT_KEY_LENGTH) #endif } +AesIcmKeyDerivation::AesIcmKeyDerivation(bool a) : KeyDerivation(a, DEFAULT_KEY_LENGTH) +{ +#ifndef USE_SSL_CRYPTO + for(int i=0; i<2; i++) + handle_[i] = NULL; +#endif +} + AesIcmKeyDerivation::AesIcmKeyDerivation(u_int16_t key_length) : KeyDerivation(key_length) { #ifndef USE_SSL_CRYPTO @@ -146,6 +154,14 @@ AesIcmKeyDerivation::AesIcmKeyDerivation(u_int16_t key_length) : KeyDerivation(k #endif } +AesIcmKeyDerivation::AesIcmKeyDerivation(bool a, u_int16_t key_length) : KeyDerivation(a, key_length) +{ +#ifndef USE_SSL_CRYPTO + for(int i=0; i<2; i++) + handle_[i] = NULL; +#endif +} + AesIcmKeyDerivation::~AesIcmKeyDerivation() { WritersLock lock(mutex_); @@ -257,8 +273,14 @@ bool AesIcmKeyDerivation::calcCtr(kd_dir_t dir, seq_nr_t* r, satp_prf_label_t la } memcpy(ctr_[dir].salt_.buf_, master_salt_.getBuf(), SALT_LENGTH); ctr_[dir].salt_.zero_ = 0; - ctr_[dir].params_.label_ ^= label; - ctr_[dir].params_.r_ ^= SEQ_NR_T_HTON(*r); + if(anytun02_compat_) { + ctr_[dir].params_compat_.label_ ^= label; + ctr_[dir].params_compat_.r_ ^= SEQ_NR_T_HTON(*r); + } + else { + ctr_[dir].params_.label_ ^= label; + ctr_[dir].params_.r_ ^= SEQ_NR_T_HTON(*r); + } return true; } diff --git a/src/keyDerivation.h b/src/keyDerivation.h index ea5f359..5b40a70 100644 --- a/src/keyDerivation.h +++ b/src/keyDerivation.h @@ -67,8 +67,10 @@ typedef struct { class KeyDerivation { public: - KeyDerivation() : is_initialized_(false), ld_kdr_(0), key_length_(0), master_salt_(0), master_key_(0) {}; - KeyDerivation(u_int16_t key_length) : is_initialized_(false), ld_kdr_(0), key_length_(key_length), master_salt_(0), master_key_(0) {}; + KeyDerivation() : is_initialized_(false), ld_kdr_(0), anytun02_compat_(false), key_length_(0), master_salt_(0), master_key_(0) {}; + KeyDerivation(bool a) : is_initialized_(false), ld_kdr_(0), anytun02_compat_(a), key_length_(0), master_salt_(0), master_key_(0) {}; + KeyDerivation(u_int16_t key_length) : is_initialized_(false), ld_kdr_(0), anytun02_compat_(false), key_length_(key_length), master_salt_(0), master_key_(0) {}; + KeyDerivation(bool a, u_int16_t key_length) : is_initialized_(false), ld_kdr_(0), anytun02_compat_(a), key_length_(key_length), master_salt_(0), master_key_(0) {}; virtual ~KeyDerivation() {}; void setLogKDRate(const int8_t ld_rate); @@ -101,6 +103,7 @@ protected: bool is_initialized_; int8_t ld_kdr_; // ld(key_derivation_rate) + bool anytun02_compat_; u_int16_t key_length_; SyncBuffer master_salt_; SyncBuffer master_key_; @@ -142,7 +145,9 @@ class AesIcmKeyDerivation : public KeyDerivation { public: AesIcmKeyDerivation(); + AesIcmKeyDerivation(bool a); AesIcmKeyDerivation(u_int16_t key_length); + AesIcmKeyDerivation(bool a, u_int16_t key_length); ~AesIcmKeyDerivation(); static const u_int16_t DEFAULT_KEY_LENGTH = 128; @@ -184,14 +189,12 @@ private: u_int8_t buf_[SALT_LENGTH]; u_int16_t zero_; } salt_; -#ifndef ANYTUN_02_COMPAT struct ATTR_PACKED { u_int8_t fill_[SALT_LENGTH - sizeof(u_int8_t) - sizeof(seq_nr_t)]; u_int8_t label_; seq_nr_t r_; u_int16_t zero_; - } params_; -#else + } params_compat_; struct ATTR_PACKED { u_int8_t fill_[SALT_LENGTH - sizeof(u_int8_t) - 2 - sizeof(seq_nr_t)]; u_int8_t label_; @@ -199,7 +202,6 @@ private: seq_nr_t r_; u_int16_t zero_; } params_; -#endif } ctr_[2]; #ifdef _MSC_VER #pragma pack(pop) diff --git a/src/keyDerivationFactory.cpp b/src/keyDerivationFactory.cpp index c241b37..2f91196 100644 --- a/src/keyDerivationFactory.cpp +++ b/src/keyDerivationFactory.cpp @@ -36,19 +36,19 @@ #include "keyDerivation.h" -KeyDerivation* KeyDerivationFactory::create(std::string const& type) +KeyDerivation* KeyDerivationFactory::create(std::string const& type, bool anytun02_compat) { if( type == "null" ) return new NullKeyDerivation(); #ifndef NO_CRYPT else if( type == "aes-ctr" ) - return new AesIcmKeyDerivation(); + return new AesIcmKeyDerivation(anytun02_compat); else if( type == "aes-ctr-128" ) - return new AesIcmKeyDerivation(128); + return new AesIcmKeyDerivation(anytun02_compat, 128); else if( type == "aes-ctr-192" ) - return new AesIcmKeyDerivation(192); + return new AesIcmKeyDerivation(anytun02_compat, 192); else if( type == "aes-ctr-256" ) - return new AesIcmKeyDerivation(256); + return new AesIcmKeyDerivation(anytun02_compat, 256); #endif else throw std::invalid_argument("key derivation prf not available"); diff --git a/src/keyDerivationFactory.h b/src/keyDerivationFactory.h index 77caf58..17f0c69 100644 --- a/src/keyDerivationFactory.h +++ b/src/keyDerivationFactory.h @@ -40,7 +40,7 @@ class KeyDerivationFactory { public: - static KeyDerivation* create(std::string const& type); + static KeyDerivation* create(std::string const& type, bool anytun02_compat=false); private: KeyDerivationFactory(); diff --git a/src/options.cpp b/src/options.cpp index 8d4240b..f7bacf4 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -183,6 +183,7 @@ Options::Options() : key_(u_int32_t(0)), salt_(u_int32_t(0)) kd_prf_ = "null"; #endif ld_kdr_ = 0; + anytun02_compat_ = false; } Options::~Options() @@ -373,6 +374,7 @@ bool Options::parse(int argc, char* argv[]) #ifndef NO_CRYPT PARSE_SCALAR_PARAM("-k","--kd-prf", kd_prf_) // PARSE_SIGNED_INT_PARAM("-l","--ld-kdr", ld_kdr_tmp) + PARSE_BOOL_PARAM("-O","--anytun02-compat", anytun02_compat_) #ifndef NO_PASSPHRASE PARSE_PHRASE_PARAM_SEC("-E","--passphrase", passphrase_) #endif @@ -479,6 +481,7 @@ void Options::printUsage() #ifndef NO_CRYPT std::cout << " [-k|--kd-prf] key derivation pseudo random function" << std::endl; // std::cout << " [-l|--ld-kdr] log2 of key derivation rate" << std::endl; + std::cout << " [-O|--anytun02-compat] enable compatiblity mode for anytun 0.2.x and prior" << std::endl; #ifndef NO_PASSPHRASE std::cout << " [-E|--passphrase] a passprhase to generate master key and salt from" << std::endl; #endif @@ -541,6 +544,7 @@ void Options::printOptions() std::cout << "auth_algo = '" << auth_algo_ << "'" << std::endl; std::cout << "kd_prf = '" << kd_prf_ << "'" << std::endl; std::cout << "ld_kdr = " << static_cast(ld_kdr_) << std::endl; + std::cout << "anytun02_compat = " << anytun02_compat_ << std::endl; std::cout << "passphrase = '" << passphrase_ << "'" << std::endl; std::cout << "key = " << key_.getHexDumpOneLine() << std::endl; std::cout << "salt = " << salt_.getHexDumpOneLine() << std::endl; @@ -908,6 +912,19 @@ Options& Options::setLdKdr(int8_t l) return *this; } +bool Options::getAnytun02Compat() +{ + ReadersLock lock(mutex); + return anytun02_compat_; +} + +Options& Options::setAnytun02Compat(bool a) +{ + WritersLock lock(mutex); + anytun02_compat_ = a; + return *this; +} + std::string Options::getPassphrase() { ReadersLock lock(mutex); diff --git a/src/options.h b/src/options.h index 9d07c84..17da8a4 100644 --- a/src/options.h +++ b/src/options.h @@ -144,6 +144,8 @@ public: Options& setKdPrf(std::string k); int8_t getLdKdr(); Options& setLdKdr(int8_t l); + bool getAnytun02Compat(); + Options& setAnytun02Compat(bool a); std::string getPassphrase(); Options& setPassphrase(std::string p); Options& setKey(std::string k); @@ -200,6 +202,7 @@ private: std::string auth_algo_; std::string kd_prf_; int8_t ld_kdr_; + bool anytun02_compat_; std::string passphrase_; Buffer key_; Buffer salt_; -- cgit v1.2.3