From 9da5a7726b28cd29c1da55ee8f899e3febc5f4c8 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Fri, 2 Jan 2009 11:11:52 +0000 Subject: key derivation seems to work now --- src/Makefile | 2 +- src/key_derivation.c | 213 +++++++++++++++++++++++++++++++++++---------------- src/key_derivation.h | 17 ++-- src/uanytun.c | 22 +++--- 4 files changed, 171 insertions(+), 83 deletions(-) (limited to 'src') diff --git a/src/Makefile b/src/Makefile index 975c375..3b3be02 100644 --- a/src/Makefile +++ b/src/Makefile @@ -42,7 +42,7 @@ ifeq ($(TARGET),Linux) LDFLAGS += -ldl endif ifeq ($(TARGET),OpenBSD) - CCFLAGS += -I/usr/local/include -DNO_UDPV6 -DNO_SEC_MEM + CCFLAGS += -I/usr/local/include -DNO_UDPV6 LDFLAGS += -L/usr/local/lib endif diff --git a/src/key_derivation.c b/src/key_derivation.c index 5e3f2c5..49fb2a2 100644 --- a/src/key_derivation.c +++ b/src/key_derivation.c @@ -38,29 +38,39 @@ #include "log.h" +#include #include #include -int key_derivation_init(key_derivation_t* kd, const char* type, u_int8_t* key, u_int32_t key_len, u_int8_t* salt, u_int32_t salt_len) +int key_derivation_init(key_derivation_t* kd, const char* type, int8_t ld_kdr, u_int8_t* key, u_int32_t key_len, u_int8_t* salt, u_int32_t salt_len) { if(!kd) return -1; - kd->type_ = unknown; + kd->type_ = kd_unknown; if(!strcmp(type, "null")) - kd->type_ = null; + kd->type_ = kd_null; else if(!strcmp(type, "aes-ctr")) - kd->type_ = aes_ctr; + kd->type_ = kd_aes_ctr; else { log_printf(ERR, "unknown key derivation type"); return -1; } - kd->ld_kdr_ = -1; + kd->ld_kdr_ = ld_kdr; + if(ld_kdr > (sizeof(seq_nr_t) * 8)) + kd->ld_kdr_ = sizeof(seq_nr_t) * 8; + kd->key_length_ = key_len * sizeof(key[0]) * 8; kd->handle_ = 0; + int i; + for(i = 0; ikey_store_[i].buf_ = NULL; + kd->key_store_[i].length_ = 0; + } + if(!key) { kd->master_key_.buf_ = NULL; kd->master_key_.length_ = 0; @@ -89,8 +99,11 @@ int key_derivation_init(key_derivation_t* kd, const char* type, u_int8_t* key, u } int ret = 0; - if(kd->type_ == aes_ctr) - ret = key_derivation_aesctr_init(kd, key, key_len, salt, salt_len); + if(kd->type_ == kd_aes_ctr) + ret = key_derivation_aesctr_init(kd, kd->key_length_); + + if(ret) + key_derivation_close(kd); return ret; } @@ -100,53 +113,78 @@ void key_derivation_close(key_derivation_t* kd) if(!kd) return; - if(kd->type_ == aes_ctr) + if(kd->type_ == kd_aes_ctr) key_derivation_aesctr_close(kd); if(kd->master_key_.buf_) free(kd->master_key_.buf_); if(kd->master_salt_.buf_) free(kd->master_salt_.buf_); + + int i; + for(i = 0; ikey_store_[i].buf_) + free(kd->key_store_[i].buf_); + } } -void key_derivation_generate(key_derivation_t* kd, satp_prf_label_t label, seq_nr_t seq_nr, u_int8_t* key, u_int32_t len) +int key_derivation_generate(key_derivation_t* kd, satp_prf_label_t label, seq_nr_t seq_nr, u_int8_t* key, u_int32_t len) { - if(!kd) - return; + if(!kd || !key) + return -1; + + if(label >= KD_LABEL_COUNT) { + log_printf(ERR, "label 0x%02X out of range", label); + return -1; + } - if(kd->type_ == null) - key_derivation_null_generate(key, len); - else if(kd->type_ == aes_ctr) - key_derivation_aesctr_generate(kd, label, seq_nr, key, len); + int ret = 0; + if(kd->type_ == kd_null) + ret = key_derivation_null_generate(key, len); + else if(kd->type_ == kd_aes_ctr) + ret = key_derivation_aesctr_generate(kd, label, seq_nr, key, len); else { - log_printf(ERR, "unknown cipher type"); - return; + log_printf(ERR, "unknown key derivation type"); + return -1; } + return ret; } /* ---------------- NULL Key Derivation ---------------- */ -void key_derivation_null_generate(u_int8_t* key, u_int32_t len) +int key_derivation_null_generate(u_int8_t* key, u_int32_t len) { memset(key, 0, len); + return 0; } /* ---------------- AES-Ctr Key Derivation ---------------- */ -int key_derivation_aesctr_init(key_derivation_t* kd, u_int8_t* key, u_int32_t key_len, u_int8_t* salt, u_int32_t salt_len) +int key_derivation_aesctr_init(key_derivation_t* kd, u_int16_t key_length) { if(!kd) return -1; - gcry_error_t err = gcry_cipher_open(&kd->handle_, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR, 0); + int algo; + switch(key_length) { + case 128: algo = GCRY_CIPHER_AES128; break; + case 192: algo = GCRY_CIPHER_AES192; break; + case 256: algo = GCRY_CIPHER_AES256; break; + default: { + log_printf(ERR, "key length of %d Bits is not supported", key_length); + return -1; + } + } + + gcry_error_t err = gcry_cipher_open(&kd->handle_, algo, GCRY_CIPHER_MODE_CTR, 0); if(err) { - log_printf(ERR, "failed to open cipher: %s/%s", gcry_strerror(err), gcry_strsource(err)); + log_printf(ERR, "failed to open key derivation cipher: %s/%s", gcry_strerror(err), gcry_strsource(err)); return -1; } err = gcry_cipher_setkey(kd->handle_, kd->master_key_.buf_, kd->master_key_.length_); if(err) { - log_printf(ERR, "failed to set cipher key: %s/%s", gcry_strerror(err), gcry_strsource(err)); + log_printf(ERR, "failed to set key derivation key: %s/%s", gcry_strerror(err), gcry_strsource(err)); return -1; } @@ -162,27 +200,21 @@ void key_derivation_aesctr_close(key_derivation_t* kd) gcry_cipher_close(kd->handle_); } -buffer_t key_derivation_aesctr_calc_ctr(key_derivation_t* kd, satp_prf_label_t label, seq_nr_t seq_nr) +int key_derivation_aesctr_calc_ctr(key_derivation_t* kd, buffer_t* result, satp_prf_label_t label, seq_nr_t seq_nr) { - buffer_t result; - result.buf_ = NULL; - result.length_ = 0; - - if(!kd) - return result; + if(!kd || !result) + return -1; - // 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 =