0

I have the below code to generate a SHA256 HMAC hash:

HMAC(EVP_sha256(), key, key_len, (const unsigned char *)data, strlen(data), digest, &digest_len);

I would however like to generate HMAC SHA256 hash of a file. Please note the file is a big file (~80 MB) I will need to do this using system calls rather than directly using a shell command.

Regards

  • Simple read the specific file with `fread()`? What do you exactly mean with system calls? –  May 15 '20 at 10:37
  • I don't want to use a shell command I meant. – Embedded Enthusiast May 15 '20 at 10:44
  • Does this answer your question? [How to read the content of a file to a string in C?](https://stackoverflow.com/questions/174531/how-to-read-the-content-of-a-file-to-a-string-in-c) – Déjà vu May 15 '20 at 10:48
  • What exactly is the question? Dont't you know how to read the file? Is your available memory limited in a way that you must split into chunks? – Gerhardh May 15 '20 at 11:54
  • The file is ~70MB file so how do I provide the data to be hashed in one-go? Should I read the file in iteration and call HMAC( ) in a loop? I am not sure. Hence the question – Embedded Enthusiast May 15 '20 at 12:03
  • If you have concerns about your memory size, loading in chunks would be the way to go. If you have a normal modern PC, you could simply load it all at once as 100MB aren't a problem unless you load docens of them. – Gerhardh May 15 '20 at 14:11

1 Answers1

2

If you have a large file then you can use HMAC_Update() and HMAC_Final(). Here is a quick and dirty example:

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <ssl/hmac.h>


int main(int argc, char *argv[])
{
    FILE *f;
    uint8_t buf[1024];
    HMAC_CTX *ctx;
    size_t ret;
    uint8_t key[8] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
    uint8_t *md;
    int md_len;
    int i;

    if (argc < 2) {
        printf("Usage: %s [FILE]\n", argv[0]);
        return 1;
    }

    f = fopen(argv[1], "r");

    if (!f) {
        printf("Could not open file\n");
        return 1;
    }

    ctx = HMAC_CTX_new();
    HMAC_Init_ex(ctx, key, 8, EVP_sha256(), NULL);

    md = (uint8_t *) malloc(HMAC_size(ctx));

    while (!feof(f)) {
        ret = fread(buf, 1, sizeof(buf), f);
        HMAC_Update(ctx, &buf[0], ret);
    }

    HMAC_Final(ctx, md, &md_len);

    for (i = 0; i < md_len; i ++)
        printf("%02X", md[i]);

    printf("\n");
    HMAC_CTX_free(ctx);
    fclose(f);
    return 0;
}

The output:

$ ./hmac hmac
C477E7AA9EC9F0DD8C98F85B94A18BC954E0648BB0C7D302F5EDE3679A93A6E8
$
  • For somereason, the hash calculated using this program vs hmac256 application available on Ubuntu doesn't match at times. How do I go about debugging this? – Embedded Enthusiast May 21 '20 at 05:40