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).
This commit is contained in:
Cedric BAIL 2015-03-17 08:50:34 +01:00
parent d4d22ca5ea
commit 8fd9770d95
6 changed files with 101 additions and 98 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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 *

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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_ */