6

This is a very basic question, but what is the difference between EVP and HMAC? EVP is a message digest, but how does that differ from what is generated by HMAC?

2 Answers 2

7

... what is the difference between EVP and HMAC

EVP_* functions are a high level interface. HMAC_*, AES_* and friends are lower level primitives. You can work with either, but its recommended you work with the EVP_* functions. The HMAC_* routines are software based and don't use hardware.

The EVP_* functions will allow you to easily swap in different hashes and the code essentially remains the same. And you will take advantage of hardware acceleration, like AES-NI for an AES-CMAC, if available.

Here's an OpenSSL example based on https://www.openssl.org/docs/crypto/EVP_DigestInit.html.

EVP_MD_CTX* mdctx = NULL; const EVP_MD* md = NULL; unsigned char md_value[EVP_MAX_MD_SIZE]; int md_len = 0; char message[] = "Now is the time for all good men to " "come to the aide of their country\n"; OpenSSL_add_all_digests(); md = EVP_get_digestbyname("SHA1"); mdctx = EVP_MD_CTX_create(); if(!EVP_DigestInit_ex(mdctx, md, NULL)) handleError(); if(!EVP_DigestUpdate(mdctx, message, strlen(message))) handleError(); if(!EVP_DigestFinal_ex(mdctx, md_value, &md_len)) handleError(); if(!EVP_MD_CTX_destroy(mdctx)) handleError(); printf("Digest is: "); for(int i = 0; i < md_len; i++) printf("%02x", md_value[i]); printf("\n"); 

Now, and HMAC is slightly different than a Hash. The HMAC is a keyed hash, while the hash is not keyed. You can also use the EVP_* functions for HMAC'ing. Below is from the OpenSSL's wiki page EVP Signing and Verifying:

EVP_MD_CTX* mdctx = NULL; const EVP_MD* md = NULL; EVP_PKEY *pkey = NULL; unsigned char md_value[EVP_MAX_MD_SIZE]; int md_len = 0; char message[] = "Now is the time for all good men to " "come to the aide of their country\n"; OpenSSL_add_all_digests(); if(!(mdctx = EVP_MD_CTX_create())) handleError(); if(!(md = EVP_get_digestbyname("SHA1"))) handleError(); if(!(pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, "password", strlen("password")))) handleError(); if(1 != EVP_DigestSignInit(mdctx, NULL, md, NULL, pkey)) handleError(); /* Call update with the message */ if(1 != EVP_DigestSignUpdate(mdctx, message, strlen(message))) handleError(); if(1 != EVP_DigestSignFinal(mdctx, md_value, &md_len)) handleError(); printf("HMAC is: "); for(int i = 0; i < md_len; i++) printf("%02x", md_value[i]); printf("\n"); 

The low level interface would look similar to:

EVP_MD_CTX* mdctx = NULL; const EVP_MD* md = NULL; unsigned char md_value[EVP_MAX_MD_SIZE]; int md_len = 0; char message[] = "Now is the time for all good men to " "come to the aide of their country\n"; OpenSSL_add_all_digests(); md = EVP_get_digestbyname("SHA1"); mdctx = EVP_MD_CTX_create(); if(!HMAC_Init_ex(mdctx, key, sizeof(key), md, NULL)) handleError(); if(!HMAC_Update(mdctx, message, strlen(message))) handleError(); if(!HMAC_Final(mdctx, md_value, &md_len)) handleError(); if(!HMAC_CTX_cleanup(mdctx)) handleError(); printf("HMAC is: "); for(int i = 0; i < md_len; i++) printf("%02x", md_value[i]); printf("\n"); 
Sign up to request clarification or add additional context in comments.

2 Comments

There is a major problem with your code. key is not an unsigned char array it's an EVP_PKEY. Also, there are some typos.
I have dug out how to create the EVP_PKEY (more at wiki.openssl.org/index.php/EVP_Key_and_Parameter_Generation)
1

You need to use EVP_PKEY_new_mac_key function in order to obtain the right key structure for HMAC. And don't forget to free it with EVP_PKEY_free.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.