From 7f67e79ddcacf9c0f98ae9749bc1c61d75570ce1 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Sun, 4 Jan 2009 14:21:20 +0000 Subject: get rid of some mallocs and mpz_inits at cipher --- src/cipher.c | 124 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 81 insertions(+), 43 deletions(-) (limited to 'src/cipher.c') 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; -- cgit v1.2.3