diff options
-rw-r--r-- | anytun.cpp | 2 | ||||
-rw-r--r-- | buffer.cpp | 22 | ||||
-rw-r--r-- | buffer.h | 9 | ||||
-rw-r--r-- | cipher.cpp | 72 | ||||
-rw-r--r-- | cipher.h | 19 | ||||
-rw-r--r-- | encryptedPacket.cpp | 2 | ||||
-rw-r--r-- | mpi.cpp | 13 |
7 files changed, 76 insertions, 63 deletions
@@ -70,7 +70,7 @@ #define SESSION_KEYLEN_ENCR 16 #define SESSION_KEYLEN_SALT 14 -void createConnection(const std::string & remote_host , u_int16_t remote_port, ConnectionList & cl, u_int16_t seqSize, SyncQueue & queue) +void createConnection(const std::string & remote_host, u_int16_t remote_port, ConnectionList & cl, u_int16_t seqSize, SyncQueue & queue) { uint8_t key[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', @@ -30,8 +30,7 @@ #include <stdexcept> #include <string> -#include <cstdio> -#include <iostream> +#include <sstream> #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> #include "datatypes.h" @@ -182,18 +181,19 @@ Buffer::operator u_int8_t*() // just for write/read tun std::string Buffer::getHexDump() const { - char text[10]; - std::string ret = ""; - + std::stringstream ss; + ss << std::hex; for( u_int32_t index = 0; index < length_; index++ ) { - std::sprintf(text, "%#4x", buf_[index]); - ret += text; - ret += ""; - if( ((index+1) % 10) == 0 ) - ret += '\n'; + ss << std::setw(2) << std::setfill('0') << static_cast<unsigned int>(buf_[index]) << " "; + if(!((index+1) % 16)) { + ss << std::endl; + continue; + } + if(!((index+1) % 8)) + ss << " "; } - return ret; + return ss.str(); } Buffer Buffer::operator^(const Buffer &xor_by) const @@ -61,14 +61,9 @@ public: u_int8_t operator[](u_int32_t index) const; std::string getHexDump() const; - operator u_int8_t*(); // just for write/read tun and packetSource -protected: - friend class TunDevice; - friend class UDPPacketSource; - friend class AesIcmCipher; - friend class KeyDerivation; // - friend class Mpi; + operator u_int8_t*(); +protected: u_int8_t *buf_; u_int32_t length_; }; @@ -39,28 +39,34 @@ #include "log.h" -void Cipher::encrypt(const PlainPacket & in,EncryptedPacket & out, seq_nr_t seq_nr, sender_id_t sender_id) +void Cipher::encrypt(const PlainPacket & in, EncryptedPacket & out, seq_nr_t seq_nr, sender_id_t sender_id) { - cipher(out.payload_, in.complete_payload_ , in.complete_payload_length_, seq_nr, sender_id); + u_int32_t len = cipher(out.payload_, out.payload_length_, in.complete_payload_ , in.complete_payload_length_, seq_nr, sender_id); out.setSenderId(sender_id); out.setSeqNr(seq_nr); - out.setPayloadLength(in.complete_payload_length_); + out.setPayloadLength(len); } -void Cipher::decrypt(const EncryptedPacket & in,PlainPacket & out) +void Cipher::decrypt(const EncryptedPacket & in, PlainPacket & out) { - cipher(out.complete_payload_, in.payload_ , in.payload_length_, in.getSeqNr(), in.getSenderId()); - out.setCompletePayloadLength(in.payload_length_); + u_int32_t len = decipher(out.complete_payload_, out.complete_payload_length_, in.payload_ , in.payload_length_, in.getSeqNr(), in.getSenderId()); + out.setCompletePayloadLength(len); } //******* NullCipher ******* -void NullCipher::cipher(u_int8_t * out, u_int8_t * in, u_int32_t length, seq_nr_t seq_nr, sender_id_t sender_id) +u_int32_t NullCipher::cipher(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) { - std::memcpy(out, in, length ); + std::memcpy(out, in, (ilen < olen) ? ilen : olen); + return (ilen < olen) ? ilen : olen; } +u_int32_t NullCipher::decipher(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) +{ + std::memcpy(out, in, (ilen < olen) ? ilen : olen); + return (ilen < olen) ? ilen : olen; +} //****** AesIcmCipher ****** @@ -94,11 +100,27 @@ void AesIcmCipher::setSalt(Buffer salt) salt_ = salt; } -void AesIcmCipher::cipher(u_int8_t * out, u_int8_t * in, u_int32_t length, seq_nr_t seq_nr, sender_id_t sender_id) +u_int32_t AesIcmCipher::cipher(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) { - gcry_error_t err; + calc(in, ilen, out, olen, seq_nr, sender_id); + return (ilen < olen) ? ilen : olen; +} - // set the IV +u_int32_t AesIcmCipher::decipher(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) +{ + calc(in, ilen, out, olen, seq_nr, sender_id); + return (ilen < olen) ? ilen : olen; +} + +void AesIcmCipher::calc(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) +{ + gcry_error_t err = gcry_cipher_reset( cipher_ ); + if( err ) { + cLog.msg(Log::PRIO_ERR) << "AesIcmCipher: Failed to reset cipher: " << gpg_strerror( err ); + return; + } + + // set the IV ( = CTR) //========================================================================== // // where the 128-bit integer value IV SHALL be defined by the SSRC, the // // SRTP packet index i, and the SRTP session salting key k_s, as below. @@ -106,33 +128,21 @@ void AesIcmCipher::cipher(u_int8_t * out, u_int8_t * in, u_int32_t length, seq_ // // IV = (k_s * 2^16) XOR (SSRC * 2^64) XOR (i * 2^16) // // sizeof(k_s) = 112 bit, random - Mpi iv(128); // TODO: hardcoded size + Mpi ctr(128); // TODO: hardcoded size Mpi salt = Mpi(salt_.getBuf(), salt_.getLength()); - Mpi sid = sender_id; + Mpi sid = sender_id; // Q@OTTI add mux to sender_id???? Mpi seq = seq_nr; - iv = salt.mul2exp(16) ^ sid.mul2exp(64) ^ seq.mul2exp(16); // TODO: hardcoded size - - u_int8_t *iv_buf = iv.getNewBuf(16); // TODO: hardcoded size - - // Q@NINE -> CTR Mode -> gcry_cipher_setctr() ???? - - err = gcry_cipher_setiv( cipher_, iv_buf, 16 ); // TODO: hardcoded size - delete[] iv_buf; + ctr = salt.mul2exp(16) ^ sid.mul2exp(64) ^ seq.mul2exp(16); // TODO: hardcoded size + u_int8_t *ctr_buf = ctr.getNewBuf(16); // TODO: hardcoded size + err = gcry_cipher_setctr( cipher_, ctr_buf, 16 ); // TODO: hardcoded size + delete[] ctr_buf; if( err ) { - cLog.msg(Log::PRIO_ERR) << "AesIcmCipher: Failed to set cipher IV: " << gpg_strerror( err ); - return; - } - - // Q@NINE -> reset clears IV ???? - - err = gcry_cipher_reset( cipher_ ); - if( err ) { - cLog.msg(Log::PRIO_ERR) << "AesIcmCipher: Failed to reset cipher: " << gpg_strerror( err ); + cLog.msg(Log::PRIO_ERR) << "AesIcmCipher: Failed to set cipher CTR: " << gpg_strerror( err ); return; } - err = gcry_cipher_encrypt( cipher_, out, length, in, length ); + err = gcry_cipher_encrypt( cipher_, out, olen, in, ilen ); if( err ) { cLog.msg(Log::PRIO_ERR) << "AesIcmCipher: Failed to generate cipher bitstream: " << gpg_strerror( err ); return; @@ -44,14 +44,15 @@ class Cipher public: virtual ~Cipher() {}; - void encrypt(const PlainPacket & in,EncryptedPacket & out, seq_nr_t seq_nr, sender_id_t sender_id); - void decrypt(const EncryptedPacket & in,PlainPacket & out); - + void encrypt(const PlainPacket & in, EncryptedPacket & out, seq_nr_t seq_nr, sender_id_t sender_id); + void decrypt(const EncryptedPacket & in, PlainPacket & out); + virtual void setKey(Buffer key) = 0; virtual void setSalt(Buffer salt) = 0; protected: - virtual void cipher(u_int8_t * in, u_int8_t * out, u_int32_t length, seq_nr_t seq_nr, sender_id_t sender_id) = 0; + virtual u_int32_t cipher(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) = 0; + virtual u_int32_t decipher(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) = 0; }; //****** NullCipher ****** @@ -63,7 +64,8 @@ public: void setSalt(Buffer salt) {}; protected: - void cipher(u_int8_t * in, u_int8_t * out, u_int32_t length, seq_nr_t seq_nr, sender_id_t sender_id); + u_int32_t cipher(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); + u_int32_t decipher(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); }; //****** AesIcmCipher ****** @@ -77,7 +79,12 @@ public: void setSalt(Buffer salt); protected: - void cipher(u_int8_t * in, u_int8_t * out, u_int32_t length, seq_nr_t seq_nr, sender_id_t sender_id); + u_int32_t cipher(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); + u_int32_t decipher(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); + +private: + void calc(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); + gcry_cipher_hd_t cipher_; Buffer salt_; }; diff --git a/encryptedPacket.cpp b/encryptedPacket.cpp index eb459e4..0731d24 100644 --- a/encryptedPacket.cpp +++ b/encryptedPacket.cpp @@ -170,7 +170,7 @@ AuthTag EncryptedPacket::getAuthTag() const throw std::runtime_error("auth tag not enabled"); AuthTag at(AUTHTAG_SIZE); - std::memcpy(at, auth_tag_, AUTHTAG_SIZE ); + std::memcpy(at, auth_tag_, AUTHTAG_SIZE ); return at; } @@ -57,6 +57,12 @@ Mpi::Mpi(const u_int8_t * src, u_int32_t len) gcry_mpi_scan( &val_, GCRYMPI_FMT_STD, src, len, NULL ); } +Mpi::~Mpi() +{ + gcry_mpi_release( val_ ); +} + + void Mpi::operator=(const Mpi &src) { val_ = gcry_mpi_copy(src.val_); @@ -88,6 +94,7 @@ Mpi Mpi::operator*(const unsigned long int n) const return res; } +//TODO: this is outstandingly ugly!!!!!!!! Mpi Mpi::operator^(const Mpi &b) const { u_int32_t a_len=0, b_len=0; @@ -150,9 +157,3 @@ u_int32_t Mpi::getLen() const { return gcry_mpi_get_nbits( val_ ); } - -Mpi::~Mpi() -{ - gcry_mpi_release( val_ ); -} - |