summaryrefslogtreecommitdiff
path: root/src/cipher.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cipher.c')
-rw-r--r--src/cipher.c104
1 files changed, 53 insertions, 51 deletions
diff --git a/src/cipher.c b/src/cipher.c
index 8c086ee..0ca48b4 100644
--- a/src/cipher.c
+++ b/src/cipher.c
@@ -51,17 +51,28 @@ int cipher_init(cipher_t* c, const char* type)
if(!c)
return -1;
+ c->key_length_ = 0;
+
c->type_ = unknown;
if(!strcmp(type, "null"))
c->type_ = null;
- else if(!strcmp(type, "aes-ctr"))
+ else if(!strncmp(type, "aes-ctr", 7)) {
c->type_ = aes_ctr;
+ if(type[7] == 0) {
+ c->key_length_ = 128;
+ }
+ else if(type[7] != '-')
+ return -1;
+ else {
+ const char* tmp = &type[8];
+ c->key_length_ = atoi(tmp);
+ }
+ }
else {
log_printf(ERR, "unknown cipher type");
return -1;
}
- c->key_length_ = 0;
c->handle_ = 0;
c->key_.buf_ = NULL;
@@ -72,47 +83,11 @@ int cipher_init(cipher_t* c, const char* type)
int ret = 0;
if(c->type_ == aes_ctr)
- ret = cipher_aesctr_init(c, 128);
+ ret = cipher_aesctr_init(c);
return ret;
}
-void cipher_set_key(cipher_t* c, u_int8_t* key, u_int32_t len)
-{
- if(!c || !key)
- return;
- if(c->type_ == null)
- return;
-
- if(c->key_.buf_)
- free(c->key_.buf_);
- c->key_.buf_ = malloc(len);
- if(!c->key_.buf_) {
- c->key_.length_ = 0;
- return;
- }
- memcpy(c->key_.buf_, key, len);
- c->key_.length_ = len;
-}
-
-void cipher_set_salt(cipher_t* c, u_int8_t* salt, u_int32_t len)
-{
- if(!c || !salt)
- return;
- if(c->type_ == null)
- return;
-
- if(c->salt_.buf_)
- free(c->salt_.buf_);
- c->salt_.buf_ = malloc(len);
- if(!c->salt_.buf_) {
- c->salt_.length_ = 0;
- return;
- }
- memcpy(c->salt_.buf_, salt, len);
- c->salt_.length_ = len;
-}
-
void cipher_close(cipher_t* c)
{
if(!c)
@@ -127,7 +102,8 @@ void cipher_close(cipher_t* c)
free(c->salt_.buf_);
}
-void cipher_encrypt(cipher_t* c, plain_packet_t* in, encrypted_packet_t* out, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
+
+void cipher_encrypt(cipher_t* c, key_derivation_t* kd, plain_packet_t* in, encrypted_packet_t* out, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
{
if(!c)
return;
@@ -137,7 +113,7 @@ void cipher_encrypt(cipher_t* c, plain_packet_t* in, encrypted_packet_t* out, se
len = cipher_null_crypt(plain_packet_get_packet(in), plain_packet_get_length(in),
encrypted_packet_get_payload(out), encrypted_packet_get_payload_length(out));
else if(c->type_ == aes_ctr)
- len = cipher_aesctr_crypt(c, plain_packet_get_packet(in), plain_packet_get_length(in),
+ len = cipher_aesctr_crypt(c, kd, plain_packet_get_packet(in), plain_packet_get_length(in),
encrypted_packet_get_payload(out), encrypted_packet_get_payload_length(out),
seq_nr, sender_id, mux);
else {
@@ -152,7 +128,7 @@ void cipher_encrypt(cipher_t* c, plain_packet_t* in, encrypted_packet_t* out, se
encrypted_packet_set_payload_length(out, len);
}
-void cipher_decrypt(cipher_t* c, encrypted_packet_t* in, plain_packet_t* out)
+void cipher_decrypt(cipher_t* c, key_derivation_t* kd, encrypted_packet_t* in, plain_packet_t* out)
{
if(!c)
return;
@@ -162,7 +138,7 @@ void cipher_decrypt(cipher_t* c, encrypted_packet_t* in, plain_packet_t* out)
len = cipher_null_crypt(encrypted_packet_get_payload(in), encrypted_packet_get_payload_length(in),
plain_packet_get_packet(out), plain_packet_get_length(out));
else if(c->type_ == aes_ctr)
- len = cipher_aesctr_crypt(c, encrypted_packet_get_payload(in), encrypted_packet_get_payload_length(in),
+ len = cipher_aesctr_crypt(c, kd, encrypted_packet_get_payload(in), encrypted_packet_get_payload_length(in),
plain_packet_get_packet(out), plain_packet_get_length(out),
encrypted_packet_get_seq_nr(in), encrypted_packet_get_sender_id(in),
encrypted_packet_get_mux(in));
@@ -184,18 +160,18 @@ u_int32_t cipher_null_crypt(u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32
/* ---------------- AES-Ctr Cipher ---------------- */
-int cipher_aesctr_init(cipher_t* c, int key_length)
+int cipher_aesctr_init(cipher_t* c)
{
if(!c)
return -1;
- c->key_length_ = key_length;
-
int algo;
- switch(key_length) {
+ switch(c->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);
+ log_printf(ERR, "cipher key length of %d Bits is not supported", c->key_length_);
return -1;
}
}
@@ -218,7 +194,7 @@ void cipher_aesctr_close(cipher_t* c)
gcry_cipher_close(c->handle_);
}
-buffer_t cipher_aesctr_calc_ctr(cipher_t* c, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
+buffer_t cipher_aesctr_calc_ctr(cipher_t* c, key_derivation_t* kd, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
{
buffer_t result;
result.buf_ = NULL;
@@ -226,6 +202,16 @@ buffer_t cipher_aesctr_calc_ctr(cipher_t* c, seq_nr_t seq_nr, sender_id_t sender
if(!c)
return result;
+
+ if(!c->salt_.buf_) {
+ c->salt_.length_ = 14;
+ c->salt_.buf_ = malloc(c->salt_.length_);
+ if(c->salt_.buf_)
+ return result;
+ }
+ int ret = key_derivation_generate(kd, LABEL_SATP_SALT, seq_nr, c->salt_.buf_, c->salt_.length_);
+ if(ret)
+ return result;
mpz_t ctr, sid_mux, seq;
mpz_init2(ctr, 128);
@@ -263,20 +249,36 @@ buffer_t cipher_aesctr_calc_ctr(cipher_t* c, seq_nr_t seq_nr, sender_id_t sender
return result;
}
-u_int32_t cipher_aesctr_crypt(cipher_t* c, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
+u_int32_t cipher_aesctr_crypt(cipher_t* c, key_derivation_t* kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
{
if(!c || !c->key_.buf_ || !c->salt_.buf_) {
log_printf(ERR, "cipher not initialized or no key or salt set");
return 0;
}
+ if(!kd) {
+ log_printf(ERR, "no key derivation supplied");
+ return 0;
+ }
+
+
+ if(!c->key_.buf_) {
+ c->key_.length_ = c->key_length_/8;
+ c->key_.buf_ = malloc(c->key_.length_);
+ if(c->key_.buf_)
+ return 0;
+ }
+ int ret = key_derivation_generate(kd, LABEL_SATP_ENCRYPTION, seq_nr, c->key_.buf_, c->key_.length_);
+ if(ret)
+ return 0;
+
gcry_error_t err = gcry_cipher_setkey(c->handle_, c->key_.buf_, c->key_.length_);
if(err) {
log_printf(ERR, "failed to set cipher key: %s/%s", gcry_strerror(err), gcry_strsource(err));
return 0;
}
- buffer_t ctr = cipher_aesctr_calc_ctr(c, seq_nr, sender_id, mux);
+ buffer_t ctr = cipher_aesctr_calc_ctr(c, kd, seq_nr, sender_id, mux);
if(!ctr.buf_) {
log_printf(ERR, "failed to calculate cipher CTR");
return 0;