X-Git-Url: https://git.syn-net.org/debian/?p=anytun.git;a=blobdiff_plain;f=src%2FkeyDerivation.cpp;h=780a51c1854aed6fbc3a29cd7b8461284079832a;hp=17d2a7cd51c8a07ae9190cbd80e982bb9a410098;hb=65944fb7a518dc659bacaf80cf235a0352fc6a7e;hpb=ef0cacf2508418915d3f64b04003be3c13fed3cc diff --git a/src/keyDerivation.cpp b/src/keyDerivation.cpp index 17d2a7c..780a51c 100644 --- a/src/keyDerivation.cpp +++ b/src/keyDerivation.cpp @@ -6,12 +6,12 @@ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel * mode and allows tunneling of every ETHER TYPE protocol (e.g. * ethernet, ip, arp ...). satp directly includes cryptography and - * message authentication based on the methodes used by SRTP. It is + * message authentication based on the methods used by SRTP. It is * intended to deliver a generic, scaleable and secure solution for * tunneling and relaying of packets of any protocol. * * - * Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl, + * Copyright (C) 2007-2014 Markus Grüneis, Othmar Gsenger, Erwin Nindl, * Christian Pointner * * This file is part of Anytun. @@ -27,7 +27,20 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with anytun. If not, see . + * along with Anytun. If not, see . + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. */ @@ -46,9 +59,15 @@ #ifndef NO_CRYPT #ifndef NO_PASSPHRASE -#ifdef USE_SSL_CRYPTO + +#if defined(USE_SSL_CRYPTO) #include +#elif defined(USE_NETTLE) +#include +#include +#include #endif + #endif #endif @@ -69,21 +88,29 @@ void KeyDerivation::calcMasterKey(std::string passphrase, uint16_t length) return; } -#ifndef USE_SSL_CRYPTO - if(length > gcry_md_get_algo_dlen(GCRY_MD_SHA256)) { -#else +#if defined(USE_SSL_CRYPTO) if(length > SHA256_DIGEST_LENGTH) { +#elif defined(USE_NETTLE) + if(length > SHA256_DIGEST_SIZE) { +#else // USE_GCRYPT is the default + if(length > gcry_md_get_algo_dlen(GCRY_MD_SHA256)) { #endif cLog.msg(Log::PRIO_ERROR) << "KeyDerivation: master key too long for passphrase algorithm"; return; } -#ifndef USE_SSL_CRYPTO - Buffer digest(static_cast(gcry_md_get_algo_dlen(GCRY_MD_SHA256))); - gcry_md_hash_buffer(GCRY_MD_SHA256, digest.getBuf(), passphrase.c_str(), passphrase.length()); -#else +#if defined(USE_SSL_CRYPTO) Buffer digest(uint32_t(SHA256_DIGEST_LENGTH)); SHA256(reinterpret_cast(passphrase.c_str()), passphrase.length(), digest.getBuf()); +#elif defined(USE_NETTLE) + Buffer digest(uint32_t(SHA256_DIGEST_SIZE)); + struct sha256_ctx ctx; + sha256_init(&ctx); + sha256_update(&ctx, passphrase.length(), reinterpret_cast(passphrase.c_str())); + sha256_digest(&ctx, digest.getLength(), digest.getBuf()); +#else // USE_GCRYPT is the default + Buffer digest(static_cast(gcry_md_get_algo_dlen(GCRY_MD_SHA256))); + gcry_md_hash_buffer(GCRY_MD_SHA256, digest.getBuf(), passphrase.c_str(), passphrase.length()); #endif master_key_.setLength(length); @@ -98,21 +125,29 @@ void KeyDerivation::calcMasterSalt(std::string passphrase, uint16_t length) return; } -#ifndef USE_SSL_CRYPTO - if(length > gcry_md_get_algo_dlen(GCRY_MD_SHA1)) { -#else +#if defined(USE_SSL_CRYPTO) if(length > SHA_DIGEST_LENGTH) { +#elif defined(USE_NETTLE) + if(length > SHA1_DIGEST_SIZE) { +#else // USE_GCRYPT is the default + if(length > gcry_md_get_algo_dlen(GCRY_MD_SHA1)) { #endif cLog.msg(Log::PRIO_ERROR) << "KeyDerivation: master key too long for passphrase algorithm"; return; } -#ifndef USE_SSL_CRYPTO - Buffer digest(static_cast(gcry_md_get_algo_dlen(GCRY_MD_SHA1))); - gcry_md_hash_buffer(GCRY_MD_SHA1, digest.getBuf(), passphrase.c_str(), passphrase.length()); -#else +#if defined(USE_SSL_CRYPTO) Buffer digest(uint32_t(SHA_DIGEST_LENGTH)); SHA1(reinterpret_cast(passphrase.c_str()), passphrase.length(), digest.getBuf()); +#elif defined(USE_NETTLE) + Buffer digest(uint32_t(SHA1_DIGEST_SIZE)); + struct sha1_ctx ctx; + sha1_init(&ctx); + sha1_update(&ctx, passphrase.length(), reinterpret_cast(passphrase.c_str())); + sha1_digest(&ctx, digest.getLength(), digest.getBuf()); +#else // USE_GCRYPT is the default + Buffer digest(static_cast(gcry_md_get_algo_dlen(GCRY_MD_SHA1))); + gcry_md_hash_buffer(GCRY_MD_SHA1, digest.getBuf(), passphrase.c_str(), passphrase.length()); #endif master_salt_.setLength(length); @@ -172,7 +207,7 @@ bool NullKeyDerivation::generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t AesIcmKeyDerivation::AesIcmKeyDerivation() : KeyDerivation(DEFAULT_KEY_LENGTH) { -#ifndef USE_SSL_CRYPTO +#if defined(USE_GCRYPT) for(int i=0; i<2; i++) { handle_[i] = NULL; } @@ -181,7 +216,7 @@ AesIcmKeyDerivation::AesIcmKeyDerivation() : KeyDerivation(DEFAULT_KEY_LENGTH) AesIcmKeyDerivation::AesIcmKeyDerivation(uint16_t key_length) : KeyDerivation(key_length) { -#ifndef USE_SSL_CRYPTO +#if defined(USE_GCRYPT) for(int i=0; i<2; i++) { handle_[i] = NULL; } @@ -191,7 +226,7 @@ AesIcmKeyDerivation::AesIcmKeyDerivation(uint16_t key_length) : KeyDerivation(ke AesIcmKeyDerivation::~AesIcmKeyDerivation() { WritersLock lock(mutex_); -#ifndef USE_SSL_CRYPTO +#if defined(USE_GCRYPT) for(int i=0; i<2; i++) if(handle_[i]) { gcry_cipher_close(handle_[i]); @@ -236,7 +271,19 @@ void AesIcmKeyDerivation::updateMasterKey() return; } -#ifndef USE_SSL_CRYPTO +#if defined(USE_SSL_CRYPTO) + for(int i=0; i<2; i++) { + int ret = AES_set_encrypt_key(master_key_.getBuf(), master_key_.getLength()*8, &aes_key_[i]); + if(ret) { + cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: Failed to set ssl key (code: " << ret << ")"; + return; + } + } +#elif defined(USE_NETTLE) + for(int i=0; i<2; i++) { + aes_set_encrypt_key(&(ctx_[i]), master_key_.getLength(), master_key_.getBuf()); + } +#else // USE_GCRYPT is the default int algo; switch(key_length_) { case 128: @@ -271,14 +318,6 @@ void AesIcmKeyDerivation::updateMasterKey() return; } } -#else - for(int i=0; i<2; i++) { - int ret = AES_set_encrypt_key(master_key_.getBuf(), master_key_.getLength()*8, &aes_key_[i]); - if(ret) { - cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: Failed to set ssl key (code: " << ret << ")"; - return; - } - } #endif is_initialized_ = true; } @@ -318,7 +357,23 @@ bool AesIcmKeyDerivation::generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_ return false; } -#ifndef USE_SSL_CRYPTO +#if defined(USE_SSL_CRYPTO) + if(CTR_LENGTH != AES_BLOCK_SIZE) { + cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher: Failed to set cipher CTR: size doesn't fit"; + return false; + } + unsigned int num = 0; + std::memset(ecount_buf_[dir], 0, AES_BLOCK_SIZE); + std::memset(key.getBuf(), 0, key.getLength()); + AES_ctr128_encrypt(key.getBuf(), key.getBuf(), key.getLength(), &aes_key_[dir], ctr_[dir].buf_, ecount_buf_[dir], &num); +#elif defined(USE_NETTLE) + if(CTR_LENGTH != AES_BLOCK_SIZE) { + cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher: Failed to set cipher CTR: size doesn't fit"; + return false; + } + std::memset(key.getBuf(), 0, key.getLength()); + ctr_crypt(&(ctx_[dir]), (nettle_crypt_func *)(aes_encrypt), AES_BLOCK_SIZE, ctr_[dir].buf_, key.getLength(), key.getBuf(), key.getBuf()); +#else // USE_GCRYPT is the default gcry_error_t err = gcry_cipher_reset(handle_[dir]); if(err) { cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::generate: Failed to reset cipher: " << AnytunGpgError(err); @@ -335,15 +390,6 @@ bool AesIcmKeyDerivation::generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_ if(err) { cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::generate: Failed to generate cipher bitstream: " << AnytunGpgError(err); } -#else - if(CTR_LENGTH != AES_BLOCK_SIZE) { - cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher: Failed to set cipher CTR: size don't fits"; - return false; - } - unsigned int num = 0; - std::memset(ecount_buf_[dir], 0, AES_BLOCK_SIZE); - std::memset(key.getBuf(), 0, key.getLength()); - AES_ctr128_encrypt(key.getBuf(), key.getBuf(), key.getLength(), &aes_key_[dir], ctr_[dir].buf_, ecount_buf_[dir], &num); #endif return true;