summaryrefslogtreecommitdiff
path: root/src/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto')
-rw-r--r--src/crypto/interface.cpp55
-rw-r--r--src/crypto/interface.h4
-rw-r--r--src/crypto/openssl.cpp27
-rw-r--r--src/crypto/openssl.h3
4 files changed, 89 insertions, 0 deletions
diff --git a/src/crypto/interface.cpp b/src/crypto/interface.cpp
index 2ae9c16..c11e382 100644
--- a/src/crypto/interface.cpp
+++ b/src/crypto/interface.cpp
@@ -68,6 +68,61 @@ void Interface::decrypt(EncryptedPacket& in, PlainPacket& out, const Buffer& mas
out.setLength(len);
}
+bool Interface::checkAndRemoveAuthTag(EncryptedPacket& packet, const Buffer& masterkey, const Buffer& mastersalt, role_t role)
+{
+ uint32_t digest_length = getDigestLength();
+ packet.withAuthTag(true);
+ if(!packet.getAuthTagLength()) {
+ return true;
+ }
+
+ Buffer digest(digest_length);
+ //Buffer key(masterkey.getLength(), false);
+ Buffer key(digest_length, false);
+ deriveKey(KD_INBOUND, LABEL_AUTH, role, packet.getSeqNr(), packet.getSeqNr(), packet.getMux(), masterkey, mastersalt, key);
+ //std::cout << "Interface::checkAndRemoveAuthTag: " << key.getHexDump() << std::endl;
+ calcAuthKey(key, digest, packet.getAuthenticatedPortion(), packet.getAuthenticatedPortionLength() );
+
+ uint8_t* tag = packet.getAuthTag();
+ uint32_t length = (packet.getAuthTagLength() < digest_length) ? packet.getAuthTagLength() : digest_length;
+
+ if(length > digest_length)
+ for(uint32_t i=0; i < (packet.getAuthTagLength() - digest_length); ++i)
+ if(tag[i]) { return false; }
+
+ int ret = std::memcmp(&tag[packet.getAuthTagLength() - length], digest.getBuf() + digest_length - length, length);
+ packet.removeAuthTag();
+
+ if(ret) {
+ return false;
+ }
+
+ return true;
+}
+
+void Interface::addAuthTag(EncryptedPacket& packet, const Buffer& masterkey, const Buffer& mastersalt, role_t role)
+{
+ uint32_t digest_length = getDigestLength();
+ packet.addAuthTag();
+ if(!packet.getAuthTagLength()) {
+ return;
+ }
+ Buffer digest(digest_length);
+ //Buffer key(masterkey.getLength(), false);
+ Buffer key(digest_length, false);
+ deriveKey(KD_OUTBOUND, LABEL_AUTH, role, packet.getSeqNr(), packet.getSeqNr(), packet.getMux(), masterkey, mastersalt, key);
+ //std::cout << "Interface::addAuthTag: " << key.getHexDump() << std::endl;
+ calcAuthKey(key, digest, packet.getAuthenticatedPortion(), packet.getAuthenticatedPortionLength() );
+ uint8_t* tag = packet.getAuthTag();
+ uint32_t length = (packet.getAuthTagLength() < digest_length) ? packet.getAuthTagLength() : digest_length;
+
+ if(length > digest_length) {
+ std::memset(tag, 0, packet.getAuthTagLength());
+ }
+
+ std::memcpy(&tag[packet.getAuthTagLength() - length], digest.getBuf() + digest_length - length, length);
+
+}
satp_prf_label_t Interface::convertLabel(kd_dir_t dir, role_t role, satp_prf_label_t label)
{
diff --git a/src/crypto/interface.h b/src/crypto/interface.h
index 0ca52fb..49013ba 100644
--- a/src/crypto/interface.h
+++ b/src/crypto/interface.h
@@ -118,6 +118,8 @@ namespace crypto {
void decrypt(EncryptedPacket& in, PlainPacket& out, const Buffer& masterkey, const Buffer& mastersalt, role_t role);
void calcCryptCtr(const Buffer& masterkey, const Buffer& mastersalt, kd_dir_t dir, role_t role, satp_prf_label_t label, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux, cipher_aesctr_ctr_t * ctr);
void calcKeyCtr(const Buffer& mastersalt, kd_dir_t dir, role_t role, satp_prf_label_t label, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux, key_derivation_aesctr_ctr_t * ctr);
+ bool checkAndRemoveAuthTag(EncryptedPacket& packet, const Buffer& masterkey, const Buffer& mastersalt, role_t role);
+ void addAuthTag(EncryptedPacket& packet, const Buffer& masterkey, const Buffer& mastersalt, role_t role);
// pure virtual
@@ -125,6 +127,8 @@ namespace crypto {
virtual uint32_t cipher(uint8_t* in, uint32_t ilen, uint8_t* out, uint32_t olen, const Buffer& masterkey, const Buffer& mastersalt, role_t role, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux) = 0;
virtual uint32_t decipher(uint8_t* in, uint32_t ilen, uint8_t* out, uint32_t olen, const Buffer& masterkey, const Buffer& mastersalt, role_t role, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux) = 0;
virtual void deriveKey(kd_dir_t dir, satp_prf_label_t label, role_t role, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux, const Buffer& masterkey, const Buffer& mastersalt, Buffer& key) = 0;
+ virtual void calcAuthKey(Buffer & key, Buffer & digest, uint8_t * payload, size_t payload_length ) = 0;
+ virtual uint32_t getDigestLength() = 0;
// virtual
virtual ~Interface();
diff --git a/src/crypto/openssl.cpp b/src/crypto/openssl.cpp
index 9252b48..95ccf3e 100644
--- a/src/crypto/openssl.cpp
+++ b/src/crypto/openssl.cpp
@@ -47,6 +47,8 @@
#include "../log.h"
#include <openssl/aes.h>
#include <openssl/sha.h>
+#include <openssl/hmac.h>
+
#include "../anytunError.h"
namespace crypto {
@@ -57,6 +59,26 @@ Openssl::~Openssl()
}
+void Openssl::calcAuthKey(Buffer & key, Buffer & digest, uint8_t * payload, size_t payload_length )
+{
+ uint32_t digest_length = getDigestLength();
+ HMAC_CTX ctx;
+ HMAC_CTX_init(&ctx);
+ //HMAC_Init_ex(&ctx, NULL, 0, EVP_sha1(), NULL);
+
+ HMAC_Init_ex(&ctx, key.getBuf(), key.getLength(), EVP_sha1(), NULL);
+
+ uint8_t hmac[digest_length];
+ HMAC_Update(&ctx, payload, payload_length );
+ HMAC_Final(&ctx, hmac, NULL);
+
+ HMAC_CTX_cleanup(&ctx);
+ digest.setLength(digest_length);
+
+ std::memcpy(digest.getBuf(), hmac, digest_length);
+}
+
+
void Openssl::calcMasterKeySalt(std::string passphrase, uint16_t length, Buffer& masterkey , Buffer& mastersalt)
{
cLog.msg(Log::PRIO_NOTICE) << "KeyDerivation: calculating master key from passphrase";
@@ -162,4 +184,9 @@ bool Openssl::init()
return true;
}
+uint32_t Openssl::getDigestLength()
+{
+ return 20;
+}
+
}
diff --git a/src/crypto/openssl.h b/src/crypto/openssl.h
index 35a2d26..27ffd48 100644
--- a/src/crypto/openssl.h
+++ b/src/crypto/openssl.h
@@ -58,6 +58,9 @@ namespace crypto {
virtual uint32_t cipher(uint8_t* in, uint32_t ilen, uint8_t* out, uint32_t olen, const Buffer& masterkey, const Buffer& mastersalt, role_t role, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux);
virtual uint32_t decipher(uint8_t* in, uint32_t ilen, uint8_t* out, uint32_t olen, const Buffer& masterkey, const Buffer& mastersalt, role_t role, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux);
virtual void deriveKey(kd_dir_t dir, satp_prf_label_t label, role_t role, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux, const Buffer& masterkey, const Buffer& mastersalt, Buffer& key);
+ virtual void calcAuthKey(Buffer & key, Buffer & digest, uint8_t * payload, size_t payload_length );
+ virtual uint32_t getDigestLength();
+
// virtual
virtual ~Openssl();
virtual std::string printType();