From 8fd9770d95c32bad17af1963b9e1919888a5ab88 Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Tue, 17 Mar 2015 08:50:34 +0100 Subject: [PATCH] emile: reduce code duplication between gnutls and openssl backend. Add a visible emile_binbuf_sha1 implementation and deduplicate emile_pbkdf2_sha1 (but does not explicitely expose it). --- src/lib/emile/emile_cipher.c | 9 ++++++ src/lib/emile/emile_cipher.h | 6 ++++ src/lib/emile/emile_cipher_gnutls.c | 57 +++++----------------------------- src/lib/emile/emile_cipher_openssl.c | 58 ++++++---------------------------- src/lib/emile/emile_main.c | 60 ++++++++++++++++++++++++++++++++++++ src/lib/emile/emile_private.h | 9 ++++++ 6 files changed, 101 insertions(+), 98 deletions(-) diff --git a/src/lib/emile/emile_cipher.c b/src/lib/emile/emile_cipher.c index 3c5fd18..544f271 100644 --- a/src/lib/emile/emile_cipher.c +++ b/src/lib/emile/emile_cipher.c @@ -13,6 +13,15 @@ Eina_Bool _emile_cipher_init(void) return EINA_FALSE; } +EAPI Eina_Bool +emile_binbuf_sha1(const char *key EINA_UNUSED, + int key_len EINA_UNUSED, + const Eina_Binbuf *data EINA_UNUSED, + unsigned char digest[20]) +{ + return EINA_FALSE; +} + EAPI Eina_Binbuf * emile_binbuf_cipher(const Eina_Binbuf *data EINA_UNUSED, const char *key EINA_UNUSED, diff --git a/src/lib/emile/emile_cipher.h b/src/lib/emile/emile_cipher.h index 8009754..69379d8 100644 --- a/src/lib/emile/emile_cipher.h +++ b/src/lib/emile/emile_cipher.h @@ -26,6 +26,12 @@ EAPI Eina_Binbuf *emile_binbuf_cipher(const Eina_Binbuf *in, EAPI Eina_Binbuf *emile_binbuf_decipher(const Eina_Binbuf *in, const char *key, unsigned int length); +EAPI Eina_Bool emile_binbuf_sha1(const char *key, + unsigned int key_len, + const Eina_Binbuf *data, + unsigned char digest[20]); + + EAPI Emile_SSL *emile_cipher_server_listen(Emile_Cipher_Type t); EAPI Emile_SSL *emile_cipher_client_connect(Emile_SSL *server, int fd); EAPI Emile_SSL *emile_cipher_server_connect(Emile_Cipher_Type t); diff --git a/src/lib/emile/emile_cipher_gnutls.c b/src/lib/emile/emile_cipher_gnutls.c index 998ce88..d51ae8b 100644 --- a/src/lib/emile/emile_cipher_gnutls.c +++ b/src/lib/emile/emile_cipher_gnutls.c @@ -170,56 +170,15 @@ emile_hmac_sha1(const void *key, return EINA_TRUE; } -static Eina_Bool -emile_pbkdf2_sha1(const char *key, - int key_len, - const unsigned char *salt, - unsigned int salt_len, - int iter, - unsigned char *res, - int res_len) +EAPI Eina_Bool +emile_binbuf_sha1(const char *key, + unsigned int key_len, + const Eina_Binbuf *data, + unsigned char digest[20]) { - unsigned char digest[20]; - unsigned char tab[4]; - unsigned char *p = res; - unsigned char *buf; - unsigned int i; - int digest_len = 20; - int len = res_len; - int tmp_len; - int j, k; - - buf = alloca(salt_len + 4); - if (!buf) return EINA_FALSE; - - for (i = 1; len; len -= tmp_len, p += tmp_len, i++) - { - if (len > digest_len) - tmp_len = digest_len; - else - tmp_len = len; - - tab[0] = (unsigned char)(i & 0xff000000) >> 24; - tab[1] = (unsigned char)(i & 0x00ff0000) >> 16; - tab[2] = (unsigned char)(i & 0x0000ff00) >> 8; - tab[3] = (unsigned char)(i & 0x000000ff) >> 0; - - memcpy(buf, salt, salt_len); - memcpy(buf + salt_len, tab, 4); - if (!emile_hmac_sha1(key, key_len, buf, salt_len + 4, digest)) - return EINA_FALSE; - memcpy(p, digest, tmp_len); - - for (j = 1; j < iter; j++) - { - if (!emile_hmac_sha1(key, key_len, digest, 20, digest)) - return EINA_FALSE; - for (k = 0; k < tmp_len; k++) - p[k] ^= digest[k]; - } - } - - return EINA_TRUE; + return emile_hmac_sha1(key, key_len, + eina_binbuf_string_get(data), eina_binbuf_length_get(data), + digest); } EAPI Eina_Binbuf * diff --git a/src/lib/emile/emile_cipher_openssl.c b/src/lib/emile/emile_cipher_openssl.c index 18ce5c7..46143d0 100644 --- a/src/lib/emile/emile_cipher_openssl.c +++ b/src/lib/emile/emile_cipher_openssl.c @@ -57,56 +57,16 @@ _emile_cipher_init(void) return EINA_TRUE; } -static Eina_Bool -emile_pbkdf2_sha1(const char *key, - int key_len, - const unsigned char *salt, - unsigned int salt_len, - int iter, - unsigned char *res, - int res_len) +EAPI Eina_Bool +emile_binbuf_sha1(const char *key, + unsigned int key_len, + const Eina_Binbuf *data, + unsigned char digest[20]) { - unsigned char digest[20]; - unsigned char tab[4]; - unsigned char *p = res; - unsigned char *buf; - unsigned int i; - int digest_len = 20; - int len = res_len; - int tmp_len; - int j, k; - HMAC_CTX hctx; - - buf = alloca(salt_len + 4); - if (!buf) return EINA_FALSE; - - for (i = 1; len; len -= tmp_len, p += tmp_len, i++) - { - if (len > digest_len) - tmp_len = digest_len; - else - tmp_len = len; - - tab[0] = (unsigned char)(i & 0xff000000) >> 24; - tab[1] = (unsigned char)(i & 0x00ff0000) >> 16; - tab[2] = (unsigned char)(i & 0x0000ff00) >> 8; - tab[3] = (unsigned char)(i & 0x000000ff) >> 0; - - HMAC_Init(&hctx, key, key_len, EVP_sha1()); - HMAC_Update(&hctx, salt, salt_len); - HMAC_Update(&hctx, tab, 4); - HMAC_Final(&hctx, digest, NULL); - memcpy(p, digest, tmp_len); - - for (j = 1; j < iter; j++) - { - HMAC(EVP_sha1(), key, key_len, digest, 20, digest, NULL); - for (k = 0; k < tmp_len; k++) - p[k] ^= digest[k]; - } - HMAC_cleanup(&hctx); - } - + HMAC(EVP_sha1(), + key, key_len, + eina_binbuf_string_get(data), eina_binbuf_length_get(data), + digest, NULL); return EINA_TRUE; } diff --git a/src/lib/emile/emile_main.c b/src/lib/emile/emile_main.c index eb18a61..b8712fc 100644 --- a/src/lib/emile/emile_main.c +++ b/src/lib/emile/emile_main.c @@ -104,3 +104,63 @@ emile_shutdown(void) return _emile_init_count; } + +/* For the moment, we have just one function shared accross both cipher + * backend, so here it is. */ +Eina_Bool +emile_pbkdf2_sha1(const char *key, + unsigned int key_len, + const unsigned char *salt, + unsigned int salt_len, + unsigned int iter, + unsigned char *res, + unsigned int res_len) +{ + Eina_Binbuf *step1, *step2; + unsigned char *buf; + unsigned char *p = res; + unsigned char digest[20]; + unsigned char tab[4]; + unsigned int len = res_len; + unsigned int tmp_len; + unsigned int i, j, k; + + buf = alloca(salt_len + 4); + if (!buf) return EINA_FALSE; + + step1 = eina_binbuf_manage_read_only_new_length(buf, salt_len + 4); + if (!step1) return EINA_FALSE; + step2 = eina_binbuf_manage_read_only_new_length(digest, 20); + if (!step2) return EINA_FALSE; + + for (i = 1; len; len -= tmp_len, p += tmp_len, i++) + { + tmp_len = (len > 20) ? 20 : len; + + tab[0] = (unsigned char)(i & 0xff000000) >> 24; + tab[1] = (unsigned char)(i & 0x00ff0000) >> 16; + tab[2] = (unsigned char)(i & 0x0000ff00) >> 8; + tab[3] = (unsigned char)(i & 0x000000ff) >> 0; + + memcpy(buf, salt, salt_len); + memcpy(buf + salt_len, tab, 4); + + if (!emile_binbuf_sha1(key, key_len, step1, digest)) + return EINA_FALSE; + + memcpy(p, digest, tmp_len); + + for (j = 1; j < iter; j++) + { + if (!emile_binbuf_sha1(key, key_len, step2, digest)) + return EINA_FALSE; + for (k = 0; k < tmp_len; k++) + p[k] ^= digest[k]; + } + } + + eina_binbuf_free(step1); + eina_binbuf_free(step2); + + return EINA_TRUE; +} diff --git a/src/lib/emile/emile_private.h b/src/lib/emile/emile_private.h index f6a005d..cba9022 100644 --- a/src/lib/emile/emile_private.h +++ b/src/lib/emile/emile_private.h @@ -34,4 +34,13 @@ typedef enum Eina_Bool _emile_cipher_init(void); +Eina_Bool +emile_pbkdf2_sha1(const char *key, + unsigned int key_len, + const unsigned char *salt, + unsigned int salt_len, + unsigned int iter, + unsigned char *res, + unsigned int res_len); + #endif /* EMILE_PRIVATE_H_ */ -- 2.7.4