summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@anytun.org>2009-03-17 15:53:22 +0000
committerChristian Pointner <equinox@anytun.org>2009-03-17 15:53:22 +0000
commit7d04626ef28ca5d27bc8515660c58bb135aa8c93 (patch)
treed8affb3523764a4be6aba9b6bd227e875ebb2096
parentremoved key derivation rate entirely (diff)
added support for configurabel auth tag length
-rw-r--r--cmd-option-letters4
-rw-r--r--src/anytun.cpp4
-rw-r--r--src/authAlgo.h2
-rw-r--r--src/authAlgoFactory.cpp16
-rw-r--r--src/authAlgoFactory.h1
-rw-r--r--src/encryptedPacket.cpp22
-rw-r--r--src/encryptedPacket.h4
-rw-r--r--src/man/anytun.8.txt11
-rw-r--r--src/options.cpp34
-rw-r--r--src/options.h3
10 files changed, 79 insertions, 22 deletions
diff --git a/cmd-option-letters b/cmd-option-letters
index 5533d21..340ed83 100644
--- a/cmd-option-letters
+++ b/cmd-option-letters
@@ -2,7 +2,7 @@
6: resolv ipv6 only (payload socket)
a: auth algo
-b: auth tag length (not yet)
+b: auth tag length
c: cipher
d: device name
e: role
@@ -42,7 +42,7 @@ K: master key
L: logging
M: remote sync hosts
N:
-O: anytun 0.2 compat mode
+O: anytun 0.2 compat mode // deprecated
P: write pid file
Q:
R: route
diff --git a/src/anytun.cpp b/src/anytun.cpp
index c19ceb5..99f1560 100644
--- a/src/anytun.cpp
+++ b/src/anytun.cpp
@@ -149,7 +149,7 @@ void sender(TunDevice* dev, PacketSource* src)
std::auto_ptr<AuthAlgo> a(AuthAlgoFactory::create(gOpt.getAuthAlgo(), KD_OUTBOUND) );
PlainPacket plain_packet(MAX_PACKET_LENGTH);
- EncryptedPacket encrypted_packet(MAX_PACKET_LENGTH);
+ EncryptedPacket encrypted_packet(MAX_PACKET_LENGTH, gOpt.getAuthTagLength());
u_int16_t mux = gOpt.getMux();
PacketSourceEndpoint emptyEndpoint;
@@ -237,7 +237,7 @@ void receiver(TunDevice* dev, PacketSource* src)
std::auto_ptr<Cipher> c(CipherFactory::create(gOpt.getCipher(), KD_INBOUND, gOpt.getAnytun02Compat()));
std::auto_ptr<AuthAlgo> a(AuthAlgoFactory::create(gOpt.getAuthAlgo(), KD_INBOUND));
- EncryptedPacket encrypted_packet(MAX_PACKET_LENGTH);
+ EncryptedPacket encrypted_packet(MAX_PACKET_LENGTH, gOpt.getAuthTagLength());
PlainPacket plain_packet(MAX_PACKET_LENGTH);
while(1) {
diff --git a/src/authAlgo.h b/src/authAlgo.h
index cca706d..c446853 100644
--- a/src/authAlgo.h
+++ b/src/authAlgo.h
@@ -75,6 +75,8 @@ class NullAuthAlgo : public AuthAlgo
public:
void generate(KeyDerivation& kd, EncryptedPacket& packet);
bool checkTag(KeyDerivation& kd, EncryptedPacket& packet);
+
+ static const u_int32_t DIGEST_LENGTH = 0;
};
#ifndef NO_CRYPT
diff --git a/src/authAlgoFactory.cpp b/src/authAlgoFactory.cpp
index 8fa16fc..c284f34 100644
--- a/src/authAlgoFactory.cpp
+++ b/src/authAlgoFactory.cpp
@@ -38,13 +38,25 @@
AuthAlgo* AuthAlgoFactory::create(std::string const& type, kd_dir_t dir)
{
- if( type == "null" )
+ if(type == "null")
return new NullAuthAlgo();
#ifndef NO_CRYPT
- else if( type == "sha1" )
+ else if(type == "sha1")
return new Sha1AuthAlgo(dir);
#endif
else
throw std::invalid_argument("auth algo not available");
}
+u_int32_t AuthAlgoFactory::getDigestLength(std::string const& type)
+{
+ if(type == "null")
+ return NullAuthAlgo::DIGEST_LENGTH;
+#ifndef NO_CRYPT
+ else if(type == "sha1")
+ return Sha1AuthAlgo::DIGEST_LENGTH;
+#endif
+ else
+ throw std::invalid_argument("auth algo not available");
+}
+
diff --git a/src/authAlgoFactory.h b/src/authAlgoFactory.h
index ee38248..2dca567 100644
--- a/src/authAlgoFactory.h
+++ b/src/authAlgoFactory.h
@@ -41,6 +41,7 @@ class AuthAlgoFactory
{
public:
static AuthAlgo* create(std::string const& type, kd_dir_t dir);
+ static u_int32_t getDigestLength(std::string const& type);
private:
AuthAlgoFactory();
diff --git a/src/encryptedPacket.cpp b/src/encryptedPacket.cpp
index c18551c..a5aec86 100644
--- a/src/encryptedPacket.cpp
+++ b/src/encryptedPacket.cpp
@@ -39,8 +39,8 @@
#include "log.h"
#include "anytunError.h"
-EncryptedPacket::EncryptedPacket(u_int32_t payload_length, bool allow_realloc)
- : Buffer(payload_length + sizeof(struct HeaderStruct), allow_realloc)
+EncryptedPacket::EncryptedPacket(u_int32_t payload_length, u_int32_t auth_tag_length, bool allow_realloc)
+ : Buffer(payload_length + sizeof(struct HeaderStruct), allow_realloc), auth_tag_length_(auth_tag_length)
{
header_ = reinterpret_cast<struct HeaderStruct*>(buf_);
payload_ = buf_ + sizeof(struct HeaderStruct);
@@ -118,7 +118,7 @@ u_int32_t EncryptedPacket::getPayloadLength() const
if(!auth_tag_)
return (length_ > sizeof(struct HeaderStruct)) ? (length_ - sizeof(struct HeaderStruct)) : 0;
- return (length_ > (sizeof(struct HeaderStruct) + AUTHTAG_SIZE)) ? (length_ - sizeof(struct HeaderStruct) - AUTHTAG_SIZE) : 0;
+ return (length_ > (sizeof(struct HeaderStruct) + auth_tag_length_)) ? (length_ - sizeof(struct HeaderStruct) - auth_tag_length_) : 0;
}
void EncryptedPacket::setPayloadLength(u_int32_t payload_length)
@@ -143,11 +143,11 @@ void EncryptedPacket::reinit()
if(auth_tag_)
{
- if(length_ < (sizeof(struct HeaderStruct) + AUTHTAG_SIZE)) {
+ if(length_ < (sizeof(struct HeaderStruct) + auth_tag_length_)) {
auth_tag_ = NULL;
AnytunError::throwErr() << "auth-tag can't be enabled, buffer is too small";
}
- auth_tag_ = buf_ + length_ - AUTHTAG_SIZE;
+ auth_tag_ = buf_ + length_ - auth_tag_length_;
}
}
@@ -169,7 +169,7 @@ u_int32_t EncryptedPacket::getAuthenticatedPortionLength()
if(!auth_tag_)
return length_;
- return (length_ > AUTHTAG_SIZE) ? (length_ - AUTHTAG_SIZE) : 0;
+ return (length_ > auth_tag_length_) ? (length_ - auth_tag_length_) : 0;
}
void EncryptedPacket::withAuthTag(bool b)
@@ -179,10 +179,10 @@ void EncryptedPacket::withAuthTag(bool b)
if(b)
{
- if(length_ < (sizeof(struct HeaderStruct) + AUTHTAG_SIZE))
+ if(length_ < (sizeof(struct HeaderStruct) + auth_tag_length_))
AnytunError::throwErr() << "auth-tag can't be enabled, buffer is too small";
- auth_tag_ = buf_ + length_ - AUTHTAG_SIZE;
+ auth_tag_ = buf_ + length_ - auth_tag_length_;
}
else
auth_tag_ = NULL;
@@ -194,7 +194,7 @@ void EncryptedPacket::addAuthTag()
return;
auth_tag_ = buf_; // will be set to the correct value @ reinit
- setLength(length_ + AUTHTAG_SIZE);
+ setLength(length_ + auth_tag_length_);
if(auth_tag_ == buf_) // reinit was not called by setLength
reinit();
}
@@ -205,7 +205,7 @@ void EncryptedPacket::removeAuthTag()
return;
auth_tag_ = NULL;
- setLength(length_ - AUTHTAG_SIZE);
+ setLength(length_ - auth_tag_length_);
}
u_int8_t* EncryptedPacket::getAuthTag()
@@ -216,7 +216,7 @@ u_int8_t* EncryptedPacket::getAuthTag()
u_int32_t EncryptedPacket::getAuthTagLength()
{
if(auth_tag_)
- return AUTHTAG_SIZE;
+ return auth_tag_length_;
return 0;
}
diff --git a/src/encryptedPacket.h b/src/encryptedPacket.h
index 4f64022..618fa44 100644
--- a/src/encryptedPacket.h
+++ b/src/encryptedPacket.h
@@ -45,7 +45,7 @@ public:
* @param the length of the payload
* @param allow reallocation of buffer
*/
- EncryptedPacket(u_int32_t payload_length, bool allow_realloc = false);
+ EncryptedPacket(u_int32_t payload_length, u_int32_t auth_tag_length, bool allow_realloc = false);
/**
* Packet destructor
@@ -152,7 +152,7 @@ private:
struct HeaderStruct* header_;
u_int8_t * payload_;
u_int8_t * auth_tag_;
- static const u_int32_t AUTHTAG_SIZE = 10; // TODO: hardcoded size
+ u_int32_t auth_tag_length_;
};
#endif
diff --git a/src/man/anytun.8.txt b/src/man/anytun.8.txt
index 05a650c..fa30441 100644
--- a/src/man/anytun.8.txt
+++ b/src/man/anytun.8.txt
@@ -41,6 +41,7 @@ SYNOPSIS
[ *-A|--salt* <master salt> ]
[ *-c|--cipher* <cipher type> ]
[ *-a|--auth-algo* <algo type> ]
+[ *-b|--auth-tag-length* <length> ]
DESCRIPTION
-----------
@@ -362,8 +363,14 @@ Possible values:
* *null* - no message authentication
* *sha1* - HMAC-SHA1, default value
-If HMAC-SHA1 is used, the packet length is increased by
-10 bytes. These 10 bytes contain the authentication data.
+If HMAC-SHA1 is used, the packet length is increased. The additional bytes
+contain the authentication data. see *-b|--auth-tag-length* for more info.
+
+-b|--auth-tag-length <length>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The number of bytes to use for the auth tag. This value defaults to 10 bytes
+unless the *null* auth algo is used in which case it defaults to 0.
EXAMPLES
diff --git a/src/options.cpp b/src/options.cpp
index e58278a..94e3c44 100644
--- a/src/options.cpp
+++ b/src/options.cpp
@@ -38,6 +38,7 @@
#include "datatypes.h"
#include "options.h"
#include "log.h"
+#include "authAlgoFactory.h"
std::ostream& operator<<(std::ostream& stream, syntax_error const& error)
{
@@ -181,10 +182,12 @@ Options::Options() : key_(u_int32_t(0)), salt_(u_int32_t(0))
#ifndef NO_CRYPT
cipher_ = "aes-ctr";
auth_algo_ = "sha1";
+ auth_tag_length_ = 10;
kd_prf_ = "aes-ctr";
#else
cipher_ = "null";
auth_algo_ = "null";
+ auth_tag_length_ = 0;
kd_prf_ = "null";
#endif
role_ = ROLE_LEFT;
@@ -412,6 +415,7 @@ bool Options::parse(int argc, char* argv[])
#ifndef NO_CRYPT
PARSE_SCALAR_PARAM("-c","--cipher", cipher_)
PARSE_SCALAR_PARAM("-a","--auth-algo", auth_algo_)
+ PARSE_SCALAR_PARAM("-b","--auth-tag-length", auth_tag_length_)
#endif
#endif
@@ -443,6 +447,19 @@ void Options::parse_post()
kd_prf_ = "null";
if((cipher_ != "null" || auth_algo_ != "null") && kd_prf_ == "null")
cLog.msg(Log::PRIO_WARNING) << "using NULL key derivation with encryption and or authentication enabled!";
+
+
+#if defined(ANYTUN_OPTIONS)
+ u_int32_t tag_len_max = AuthAlgoFactory::getDigestLength(auth_algo_);
+ if(!tag_len_max) auth_tag_length_ = 0;
+ else if(tag_len_max < auth_tag_length_) {
+ cLog.msg(Log::PRIO_WARNING) << auth_algo_ << " auth algo can't generate tags of length " << auth_tag_length_ << ", using maximum tag length(" << tag_len_max << ")";
+ auth_tag_length_ = tag_len_max;
+ }
+#endif
+
+ if(anytun02_compat_)
+ cLog.msg(Log::PRIO_WARNING) << "--anytun02-compat is deprecated and very likly to be removed by the next release";
if(dev_name_ == "" && dev_type_ == "")
dev_type_ = "tun";
@@ -528,7 +545,6 @@ void Options::printUsage()
#ifndef NO_CRYPT
std::cout << " [-k|--kd-prf] <kd-prf type> key derivation pseudo random function" << std::endl;
std::cout << " [-e|--role] <role> left (alice) or right (bob)" << std::endl;
- std::cout << " [-O|--anytun02-compat] enable compatiblity mode for anytun 0.2.x and prior" << std::endl;
#ifndef NO_PASSPHRASE
std::cout << " [-E|--passphrase] <pass phrase> a passprhase to generate master key and salt from" << std::endl;
#endif
@@ -542,6 +558,7 @@ void Options::printUsage()
#ifndef NO_CRYPT
std::cout << " [-c|--cipher] <cipher type> payload encryption algorithm" << std::endl;
std::cout << " [-a|--auth-algo] <algo type> message authentication algorithm" << std::endl;
+ std::cout << " [-b|--auth-tag-length] length of the auth tag" << std::endl;
#endif
#endif
@@ -602,6 +619,7 @@ void Options::printOptions()
std::cout << std::endl;
std::cout << "cipher = '" << cipher_ << "'" << std::endl;
std::cout << "auth_algo = '" << auth_algo_ << "'" << std::endl;
+ std::cout << "auth_tag_length = " << auth_tag_length_ << std::endl;
std::cout << "kd_prf = '" << kd_prf_ << "'" << std::endl;
std::cout << "role = ";
switch(role_) {
@@ -971,6 +989,20 @@ Options& Options::setAuthAlgo(std::string a)
return *this;
}
+u_int32_t Options::getAuthTagLength()
+{
+ ReadersLock lock(mutex);
+ return auth_tag_length_;
+}
+
+Options& Options::setAuthTagLength(u_int32_t a)
+{
+ WritersLock lock(mutex);
+ auth_tag_length_ = a;
+ return *this;
+}
+
+
std::string Options::getKdPrf()
{
ReadersLock lock(mutex);
diff --git a/src/options.h b/src/options.h
index 480d1c7..71229cc 100644
--- a/src/options.h
+++ b/src/options.h
@@ -149,6 +149,8 @@ public:
Options& setCipher(std::string c);
std::string getAuthAlgo();
Options& setAuthAlgo(std::string a);
+ u_int32_t getAuthTagLength();
+ Options& setAuthTagLength(u_int32_t a);
std::string getKdPrf();
Options& setKdPrf(std::string k);
role_t getRole();
@@ -212,6 +214,7 @@ private:
std::string cipher_;
std::string auth_algo_;
+ u_int32_t auth_tag_length_;
std::string kd_prf_;
role_t role_;
bool anytun02_compat_;