summaryrefslogtreecommitdiff
path: root/keyDerivation.cpp
diff options
context:
space:
mode:
authorErwin Nindl <nine@wirdorange.org>2007-11-07 19:08:25 +0000
committerErwin Nindl <nine@wirdorange.org>2007-11-07 19:08:25 +0000
commitdd056636dd2cd8c83822ebecfc2448cf8b4b713c (patch)
treee2ca8e3f9565f7da7a7bbbd9a8d9ebd317b2e5b1 /keyDerivation.cpp
parenti bin da beste deshalb haut des jetzt endlich so hin (diff)
* TunDevice: changed 'char* getTypeString()' to 'const char* getTypeString()'
to fix warning: deprecated conversion from string constant to ‘char*’ * removed libsrtp, use libgcrypt instead now * added buffer funcitons TODO: * fix IV issues * add authentification
Diffstat (limited to 'keyDerivation.cpp')
-rw-r--r--keyDerivation.cpp113
1 files changed, 70 insertions, 43 deletions
diff --git a/keyDerivation.cpp b/keyDerivation.cpp
index 95b94d2..f8e3c55 100644
--- a/keyDerivation.cpp
+++ b/keyDerivation.cpp
@@ -31,82 +31,109 @@
#include "keyDerivation.h"
+#include <stdexcept>
+#include <iostream>
+#include <string>
+
extern "C" {
-#include <srtp/crypto_kernel.h>
+#include <gcrypt.h>
}
-err_status_t KeyDerivation::init(Buffer key, Buffer salt)
+const char* KeyDerivation::MIN_GCRYPT_VERSION = "1.2.3";
+
+void KeyDerivation::init(Buffer key, Buffer salt)
{
- extern cipher_type_t aes_icm;
- err_status_t status = err_status_ok;
+ gcry_error_t err;
+ if( !gcry_check_version( MIN_GCRYPT_VERSION ) )
+ {
+ std::cerr << "Invalid Version of libgcrypt, should be >= " << MIN_GCRYPT_VERSION << std::endl;
+ return;
+ }
- salt_ = salt;
+ /* Allocate a pool of 16k secure memory. This also drops priviliges
+ * on some systems. */
+ err = gcry_control(GCRYCTL_INIT_SECMEM, 16384, 0);
+ if( err )
+ {
+ std::cerr << "Failed to allocate 16k secure memory: " << gpg_strerror( err ) << std::endl;
+ return;
+ }
- // 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;
+ /* Tell Libgcrypt that initialization has completed. */
+ err = gcry_control(GCRYCTL_INITIALIZATION_FINISHED);
+ if( err )
+ {
+ std::cerr << "Failed to finish the initialization of libgcrypt" << gpg_strerror( err ) << std::endl;
+ return;
+ }
- // init cipher
- status = cipher_init(cipher_, key.getBuf(), direction_any);
- if( status )
- cipher_dealloc(cipher_);
+ err = gcry_cipher_open( &cipher_, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR, 0 );
+ if( err )
+ {
+ std::cerr << "Failed to open cipher: " << gpg_strerror( err ) << std::endl;
+ return;
+ }
- return status;
}
-err_status_t KeyDerivation::setLogKDRate(const uint8_t log_rate)
+void KeyDerivation::setLogKDRate(const uint8_t log_rate)
{
if( log_rate < 49 )
- {
ld_kdr_ = log_rate;
- return err_status_ok;
- }
- return err_status_bad_param;
}
-err_status_t KeyDerivation::generate(satp_prf_label label, seq_nr_t seq_nr, Buffer& key, uint32_t length)
+void KeyDerivation::generate(satp_prf_label label, seq_nr_t seq_nr, Buffer& key, u_int32_t length)
{
- err_status_t status = err_status_ok;
- v128_t iv, salt, key_id;
- uint8_t r = 0;
+ gcry_error_t err;
+ u_int8_t r = 0;
+ Buffer iv(16);
+
+ u_int8_t tmp_key_id[16];
- v128_set_to_zero(&iv);
- v128_set_to_zero(&salt);
- v128_set_to_zero(&key_id);
+ // see at: http://tools.ietf.org/html/rfc3711#section-4.3
+ // * Let r = index DIV key_derivation_rate (with DIV as defined above).
+ // * Let key_id = <label> || r.
+ // * Let x = key_id XOR master_salt, where key_id and master_salt are
+ // aligned so that their least significant bits agree (right-
+ // alignment).
+ //
- // look at: http://tools.ietf.org/html/rfc3711#section-4.3
if( ld_kdr_ == -1 ) // means key_derivation_rate = 0
r = 0;
else
// FIXXME: kdr can be greater than 2^32 (= 2^48)
r = seq_nr / ( 0x01 << ld_kdr_ );
- key_id.v32[0] = (label << 8);
- key_id.v32[0] += r;
- v128_copy_octet_string(&salt, salt_.getBuf());
- v128_xor(&iv, &salt, &key_id);
- status = cipher_set_iv(cipher_, &iv);
- if( status )
+ // FIXXME: why i cant access key_id via operator []?
+ for(u_int8_t i=0; i<sizeof(tmp_key_id); i++)
+ tmp_key_id[i] = 0x00;
+
+ tmp_key_id[0] = r;
+ tmp_key_id[1] = label;
+
+ Buffer key_id(tmp_key_id, 16);
+
+ iv = key_id ^ salt_;
+
+ err = gcry_cipher_reset( cipher_ );
+ if( err )
{
- KeyDerivation::clear();
- return status;
+ std::cerr << "Failed to reset cipher: " << gpg_strerror( err ) << std::endl;
}
- /* generate keystream output */
- status = cipher_output(cipher_, key, length);
-
- return status;
+ err = gcry_cipher_encrypt( cipher_, key, key.getLength(), 0, 0 );
+ if( err )
+ {
+ std::cerr << "Failed to generate cipher bitstream: " << gpg_strerror( err ) << std::endl;
+ }
}
-err_status_t KeyDerivation::clear()
+void KeyDerivation::clear()
{
- return cipher_dealloc(cipher_);
+ gcry_cipher_close( cipher_ );
}