summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--anytun.cpp30
-rw-r--r--buffer.h1
-rw-r--r--cypher.cpp57
-rw-r--r--cypher.h12
-rw-r--r--keyDerivation.cpp29
-rw-r--r--keyDerivation.h6
6 files changed, 103 insertions, 32 deletions
diff --git a/anytun.cpp b/anytun.cpp
index 4e3b2b6..f01d998 100644
--- a/anytun.cpp
+++ b/anytun.cpp
@@ -37,6 +37,7 @@
#include "buffer.h"
#include "packet.h"
#include "cypher.h"
+#include "keyDerivation.h"
#include "authAlgo.h"
#include "signalController.h"
#include "packetSource.h"
@@ -51,6 +52,7 @@ struct Param
{
Options& opt;
TunDevice& dev;
+ KeyDerivation& kd;
Cypher& c;
AuthAlgo& a;
PacketSource& src;
@@ -82,6 +84,11 @@ void* sender(void* p)
pack.addPayloadType(0);
// cypher the packet
+ Buffer tmp_key(16), tmp_salt(14);
+ param->kd.generate(label_satp_encryption, seq, tmp_key, tmp_key.getLength());
+ param->kd.generate(label_satp_salt, seq, tmp_salt, tmp_salt.getLength());
+ param->c.setKey(tmp_key);
+ param->c.setSalt(tmp_salt);
param->c.cypher(pack, seq, param->opt.getSenderId());
// add header to packet
@@ -132,6 +139,11 @@ void* receiver(void* p)
pack.removeHeader();
// decypher the packet
+ Buffer tmp_key(16), tmp_salt(14);
+ param->kd.generate(label_satp_encryption, pack.getSeqNr(), tmp_key, tmp_key.getLength());
+ param->kd.generate(label_satp_salt, pack.getSeqNr(), tmp_salt, tmp_salt.getLength());
+ param->c.setKey(tmp_key);
+ param->c.setSalt(tmp_salt);
param->c.cypher(pack, pack.getSeqNr(), pack.getSenderId());
// check payload_type and remove it
@@ -162,6 +174,22 @@ int main(int argc, char* argv[])
TunDevice dev(opt.getDevName().c_str(), opt.getIfconfigParamLocal().c_str(), opt.getIfconfigParamRemoteNetmask().c_str());
SeqWindow seq(opt.getSeqWindowSize());
+
+ uint8_t key[] = {
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
+ 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+ 'q', 'r', 's', 't'
+ };
+
+ uint8_t salt[] = {
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
+ 'i', 'j', 'k', 'l', 'm', 'n'
+ };
+
+
+ KeyDerivation kd;
+ kd.init(Buffer(key, sizeof(key)), Buffer(salt, sizeof(salt)));
+
// NullCypher c;
AesIcmCypher c;
NullAuthAlgo a;
@@ -171,7 +199,7 @@ int main(int argc, char* argv[])
else
src = new UDPPacketSource(opt.getLocalAddr(), opt.getLocalPort());
- struct Param p = {opt, dev, c, a, *src, seq};
+ struct Param p = {opt, dev, kd, c, a, *src, seq};
std::cout << "dev created (opened)" << std::endl;
std::cout << "dev opened - actual name is '" << p.dev.getActualName() << "'" << std::endl;
diff --git a/buffer.h b/buffer.h
index e46939b..2e3a75e 100644
--- a/buffer.h
+++ b/buffer.h
@@ -58,6 +58,7 @@ protected:
friend class TunDevice;
friend class UDPPacketSource;
friend class AesIcmCypher;
+ friend class KeyDerivation; //
u_int8_t *buf_;
u_int32_t length_;
diff --git a/cypher.cpp b/cypher.cpp
index 0e48ae7..345b4a4 100644
--- a/cypher.cpp
+++ b/cypher.cpp
@@ -32,6 +32,8 @@
#include <vector>
#include "cypher.h"
+#include "keyDerivation.h"
+
extern "C" {
#include <srtp/crypto_kernel.h>
@@ -62,44 +64,69 @@ Buffer NullCypher::getBitStream(u_int32_t length, seq_nr_t seq_nr, sender_id_t s
}
+void AesIcmCypher::setKey(Buffer key)
+{
+ key_ = key;
+}
+
+void AesIcmCypher::setSalt(Buffer salt)
+{
+ salt = salt;
+}
+
void AesIcmCypher::cypher(Buffer& buf, seq_nr_t seq_nr, sender_id_t sender_id)
{
extern cipher_type_t aes_icm;
err_status_t status = err_status_ok;
cipher_t* cipher = NULL;
uint32_t length = 0;
+ v128_t iv, sid, seq, salt;
- uint8_t key[] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d
- };
-
- v128_t iv;
v128_set_to_zero(&iv);
+ v128_set_to_zero(&sid);
+ v128_set_to_zero(&seq);
+ v128_set_to_zero(&salt);
// allocate cipher
+ // FIXXME: why we do not can do this???
+// status = cipher_type_alloc(&aes_icm, &cipher, key_.getLength());
status = cipher_type_alloc(&aes_icm, &cipher, 30);
+ if( status )
+ return;
// init cipher
- status = cipher_init(cipher, key, direction_any);
+ status = cipher_init(cipher, key_.getBuf(), direction_any);
+ if( status )
+ {
+ cipher_dealloc(cipher);
+ return;
+ }
- //set iv
+ // set IV
// 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.
//
// IV = (k_s * 2^16) XOR (SSRC * 2^64) XOR (i * 2^16)
+ // sizeof(k_s) = 112 bit, random
- // sizeof(k_s) = 112, random
+// iv.v32[0] ^= 0;
+// iv.v32[1] ^= sender_id;
+// iv.v32[2] ^= (seq_nr >> 16);
+// iv.v32[3] ^= (seq_nr << 16);
- iv.v32[0] ^= 0;
- iv.v32[1] ^= sender_id;
- iv.v32[2] ^= (seq_nr >> 16);
- iv.v32[3] ^= (seq_nr << 16);
+ seq.v64[0] = seq_nr;
+ sid.v64[0] = sender_id;
+ v128_copy_octet_string(&salt, salt_.getBuf());
+ v128_left_shift(&salt, 16);
+ v128_left_shift(&sid, 64);
+ v128_left_shift(&seq, 16);
+ v128_xor(&iv, &salt, &sid);
+ v128_xor(&iv, &iv, &seq);
status = cipher_set_iv(cipher, &iv);
+ if( status )
+ cipher_dealloc(cipher);
length = buf.getLength();
diff --git a/cypher.h b/cypher.h
index 30147a1..1df207f 100644
--- a/cypher.h
+++ b/cypher.h
@@ -40,7 +40,9 @@ class Cypher
public:
Cypher() {};
virtual ~Cypher() {};
-
+
+ void setKey(Buffer key) {};
+ void setSalt(Buffer salt) {};
void cypher(Buffer& buf, seq_nr_t seq_nr, sender_id_t sender_id);
protected:
@@ -57,13 +59,17 @@ protected:
class AesIcmCypher : public Cypher
{
public:
-// AesIcmCypher() {};
-// ~AesIcmCypher() {};
+ AesIcmCypher() : key_(Buffer(0)), salt_(Buffer(14)) {};
+ void setKey(Buffer key);
+ void setSalt(Buffer salt);
void cypher(Buffer& buf, seq_nr_t seq_nr, sender_id_t sender_id);
protected:
Buffer getBitStream(u_int32_t length, seq_nr_t seq_nr, sender_id_t sender_id) { return Buffer(); };
+private:
+ Buffer key_;
+ Buffer salt_; // size: 112 bit
};
#endif
diff --git a/keyDerivation.cpp b/keyDerivation.cpp
index d6b1ca3..95b94d2 100644
--- a/keyDerivation.cpp
+++ b/keyDerivation.cpp
@@ -35,21 +35,26 @@ extern "C" {
#include <srtp/crypto_kernel.h>
}
-err_status_t KeyDerivation::init(const uint8_t key[30], const uint8_t salt[14])
+err_status_t KeyDerivation::init(Buffer key, Buffer salt)
{
extern cipher_type_t aes_icm;
err_status_t status = err_status_ok;
- for(uint8_t i = 0; i < 14; i++)
- salt_[i] = salt[i];
+ salt_ = salt;
// allocate cipher
+ // FIXXME: why we do not can do this??
+// status = cipher_type_alloc(&aes_icm, &cipher_, key.getLength());
status = cipher_type_alloc(&aes_icm, &cipher_, 30);
+ if( status )
+ return status;
// init cipher
- status = cipher_init(cipher_, key, direction_any);
+ status = cipher_init(cipher_, key.getBuf(), direction_any);
+ if( status )
+ cipher_dealloc(cipher_);
- return err_status_ok;
+ return status;
}
err_status_t KeyDerivation::setLogKDRate(const uint8_t log_rate)
@@ -63,7 +68,7 @@ err_status_t KeyDerivation::setLogKDRate(const uint8_t log_rate)
}
-err_status_t KeyDerivation::generate(satp_prf_label label, seq_nr_t seq_nr, uint8_t *key, uint32_t length)
+err_status_t KeyDerivation::generate(satp_prf_label label, seq_nr_t seq_nr, Buffer& key, uint32_t length)
{
err_status_t status = err_status_ok;
v128_t iv, salt, key_id;
@@ -83,21 +88,25 @@ err_status_t KeyDerivation::generate(satp_prf_label label, seq_nr_t seq_nr, uint
key_id.v32[0] = (label << 8);
key_id.v32[0] += r;
- v128_copy_octet_string(&salt, salt_);
+ v128_copy_octet_string(&salt, salt_.getBuf());
v128_xor(&iv, &salt, &key_id);
status = cipher_set_iv(cipher_, &iv);
+ if( status )
+ {
+ KeyDerivation::clear();
+ return status;
+ }
/* generate keystream output */
status = cipher_output(cipher_, key, length);
- return err_status_ok;
+ return status;
}
err_status_t KeyDerivation::clear()
{
- cipher_dealloc(cipher_);
- return err_status_ok;
+ return cipher_dealloc(cipher_);
}
diff --git a/keyDerivation.h b/keyDerivation.h
index 9033d30..c65df0e 100644
--- a/keyDerivation.h
+++ b/keyDerivation.h
@@ -52,14 +52,14 @@ public:
KeyDerivation() : ld_kdr_(-1), cipher_(NULL) {};
virtual ~KeyDerivation() {};
- err_status_t init(const uint8_t key[30], const uint8_t salt[14]);
+ err_status_t init(Buffer key, Buffer salt);
err_status_t setLogKDRate(const uint8_t ld_rate);
- err_status_t generate(satp_prf_label label, seq_nr_t seq_nr, uint8_t *key, uint32_t length);
+ err_status_t generate(satp_prf_label label, seq_nr_t seq_nr, Buffer& key, uint32_t length);
err_status_t clear();
protected:
int8_t ld_kdr_; // ld(key_derivation_rate)
- uint8_t salt_[14];
+ Buffer salt_;
cipher_t* cipher_;
};