X-Git-Url: https://git.syn-net.org/?p=debian%2Fuanytun.git;a=blobdiff_plain;f=src%2Fkey_derivation.c;h=f2d854862653855445e0d199ffe30efb0a3a5bb6;hp=a01695bc2158c5c6f4b18c7525771b4b3416c7f7;hb=71f6f666a3d69c6e1e7a77e238362c5bbe288e66;hpb=aa74a4fd24d8e8537f76531e6257fa90145355d3 diff --git a/src/key_derivation.c b/src/key_derivation.c index a01695b..f2d8548 100644 --- a/src/key_derivation.c +++ b/src/key_derivation.c @@ -10,12 +10,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-2010 Christian Pointner + * + * Copyright (C) 2007-2014 Christian Pointner * * This file is part of uAnytun. * @@ -31,14 +31,31 @@ * * You should have received a copy of the GNU General Public License * along with uAnytun. 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. */ #include "datatypes.h" #include "key_derivation.h" -#ifdef USE_SSL_CRYPTO +#if defined(USE_SSL_CRYPTO) #include +#elif defined(USE_NETTLE) +#include +#include +#include #endif #include "log.h" @@ -48,7 +65,7 @@ int key_derivation_init(key_derivation_t* kd, const char* type, role_t role, const char* passphrase, u_int8_t* key, u_int32_t key_len, u_int8_t* salt, u_int32_t salt_len) { - if(!kd) + if(!kd) return -1; kd->role_ = role; @@ -62,7 +79,7 @@ int key_derivation_init(key_derivation_t* kd, const char* type, role_t role, con if(type[7] == 0) { kd->key_length_ = KD_AESCTR_DEFAULT_KEY_LENGTH; } - else if(type[7] != '-') + else if(type[7] != '-') return -1; else { const char* tmp = &type[8]; @@ -127,7 +144,7 @@ int key_derivation_generate_master_key(key_derivation_t* kd, const char* passphr if(kd->master_key_.buf_) { log_printf(WARNING, "master key and passphrase provided, ignoring passphrase"); return 0; - } + } log_printf(NOTICE, "using passphrase to generate master key"); if(!key_length || (key_length % 8)) { @@ -135,30 +152,39 @@ int key_derivation_generate_master_key(key_derivation_t* kd, const char* passphr return -1; } -#ifndef USE_SSL_CRYPTO - if(key_length > (gcry_md_get_algo_dlen(GCRY_MD_SHA256) * 8)) { -#else +#if defined(USE_SSL_CRYPTO) if(key_length > (SHA256_DIGEST_LENGTH * 8)) { +#elif defined(USE_NETTLE) + if(key_length > (SHA256_DIGEST_SIZE * 8)) { +#else // USE_GCRYPT is the default + if(key_length > (gcry_md_get_algo_dlen(GCRY_MD_SHA256) * 8)) { #endif log_printf(ERROR, "master key too long for passphrase algorithm"); return -1; } buffer_t digest; -#ifndef USE_SSL_CRYPTO - digest.length_ = gcry_md_get_algo_dlen(GCRY_MD_SHA256); -#else +#if defined(USE_SSL_CRYPTO) digest.length_ = SHA256_DIGEST_LENGTH; +#elif defined(USE_NETTLE) + digest.length_ = SHA256_DIGEST_SIZE; +#else // USE_GCRYPT is the default + digest.length_ = gcry_md_get_algo_dlen(GCRY_MD_SHA256); #endif digest.buf_ = malloc(digest.length_); if(!digest.buf_) return -2; -#ifndef USE_SSL_CRYPTO +#if defined(USE_SSL_CRYPTO) + SHA256((const u_int8_t*)passphrase, strlen(passphrase), digest.buf_); +#elif defined(USE_NETTLE) + struct sha256_ctx ctx; + sha256_init(&ctx); + sha256_update(&ctx, strlen(passphrase), (const u_int8_t*)passphrase); + sha256_digest(&ctx, digest.length_, digest.buf_); +#else // USE_GCRYPT is the default gcry_md_hash_buffer(GCRY_MD_SHA256, digest.buf_, passphrase, strlen(passphrase)); -#else - SHA256(passphrase, strlen(passphrase), digest.buf_); #endif kd->master_key_.length_ = key_length/8; @@ -183,7 +209,7 @@ int key_derivation_generate_master_salt(key_derivation_t* kd, const char* passph if(kd->master_salt_.buf_) { log_printf(WARNING, "master salt and passphrase provided, ignoring passphrase"); return 0; - } + } log_printf(NOTICE, "using passphrase to generate master salt"); if(!salt_length || (salt_length % 8)) { @@ -191,29 +217,38 @@ int key_derivation_generate_master_salt(key_derivation_t* kd, const char* passph return -1; } -#ifndef USE_SSL_CRYPTO - if(salt_length > (gcry_md_get_algo_dlen(GCRY_MD_SHA1) * 8)) { -#else +#if defined(USE_SSL_CRYPTO) if(salt_length > (SHA_DIGEST_LENGTH * 8)) { +#elif defined(USE_NETTLE) + if(salt_length > (SHA1_DIGEST_SIZE * 8)) { +#else // USE_GCRYPT is the default + if(salt_length > (gcry_md_get_algo_dlen(GCRY_MD_SHA1) * 8)) { #endif log_printf(ERROR, "master salt too long for passphrase algorithm"); return -1; } buffer_t digest; -#ifndef USE_SSL_CRYPTO - digest.length_ = gcry_md_get_algo_dlen(GCRY_MD_SHA1); -#else +#if defined(USE_SSL_CRYPTO) digest.length_ = SHA_DIGEST_LENGTH; +#elif defined(USE_NETTLE) + digest.length_ = SHA1_DIGEST_SIZE; +#else // USE_GCRYPT is the default + digest.length_ = gcry_md_get_algo_dlen(GCRY_MD_SHA1); #endif digest.buf_ = malloc(digest.length_); if(!digest.buf_) return -2; -#ifndef USE_SSL_CRYPTO +#if defined(USE_SSL_CRYPTO) + SHA1((const u_int8_t*)passphrase, strlen(passphrase), digest.buf_); +#elif defined(USE_NETTLE) + struct sha1_ctx ctx; + sha1_init(&ctx); + sha1_update(&ctx, strlen(passphrase), (const u_int8_t*)passphrase); + sha1_digest(&ctx, digest.length_, digest.buf_); +#else // USE_GCRYPT is the default gcry_md_hash_buffer(GCRY_MD_SHA1, digest.buf_, passphrase, strlen(passphrase)); -#else - SHA1(passphrase, strlen(passphrase), digest.buf_); #endif kd->master_salt_.length_ = salt_length/8; @@ -247,7 +282,7 @@ void key_derivation_close(key_derivation_t* kd) int key_derivation_generate(key_derivation_t* kd, key_derivation_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, u_int8_t* key, u_int32_t len) { - if(!kd || !key) + if(!kd || !key) return -1; if(label >= LABEL_NIL) { @@ -330,7 +365,7 @@ int key_derivation_aesctr_init(key_derivation_t* kd, const char* passphrase) return -2; key_derivation_aesctr_param_t* params = kd->params_; -#ifndef USE_SSL_CRYPTO +#ifdef USE_GCRYPT params->handle_ = 0; #endif @@ -345,7 +380,15 @@ int key_derivation_aesctr_init(key_derivation_t* kd, const char* passphrase) } #endif -#ifndef USE_SSL_CRYPTO +#if defined(USE_SSL_CRYPTO) + int ret = AES_set_encrypt_key(kd->master_key_.buf_, kd->master_key_.length_*8, ¶ms->aes_key_); + if(ret) { + log_printf(ERROR, "failed to set key derivation ssl aes-key (code: %d)", ret); + return -1; + } +#elif defined(USE_NETTLE) + aes_set_encrypt_key(¶ms->ctx_, kd->master_key_.length_, kd->master_key_.buf_); +#else // USE_GCRYPT is the default int algo; switch(kd->key_length_) { case 128: algo = GCRY_CIPHER_AES128; break; @@ -361,19 +404,13 @@ int key_derivation_aesctr_init(key_derivation_t* kd, const char* passphrase) if(err) { log_printf(ERROR, "failed to open key derivation cipher: %s", gcry_strerror(err)); return -1; - } + } err = gcry_cipher_setkey(params->handle_, kd->master_key_.buf_, kd->master_key_.length_); if(err) { log_printf(ERROR, "failed to set key derivation key: %s", gcry_strerror(err)); return -1; } -#else - int ret = AES_set_encrypt_key(kd->master_key_.buf_, kd->master_key_.length_*8, ¶ms->aes_key_); - if(ret) { - log_printf(ERROR, "failed to set key derivation ssl aes-key (code: %d)", ret); - return -1; - } #endif return 0; @@ -385,9 +422,8 @@ void key_derivation_aesctr_close(key_derivation_t* kd) return; if(kd->params_) { +#ifdef USE_GCRYPT key_derivation_aesctr_param_t* params = kd->params_; - -#ifndef USE_SSL_CRYPTO if(params->handle_) gcry_cipher_close(params->handle_); #endif @@ -429,7 +465,23 @@ int key_derivation_aesctr_generate(key_derivation_t* kd, key_derivation_dir_t di return -1; } -#ifndef USE_SSL_CRYPTO +#if defined(USE_SSL_CRYPTO) + if(KD_AESCTR_CTR_LENGTH != AES_BLOCK_SIZE) { + log_printf(ERROR, "failed to set key derivation CTR: size don't fits"); + return -1; + } + u_int32_t num = 0; + memset(params->ecount_buf_, 0, AES_BLOCK_SIZE); + memset(key, 0, len); + AES_ctr128_encrypt(key, key, len, ¶ms->aes_key_, params->ctr_.buf_, params->ecount_buf_, &num); +#elif defined(USE_NETTLE) + if(KD_AESCTR_CTR_LENGTH != AES_BLOCK_SIZE) { + log_printf(ERROR, "failed to set cipher CTR: size doesn't fit"); + return -1; + } + memset(key, 0, len); + ctr_crypt(¶ms->ctx_, (nettle_crypt_func *)(aes_encrypt), AES_BLOCK_SIZE, params->ctr_.buf_, len, key, key); +#else // USE_GCRYPT is the default gcry_error_t err = gcry_cipher_reset(params->handle_); if(err) { log_printf(ERROR, "failed to reset key derivation cipher: %s", gcry_strerror(err)); @@ -448,16 +500,7 @@ int key_derivation_aesctr_generate(key_derivation_t* kd, key_derivation_dir_t di log_printf(ERROR, "failed to generate key derivation bitstream: %s", gcry_strerror(err)); return -1; } -#else - if(KD_AESCTR_CTR_LENGTH != AES_BLOCK_SIZE) { - log_printf(ERROR, "failed to set key derivation CTR: size don't fits"); - return -1; - } - u_int32_t num = 0; - memset(params->ecount_buf_, 0, AES_BLOCK_SIZE); - memset(key, 0, len); - AES_ctr128_encrypt(key, key, len, ¶ms->aes_key_, params->ctr_.buf_, params->ecount_buf_, &num); #endif - + return 0; }