Reputation: 245
I am trying the code bellow. The thing is: some times work and some times doesn't! I am using the OpenSSL library, but I believe my mistake is something simple, C related.
int test_c(string to_sign, string key)
{
const void* key_void = (const void*)key.c_str();
int key_size = key.size();
const unsigned char* data_char = (const unsigned char*)to_sign.c_str();
int data_size = to_sign.size();
unsigned int res_f_len = data_size*8;
unsigned char* res_f = (unsigned char*) malloc(sizeof(unsigned char)*res_f_len);
HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, key_void, key_size, EVP_sha256(), NULL);
HMAC_Update(&ctx, data_char, data_size);
HMAC_Final(&ctx, res_f, &res_f_len);
HMAC_CTX_cleanup(&ctx);
return strlen(res_f);
}
When I say it doesn't work, I mean, for the same data and key, different results are returned!
Upvotes: 1
Views: 417
Reputation: 17936
Rather than return strlen(res_f);
as the length of the output buffer, you need to return res_f_len
.
There are three things that could happen with strlen()
in your code:
strlen
will return a length that's shorter than the HMAC message digest.strlen
will read beyond the message digest, leading to one of two outcomes:
strlen
reads through garbage in memory after the message digest, eventually stopping on a random 0. strlen
returns a value that's way too large.strlen
returns the actual length of the message digest.So, only in the last scenario will you get the right value. That pretty much seems wrong.
It appears tht HMAC_Final
does update the length argument you pass to it. (See the example in the top-voted answer to this StackOverflow question.) That's why you pass a pointer-to-int. You should just return this updated value.
Upvotes: 1