[ACCEPTED]-Understanding engine initialization in OpenSSL-openssl
The problem with your original suggestion 20 is, as Martin said, that you need to initialise 19 the ENGINE. The problem with your edited 18 code was that you were doing ENGINE_new, which 17 is getting you a completely new ENGINE of 16 your own, which you then need to provide 15 with cipher methods, digest methods, etc. In 14 fact, for what you want (and what almost 13 everybody wants), just completely ignoring 12 all of the ENGINE stuff is the right choice.
Some 11 subsidiary problems:
- your strings were hex, but you needed a \x per character to actually get that hex byte at that position in the string, which I suspect was what you wanted.
- you were trying to hash 40 bytes from "data", which wasn't that long (actual effect: you'd end up partly hashing your result string)
- your expected result was (as far as I can tell) incorrect
- you would print out random characters to the terminal, since the HMAC function will produce 32 bytes of random binary data, not printable stuff.
The following code 10 compiles, works and passes the test. It's 9 a bit different to the example code you 8 found (since it still uses the individual 7 HMAC_* functions - useful if you want to 6 do your hashing bit by bit using HMAC_Update):
#include <openssl/engine.h>
#include <openssl/hmac.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
unsigned char* key = (unsigned char*) "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
unsigned char* data = (unsigned char*) "\x48\x69\x20\x54\x68\x65\x72\x65";
unsigned char* expected = (unsigned char*) "\x49\x2c\xe0\x20\xfe\x25\x34\xa5\x78\x9d\xc3\x84\x88\x06\xc7\x8f\x4f\x67\x11\x39\x7f\x08\xe7\xe7\xa1\x2c\xa5\xa4\x48\x3c\x8a\xa6";
unsigned char* result;
unsigned int result_len = 32;
int i;
HMAC_CTX ctx;
result = (unsigned char*) malloc(sizeof(char) * result_len);
ENGINE_load_builtin_engines();
ENGINE_register_all_complete();
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, key, 16, EVP_sha256(), NULL);
HMAC_Update(&ctx, data, 8);
HMAC_Final(&ctx, result, &result_len);
HMAC_CTX_cleanup(&ctx);
for (i=0; i!=result_len; i++)
{
if (expected[i]!=result[i])
{
printf("Got %02X instead of %02X at byte %d!\n", result[i], expected[i], i);
break;
}
}
if (i==result_len)
{
printf("Test ok!\n");
}
return 0;
}
Of 5 course, it doesn't answer your original 4 question about how to initialise ENGINEs, but 3 there's really no right answer to that without 2 having more context, which context turns 1 out not to be relevant in your situation...
Okay, turns out that you don't have to use 10 an engine but I'd misunderstood exactly 9 how not to use an explicit engine. I also 8 misunderstood how to properly format the 7 test vectors. In the end I looked at hmactest.c 6 which pretty much does all I want to do, I 5 just didn't understand the code.
The final 4 solution to what I was trying to do looks 3 like this:
int main() {
unsigned char* key = (unsigned char*) "Jefe";
unsigned char* data = (unsigned char*) "what do ya want for nothing?";
unsigned char* expected = (unsigned char*) "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843";
unsigned char* result;
unsigned int result_len = 32;
int i;
static char res_hexstring[32];
result = HMAC(EVP_sha256(), key, 4, data, 28, NULL, NULL);
for (i = 0; i < result_len; i++) {
sprintf(&(res_hexstring[i * 2]), "%02x", result[i]);
}
if (strcmp((char*) res_hexstring, (char*) expected) == 0) {
printf("Test ok, result length %d\n", result_len);
} else {
printf("Got %s instead of %s\n", res_hexstring, expected);
}
}
But since I was asking about something 2 entirely different, I'm unsure about what 1 to do with the original question. Suggestions?
It looks as though nothing is allocating 25 an engine, so the first use of e
is segfaulting. I 24 think you need to call ENGINE *ENGINE_new(void)
first.
(Note that 23 I've used OpenSSL, but I haven't used the 22 ENGINE
functions before.)
Update: I'm not really happy 21 with my own answer (I had to dash off to 20 tea, before). So my further notes are:
I've 19 had a bit of a look at the (long) man page for the 18
ENGINE
functions, and I'm not quite sure that 17 callingENGINE_new
is sufficient.I didn't notice that 16 the calls to the
HMAC_CTX_*
functions were taking 15 an uninitialized pointer, rather than a 14 pointer to an allocated structure.HMAC_CTX_init
will 13 try to write to the memory pointed to by 12 itsctx
parameter, which will segfault. You 11 need to declare and usectx
like this:HMAC_CTX ctx; HMAC_CTX_init(&ctx); HMAC_Init_ex(&ctx, key, 40, EVP_sha256(), e); ...
That 10 way you're allocating the structure on the 9 stack, and then passing a pointer to it.
The 8
HMAC
function doesn't take a pointer to aCTX
at 7 all, so apart from global or thread-local 6 storage, I'm not sure what it's connection 5 to theCTX
is. I think you can bypass that 4 by callingHMAC_Update
one-or-more times, followed 3 byHMAC_Final
to get the result. You'd need to allocate 2 space for that result, so something like 1 the following would work for that:unsigned int len; HMAC_Final(&ctx, result, &len);
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.