From f6d182bc21651b2040577754471db2d1870b54c0 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Sun, 18 Jan 2009 02:06:11 +0000 Subject: added passphrase support to key derivation --- src/anytun.cpp | 2 +- src/keyDerivation.cpp | 82 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/keyDerivation.h | 11 +++++-- src/options.cpp | 53 ++++++++++++++++++++++++++++----- src/options.h | 3 ++ 5 files changed, 136 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/anytun.cpp b/src/anytun.cpp index 06113b2..a2d7f05 100644 --- a/src/anytun.cpp +++ b/src/anytun.cpp @@ -82,7 +82,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()); - kd->init(gOpt.getKey(), gOpt.getSalt()); + kd->init(gOpt.getKey(), gOpt.getSalt(), gOpt.getPassphrase()); kd->setLogKDRate(gOpt.getLdKdr()); cLog.msg(Log::PRIO_NOTICE) << "added connection remote host " << remote_end; diff --git a/src/keyDerivation.cpp b/src/keyDerivation.cpp index dbe5dee..48db034 100644 --- a/src/keyDerivation.cpp +++ b/src/keyDerivation.cpp @@ -41,6 +41,10 @@ #include #include +#ifdef USE_SSL_CRYPTO +#include +#endif + void KeyDerivation::setLogKDRate(const int8_t log_rate) { WritersLock lock(mutex_); @@ -49,6 +53,66 @@ void KeyDerivation::setLogKDRate(const int8_t log_rate) ld_kdr_ = sizeof(seq_nr_t) * 8; } +#ifndef NO_PASSPHRASE +void KeyDerivation::calcMasterKey(std::string passphrase, u_int16_t length) +{ + cLog.msg(Log::PRIO_NOTICE) << "KeyDerivation: calculating master key from passphrase"; + if(!length) { + cLog.msg(Log::PRIO_ERR) << "KeyDerivation: bad master key length"; + return; + } + +#ifndef USE_SSL_CRYPTO + if(length > gcry_md_get_algo_dlen(GCRY_MD_SHA256)) { +#else + if(length > SHA256_DIGEST_LENGTH) { +#endif + cLog.msg(Log::PRIO_ERR) << "KeyDerivation: master key too long for passphrase algorithm"; + return; + } + +#ifndef USE_SSL_CRYPTO + Buffer digest(gcry_md_get_algo_dlen(GCRY_MD_SHA256)); + gcry_md_hash_buffer(GCRY_MD_SHA256, digest.getBuf(), passphrase.c_str(), passphrase.length()); +#else + Buffer digest(u_int32_t(SHA256_DIGEST_LENGTH)); + SHA256(reinterpret_cast(passphrase.c_str()), passphrase.length(), digest.getBuf()); +#endif + master_key_.setLength(length); + + memcpy(master_key_.getBuf(), &digest.getBuf()[digest.getLength() - master_key_.getLength()], master_key_.getLength()); +} + +void KeyDerivation::calcMasterSalt(std::string passphrase, u_int16_t length) +{ + cLog.msg(Log::PRIO_NOTICE) << "KeyDerivation: calculating master salt from passphrase"; + if(!length) { + cLog.msg(Log::PRIO_ERR) << "KeyDerivation: bad master salt length"; + return; + } + +#ifndef USE_SSL_CRYPTO + if(length > gcry_md_get_algo_dlen(GCRY_MD_SHA1)) { +#else + if(length > SHA_DIGEST_LENGTH) { +#endif + cLog.msg(Log::PRIO_ERR) << "KeyDerivation: master key too long for passphrase algorithm"; + return; + } + +#ifndef USE_SSL_CRYPTO + Buffer digest(gcry_md_get_algo_dlen(GCRY_MD_SHA1)); + gcry_md_hash_buffer(GCRY_MD_SHA1, digest.getBuf(), passphrase.c_str(), passphrase.length()); +#else + Buffer digest(u_int32_t(SHA_DIGEST_LENGTH)); + SHA1(reinterpret_cast(passphrase.c_str()), passphrase.length(), digest.getBuf()); +#endif + master_salt_.setLength(length); + + memcpy(master_salt_.getBuf(), &digest.getBuf()[digest.getLength() - master_salt_.getLength()], master_salt_.getLength()); +} +#endif + //****** NullKeyDerivation ****** bool NullKeyDerivation::generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key) @@ -86,13 +150,25 @@ AesIcmKeyDerivation::~AesIcmKeyDerivation() #endif } -void AesIcmKeyDerivation::init(Buffer key, Buffer salt) +void AesIcmKeyDerivation::init(Buffer key, Buffer salt, std::string passphrase) { WritersLock lock(mutex_); - + is_initialized_ = false; - master_salt_ = SyncBuffer(salt); +#ifndef NO_PASSPHRASE + if(passphrase != "" && !key.getLength()) + calcMasterKey(passphrase, key_length_/8); + else + master_key_ = SyncBuffer(key); + + if(passphrase != "" && !salt.getLength()) + calcMasterSalt(passphrase, SALT_LENGTH); + else + master_salt_ = SyncBuffer(salt); +#else master_key_ = SyncBuffer(key); + master_salt_ = SyncBuffer(salt); +#endif updateMasterKey(); } diff --git a/src/keyDerivation.h b/src/keyDerivation.h index 926d35f..518a498 100644 --- a/src/keyDerivation.h +++ b/src/keyDerivation.h @@ -73,7 +73,7 @@ public: void setLogKDRate(const int8_t ld_rate); - virtual void init(Buffer key, Buffer salt) = 0; + virtual void init(Buffer key, Buffer salt, std::string passphrase = "") = 0; virtual bool generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key) = 0; virtual std::string printType() { return "GenericKeyDerivation"; }; @@ -81,6 +81,11 @@ public: protected: virtual void updateMasterKey() = 0; +#ifndef NO_PASSPHRASE + void calcMasterKey(std::string passphrase, u_int16_t length); + void calcMasterSalt(std::string passphrase, u_int16_t length); +#endif + KeyDerivation(const KeyDerivation & src); friend class boost::serialization::access; template @@ -113,7 +118,7 @@ public: NullKeyDerivation() {}; ~NullKeyDerivation() {}; - void init(Buffer key, Buffer salt) {}; + void init(Buffer key, Buffer salt, std::string passphrase = "") {}; bool generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key); std::string printType() { return "NullKeyDerivation"; }; @@ -144,7 +149,7 @@ public: static const u_int16_t CTR_LENGTH = 16; static const u_int16_t SALT_LENGTH = 14; - void init(Buffer key, Buffer salt); + void init(Buffer key, Buffer salt, std::string passphrase = ""); bool generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key); std::string printType(); diff --git a/src/options.cpp b/src/options.cpp index 40182c4..d241eae 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -238,6 +238,26 @@ Options::~Options() i+=2; \ } +#define PARSE_CSLIST_PARAM(SHORT, LONG, LIST, TYPE) \ + else if(str == SHORT || str == LONG) \ + { \ + if(argc < 1) \ + throw syntax_error(str, str.length()); \ + if(argv[i+1][0] == '-') { \ + u_int32_t pos = str.length() + 1; \ + throw syntax_error(str.append(" ").append(argv[i+1]), pos); \ + } \ + std::stringstream tmp(argv[i+1]); \ + while (tmp.good()) \ + { \ + std::string tmp_line; \ + getline(tmp,tmp_line,','); \ + LIST.push_back(TYPE(tmp_line)); \ + } \ + argc--; \ + i++; \ + } + #define PARSE_HEXSTRING_PARAM_SEC(SHORT, LONG, VALUE) \ else if(str == SHORT || str == LONG) \ { \ @@ -254,7 +274,7 @@ Options::~Options() i++; \ } -#define PARSE_CSLIST_PARAM(SHORT, LONG, LIST, TYPE) \ +#define PARSE_PHRASE_PARAM_SEC(SHORT, LONG, VALUE) \ else if(str == SHORT || str == LONG) \ { \ if(argc < 1) \ @@ -263,13 +283,10 @@ Options::~Options() u_int32_t pos = str.length() + 1; \ throw syntax_error(str.append(" ").append(argv[i+1]), pos); \ } \ - std::stringstream tmp(argv[i+1]); \ - while (tmp.good()) \ - { \ - std::string tmp_line; \ - getline(tmp,tmp_line,','); \ - LIST.push_back(TYPE(tmp_line)); \ - } \ + std::stringstream tmp; \ + VALUE = argv[i+1]; \ + for(size_t j=0; j < strlen(argv[i+1]); ++j) \ + argv[i+1][j] = '#'; \ argc--; \ i++; \ } @@ -320,6 +337,9 @@ bool Options::parse(int argc, char* argv[]) PARSE_SCALAR_PARAM("-a","--auth-algo", auth_algo_) PARSE_SCALAR_PARAM("-k","--kd-prf", kd_prf_) PARSE_SIGNED_INT_PARAM("-l","--ld-kdr", ld_kdr_tmp) +#ifndef NO_PASSPHRASE + PARSE_PHRASE_PARAM_SEC("-E","--passphrase", passphrase_) +#endif PARSE_HEXSTRING_PARAM_SEC("-K","--key", key_) PARSE_HEXSTRING_PARAM_SEC("-A","--salt", salt_) else @@ -380,6 +400,9 @@ void Options::printUsage() std::cout << " [-a|--auth-algo] message authentication algorithm" << std::endl; std::cout << " [-k|--kd-prf] key derivation pseudo random function" << std::endl; std::cout << " [-l|--ld-kdr] log2 of key derivation rate" << std::endl; +#ifndef NO_PASSPHRASE + std::cout << " [-E|--passphrase] a passprhase to generate master key and salt from" << std::endl; +#endif std::cout << " [-K|--key] master key to use for encryption" << std::endl; std::cout << " [-A|--salt] master salt to use for encryption" << std::endl; } @@ -429,6 +452,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 << "passphrase = '" << passphrase_ << "'" << std::endl; std::cout << "key = " << key_.getHexDumpOneLine() << std::endl; std::cout << "salt = " << salt_.getHexDumpOneLine() << std::endl; } @@ -808,6 +832,19 @@ Options& Options::setLdKdr(int8_t l) return *this; } +std::string Options::getPassphrase() +{ + ReadersLock lock(mutex); + return passphrase_; +} + +Options& Options::setPassphrase(std::string p) +{ + WritersLock lock(mutex); + passphrase_ = p; + return *this; +} + Buffer Options::getKey() { ReadersLock lock(mutex); diff --git a/src/options.h b/src/options.h index 5167878..694526e 100644 --- a/src/options.h +++ b/src/options.h @@ -146,6 +146,8 @@ public: Options& setKdPrf(std::string k); int8_t getLdKdr(); Options& setLdKdr(int8_t l); + std::string getPassphrase(); + Options& setPassphrase(std::string p); Options& setKey(std::string k); Buffer getKey(); Options& setSalt(std::string s); @@ -201,6 +203,7 @@ private: std::string auth_algo_; std::string kd_prf_; int8_t ld_kdr_; + std::string passphrase_; Buffer key_; Buffer salt_; }; -- cgit v1.2.3