From 974d6973f4479c0f5bacc0a5ce07a5cfc62bb01c Mon Sep 17 00:00:00 2001 From: Erwin Nindl Date: Wed, 12 Dec 2007 16:10:58 +0000 Subject: * renamed HmacAuthAlgo to Sha1AuthAlgo * removed a memleak at the IV generation in kd, cypher --- authAlgo.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++---------- authAlgo.h | 13 +++++++++++-- cypher.cpp | 14 ++++++++------ keyDerivation.cpp | 4 +++- mpi.cpp | 2 +- mpi.h | 20 +++++++++++++++++++- 6 files changed, 88 insertions(+), 21 deletions(-) diff --git a/authAlgo.cpp b/authAlgo.cpp index db4a16c..328a42f 100644 --- a/authAlgo.cpp +++ b/authAlgo.cpp @@ -29,10 +29,10 @@ */ #include "authAlgo.h" +#include "log.h" +#include "buffer.h" -extern "C" { #include -} AuthTag NullAuthAlgo::calc(const Buffer& buf) @@ -40,20 +40,56 @@ AuthTag NullAuthAlgo::calc(const Buffer& buf) return AuthTag(0); } +const char* Sha1AuthAlgo::MIN_GCRYPT_VERSION = "1.2.3"; // HMAC_SHA1 -AuthTag HmacAuthAlgo::calc(const Buffer& buf) +Sha1AuthAlgo::Sha1AuthAlgo() : ctx_(NULL) +{ + gcry_error_t err; + // No other library has already initialized libgcrypt. + if( !gcry_control(GCRYCTL_ANY_INITIALIZATION_P) ) + { + if( !gcry_check_version( MIN_GCRYPT_VERSION ) ) { + cLog.msg(Log::PRIO_ERR) << "Sha1AuthAlgo::Sha1AuthAlgo: Invalid Version of libgcrypt, should be >= " << MIN_GCRYPT_VERSION; + return; + } + /* Tell Libgcrypt that initialization has completed. */ + err = gcry_control(GCRYCTL_INITIALIZATION_FINISHED); + if( err ) { + cLog.msg(Log::PRIO_CRIT) << "Sha1AuthAlgo::Sha1AuthAlgo: Failed to finish the initialization of libgcrypt: " << gpg_strerror( err ); + return; + } else { + cLog.msg(Log::PRIO_DEBUG) << "Sha1AuthAlgo::Sha1AuthAlgo: libgcrypt init finished"; + } + } + err = gcry_md_open( &ctx_, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC ); + if( err ) + cLog.msg(Log::PRIO_CRIT) << "Sha1AuthAlgo::Sha1AuthAlgo: Failed to open message digest algo"; +} + +Sha1AuthAlgo::~Sha1AuthAlgo() +{ + gcry_md_close( ctx_ ); + cLog.msg(Log::PRIO_DEBUG) << "Sha1AuthAlgo::~Sha1AuthAlgo: closed hmac handler"; +} + +void Sha1AuthAlgo::setKey(Buffer key) { gcry_error_t err; - gcry_md_hd_t ctx; + err = gcry_md_setkey( ctx_, key.getBuf(), key.getLength() ); + if( err ) + cLog.msg(Log::PRIO_ERR) << "Sha1AuthAlgo::setKey: Failed to set cipher key: " << gpg_strerror( err ); +} + + +AuthTag Sha1AuthAlgo::calc(const Buffer& buf) +{ + // gcry_error_t err; Buffer hmac; //80bit - err = gcry_md_open( &ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC ); - //gcry_md_setkey( ctx, key, keylen ); - gcry_md_write( ctx, static_cast(buf).getBuf(), buf.getLength() ); - gcry_md_final( ctx ); - hmac = Buffer(gcry_md_read( ctx, 0 ), 10); - gcry_md_close( ctx ); + gcry_md_write( ctx_, static_cast(buf).getBuf(), buf.getLength() ); + gcry_md_final( ctx_ ); + hmac = Buffer(gcry_md_read( ctx_, 0 ), 10); return hmac; } diff --git a/authAlgo.h b/authAlgo.h index e3de813..1a6d431 100644 --- a/authAlgo.h +++ b/authAlgo.h @@ -31,8 +31,11 @@ #ifndef _AUTHALGO_H_ #define _AUTHALGO_H_ -#include "datatypes.h" #include "authTag.h" +#include "datatypes.h" +#include "buffer.h" + +#include class AuthAlgo { @@ -51,10 +54,16 @@ public: // HMAC_SHA1 -class HmacAuthAlgo : public AuthAlgo +class Sha1AuthAlgo : public AuthAlgo { public: + Sha1AuthAlgo(); + ~Sha1AuthAlgo(); + void setKey(Buffer key); AuthTag calc(const Buffer& buf); +protected: + static const char* MIN_GCRYPT_VERSION; + gcry_md_hd_t ctx_; }; #endif diff --git a/cypher.cpp b/cypher.cpp index 34a9a10..58b971c 100644 --- a/cypher.cpp +++ b/cypher.cpp @@ -65,10 +65,7 @@ Buffer NullCypher::getBitStream(u_int32_t length, seq_nr_t seq_nr, sender_id_t s return buf; } - const char* AesIcmCypher::MIN_GCRYPT_VERSION = "1.2.3"; -bool AesIcmCypher::gcrypt_initialized_ = false; - AesIcmCypher::AesIcmCypher() : salt_(Buffer(14)) { @@ -78,7 +75,7 @@ AesIcmCypher::AesIcmCypher() : salt_(Buffer(14)) if( !gcry_control(GCRYCTL_ANY_INITIALIZATION_P) ) { if( !gcry_check_version( MIN_GCRYPT_VERSION ) ) { - cLog.msg(Log::PRIO_ERR) << "Invalid Version of libgcrypt, should be >= " << MIN_GCRYPT_VERSION; + cLog.msg(Log::PRIO_ERR) << "AesIcmCypher::AesIcmCypher: Invalid Version of libgcrypt, should be >= " << MIN_GCRYPT_VERSION; return; } @@ -99,17 +96,20 @@ AesIcmCypher::AesIcmCypher() : salt_(Buffer(14)) cLog.msg(Log::PRIO_CRIT) << "AesIcmCypher::AesIcmCypher: Failed to finish the initialization of libgcrypt: " << gpg_strerror( err ); return; } else { - cLog.msg(Log::PRIO_NOTICE) << "AesIcmCypher::AesIcmCypher: libgcrypt init finished"; + cLog.msg(Log::PRIO_DEBUG) << "AesIcmCypher::AesIcmCypher: libgcrypt init finished"; } } gcry_cipher_open( &cipher_, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR, 0 ); + if( err ) + cLog.msg(Log::PRIO_CRIT) << "AesIcmCypher::AesIcmCypher: Failed to open cypher"; } AesIcmCypher::~AesIcmCypher() { gcry_cipher_close( cipher_ ); + cLog.msg(Log::PRIO_DEBUG) << "AesIcmCypher::~AesIcmCypher: closed cipher"; } @@ -147,7 +147,9 @@ Buffer AesIcmCypher::getBitStream(u_int32_t length, seq_nr_t seq_nr, sender_id_t iv = salt.mul2exp(16) ^ sid.mul2exp(64) ^ seq.mul2exp(16); - err = gcry_cipher_setiv( cipher_, iv.getBuf(16), 16 ); + u_int8_t *iv_buf = iv.getNewBuf(16); + err = gcry_cipher_setiv( cipher_, iv_buf, 16 ); + delete[] iv_buf; if( err ) { cLog.msg(Log::PRIO_ERR) << "AesIcmCypher: Failed to set cipher IV: " << gpg_strerror( err ); return Buffer(0); diff --git a/keyDerivation.cpp b/keyDerivation.cpp index 4ed87ad..dbef123 100644 --- a/keyDerivation.cpp +++ b/keyDerivation.cpp @@ -133,7 +133,9 @@ void KeyDerivation::generate(satp_prf_label label, seq_nr_t seq_nr, Buffer& key, if( err ) cLog.msg(Log::PRIO_ERR) << "KeyDerivation::generate: Failed to reset cipher: " << gpg_strerror( err ); - err = gcry_cipher_setiv( cipher_ , iv.getBuf(16), 16); + u_int8_t *iv_buf = iv.getNewBuf(16); + err = gcry_cipher_setiv( cipher_ , iv_buf, 16); + delete[] iv_buf; if( err ) cLog.msg(Log::PRIO_ERR) << "KeyDerivation::generate: Failed to set IV: " << gpg_strerror( err ); diff --git a/mpi.cpp b/mpi.cpp index afd1785..7c94b7e 100644 --- a/mpi.cpp +++ b/mpi.cpp @@ -127,7 +127,7 @@ void Mpi::clearHighBit(u_int32_t n) gcry_mpi_clear_highbit( val_, n ); } -u_int8_t* Mpi::getBuf(u_int32_t buf_len) const +u_int8_t* Mpi::getNewBuf(u_int32_t buf_len) const { // u_int32_t len = 0; u_int32_t written = 0; diff --git a/mpi.h b/mpi.h index de7aa98..2638e1d 100644 --- a/mpi.h +++ b/mpi.h @@ -37,6 +37,11 @@ #include +/** + * This class is a wrapper for the libgcrypt multi precision integer library. + * + */ + class Mpi { public: @@ -52,10 +57,23 @@ public: Mpi operator^(const Mpi &b) const; Mpi operator*(const unsigned long int n) const; + /** + * shift the bits to the right + * (LSB on the right side) + * @param n number of bits to shift + */ void rShift(u_int8_t n); // LSB on the right side! Mpi mul2exp(u_int32_t e) const; // value * 2^e void clearHighBit(u_int32_t n); - u_int8_t *getBuf(u_int32_t buf_len) const; + + /** + * returns a new[] u_int8_t* buffer with the MPI value in the + * GCRYMPI_FMT_STD (2-complement stored without a length header). + * you have to delete it by hand with delete[]! + * @param buf_len size of the new buffer that is returned + * @return a byte buffer of size buf_len + */ + u_int8_t *getNewBuf(u_int32_t buf_len) const; u_int32_t getLen() const; protected: -- cgit v1.2.3