diff options
-rw-r--r-- | src/Makefile | 2 | ||||
-rw-r--r-- | src/cipher.c | 124 | ||||
-rw-r--r-- | src/cipher.h | 19 | ||||
-rw-r--r-- | src/key_derivation.c | 2 |
4 files changed, 97 insertions, 50 deletions
diff --git a/src/Makefile b/src/Makefile index a3c9997..45ae277 100644 --- a/src/Makefile +++ b/src/Makefile @@ -34,7 +34,7 @@ TARGET=$(shell uname -s) CC = gcc -CCFLAGS = -g -O2 -DANYTUN_02_COMPAT #-DNO_LIBGMP #-DNO_CRYPT +CCFLAGS = -g -O2 -DANYTUN_02_COMPAT #-DNO_LIBGMP -DNO_CRYPT LD = gcc LDFLAGS = -g -Wall -O2 -lgcrypt -lgpg-error -lgmp diff --git a/src/cipher.c b/src/cipher.c index 07c9f32..ff9e4e9 100644 --- a/src/cipher.c +++ b/src/cipher.c @@ -77,9 +77,7 @@ int cipher_init(cipher_t* c, const char* type) return -1; } -#ifndef NO_CRYPT - c->handle_ = 0; -#endif + c->params_ = NULL; c->key_.buf_ = NULL; c->key_.length_ = 0; @@ -209,6 +207,29 @@ int cipher_aesctr_init(cipher_t* c) if(!c->salt_.buf_) return -2; + if(c->params_) + free(c->params_); + c->params_ = malloc(sizeof(cipher_aesctr_param_t)); + if(!c->params_) + return -2; + + cipher_aesctr_param_t* params = c->params_; + +#ifndef NO_LIBGMP + mpz_init2(params->mp_ctr, 128); + mpz_init2(params->mp_sid_mux, 128); + mpz_init2(params->mp_seq, 128); +#endif + + params->ctr_.length_ = 16; + params->ctr_.buf_ = malloc(params->ctr_.length_); + if(!params->ctr_.buf_) { + free(c->params_); + c->params_ = NULL; + return -2; + } + + int algo; switch(c->key_length_) { case 128: algo = GCRY_CIPHER_AES128; break; @@ -220,7 +241,7 @@ int cipher_aesctr_init(cipher_t* c) } } - gcry_error_t err = gcry_cipher_open(&c->handle_, algo, GCRY_CIPHER_MODE_CTR, 0); + gcry_error_t err = gcry_cipher_open(¶ms->handle_, algo, GCRY_CIPHER_MODE_CTR, 0); if(err) { log_printf(ERR, "failed to open cipher: %s/%s", gcry_strerror(err), gcry_strsource(err)); return -1; @@ -234,22 +255,35 @@ void cipher_aesctr_close(cipher_t* c) if(!c) return; - if(c->handle_) - gcry_cipher_close(c->handle_); + if(c->params_) { + cipher_aesctr_param_t* params = c->params_; +#ifndef NO_LIBGMP + mpz_clear(params->mp_ctr); + mpz_clear(params->mp_sid_mux); + mpz_clear(params->mp_seq); +#endif + if(params->ctr_.buf_) + free(params->ctr_.buf_); + + if(params->handle_) + gcry_cipher_close(params->handle_); + + free(c->params_); + } } -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) +int 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; - result.length_ = 0; - - if(!c) - return result; + if(!c || !c->params_) + return -1; + cipher_aesctr_param_t* params = c->params_; + if(!params->ctr_.buf_) + return -1; + int ret = key_derivation_generate(kd, LABEL_SATP_SALT, seq_nr, c->salt_.buf_, c->salt_.length_); if(ret < 0) - return result; + return ret; int faked_msb = 0; if(!c->salt_.buf_[0]) { @@ -258,45 +292,50 @@ buffer_t cipher_aesctr_calc_ctr(cipher_t* c, key_derivation_t* kd, seq_nr_t seq_ } #ifndef NO_LIBGMP - mpz_t ctr, sid_mux, seq; - mpz_init2(ctr, 128); - mpz_init2(sid_mux, 128); - mpz_init2(seq, 128); - - mpz_import(ctr, c->salt_.length_, 1, 1, 0, 0, c->salt_.buf_); + mpz_import(params->mp_ctr, c->salt_.length_, 1, 1, 0, 0, c->salt_.buf_); - mpz_set_ui(sid_mux, mux); - mpz_mul_2exp(sid_mux, sid_mux, (sizeof(sender_id) * 8)); - mpz_add_ui(sid_mux, sid_mux, sender_id); - mpz_mul_2exp(sid_mux, sid_mux, 48); + mpz_set_ui(params->mp_sid_mux, mux); + mpz_mul_2exp(params->mp_sid_mux, params->mp_sid_mux, (sizeof(sender_id) * 8)); + mpz_add_ui(params->mp_sid_mux, params->mp_sid_mux, sender_id); + mpz_mul_2exp(params->mp_sid_mux, params->mp_sid_mux, 48); - mpz_set_ui(seq, seq_nr); + mpz_set_ui(params->mp_seq, seq_nr); - mpz_xor(ctr, ctr, sid_mux); - mpz_xor(ctr, ctr, seq); + mpz_xor(params->mp_ctr, params->mp_ctr, params->mp_sid_mux); + mpz_xor(params->mp_ctr, params->mp_ctr, params->mp_seq); - mpz_mul_2exp(ctr, ctr, 16); + mpz_mul_2exp(params->mp_ctr, params->mp_ctr, 16); - result.buf_ = mpz_export(NULL, (size_t*)&result.length_, 1, 1, 0, 0, ctr); - mpz_clear(ctr); - mpz_clear(sid_mux); - mpz_clear(seq); + int out_size = (mpz_sizeinbase(params->mp_ctr, 2) + 7) / 8; + if(out_size > params->ctr_.length_) { + log_printf(ERR, "computed cipher ctr is too big ?!?"); + return -1; + } + mpz_export(params->ctr_.buf_, NULL, 1, 1, 0, 0, params->mp_ctr); #endif #ifndef ANYTUN_02_COMPAT if(faked_msb) { c->salt_.buf_[0] = 0; - result.buf_[0] = 0; + params->ctr_.buf_[0] = 0; } #endif - return result; + return 0; } 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) + if(!c || !c->params_) { + log_printf(ERR, "cipher not initialized"); + return -1; + } + + cipher_aesctr_param_t* params = c->params_; + if(!params->ctr_.buf_) { + log_printf(ERR, "cipher not initialized"); return -1; + } if(!kd) { log_printf(ERR, "no key derivation supplied"); @@ -309,34 +348,33 @@ int32_t cipher_aesctr_crypt(cipher_t* c, key_derivation_t* kd, u_int8_t* in, u_i gcry_error_t err; if(ret) { // a new key got generated - err = gcry_cipher_setkey(c->handle_, c->key_.buf_, c->key_.length_); + err = gcry_cipher_setkey(params->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 -1; } } // no new key got generated else { - err = gcry_cipher_reset(c->handle_); + err = gcry_cipher_reset(params->handle_); if(err) { log_printf(ERR, "failed to reset cipher: %s/%s", gcry_strerror(err), gcry_strsource(err)); return -1; } } - buffer_t ctr = cipher_aesctr_calc_ctr(c, kd, seq_nr, sender_id, mux); - if(!ctr.buf_) { + ret = cipher_aesctr_calc_ctr(c, kd, seq_nr, sender_id, mux); + if(ret < 0) { log_printf(ERR, "failed to calculate cipher CTR"); - return -1; + return ret; } - err = gcry_cipher_setctr(c->handle_, ctr.buf_, ctr.length_); - free(ctr.buf_); + err = gcry_cipher_setctr(params->handle_, params->ctr_.buf_, params->ctr_.length_); if(err) { log_printf(ERR, "failed to set cipher CTR: %s/%s", gcry_strerror(err), gcry_strsource(err)); return -1; } - err = gcry_cipher_encrypt(c->handle_, out, olen, in, ilen); + err = gcry_cipher_encrypt(params->handle_, out, olen, in, ilen); if(err) { log_printf(ERR, "failed to de/encrypt packet: %s/%s", gcry_strerror(err), gcry_strsource(err)); return -1; diff --git a/src/cipher.h b/src/cipher.h index 036eb72..137540b 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -39,7 +39,7 @@ #include <gcrypt.h> #include "key_derivation.h" #else -typedef u_int8_t* key_derivation_t; +typedef u_int8_t key_derivation_t; #endif enum cipher_type_enum { c_unknown, c_null, c_aes_ctr }; @@ -50,9 +50,7 @@ struct cipher_struct { u_int16_t key_length_; buffer_t key_; buffer_t salt_; -#ifndef NO_CRYPT - gcry_cipher_hd_t handle_; -#endif + void* params_; }; typedef struct cipher_struct cipher_t; @@ -66,9 +64,20 @@ int32_t cipher_null_crypt(u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t #ifndef NO_CRYPT +struct cipher_aesctr_param_struct { + gcry_cipher_hd_t handle_; + buffer_t ctr_; +#ifndef NO_LIBGMP + mpz_t mp_ctr; + mpz_t mp_sid_mux; + mpz_t mp_seq; +#endif +}; +typedef struct cipher_aesctr_param_struct cipher_aesctr_param_t; + int cipher_aesctr_init(cipher_t* c); void cipher_aesctr_close(cipher_t* c); -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); +int cipher_aesctr_calc_ctr(cipher_t* c, key_derivation_t* kd, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux); 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); #endif diff --git a/src/key_derivation.c b/src/key_derivation.c index 070cade..aec90a1 100644 --- a/src/key_derivation.c +++ b/src/key_derivation.c @@ -277,7 +277,7 @@ int key_derivation_aesctr_calc_ctr(key_derivation_t* kd, seq_nr_t* r, satp_prf_l int out_size = (mpz_sizeinbase(params->mp_ctr, 2) + 7) / 8; if(out_size > params->ctr_.length_) { - log_printf(ERR, "computed ctr is too big ?!?"); + log_printf(ERR, "computed key derivation ctr is too big ?!?"); return -1; } mpz_export(params->ctr_.buf_, NULL, 1, 1, 0, 0, params->mp_ctr); |