Reputation: 2682
I am trying to write a simple hashing program. This is the code:
#include <openssl/evp.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
unsigned char hash[EVP_MAX_MD_SIZE];
unsigned hash_size;
unsigned i;
char s[100];
EVP_MD_CTX *ctx = EVP_MD_CTX_create();
EVP_MD_CTX_init(ctx);
EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
while (fgets(s, sizeof(s), stdin))
{
EVP_DigestUpdate(ctx, s, strnlen(s, sizeof(s) - 1));
}
EVP_DigestFinal_ex(ctx, hash, &hash_size);
EVP_MD_CTX_destroy(ctx);
for (i = 0; i < hash_size; ++i)
{
printf("%02x", hash[i]);
}
printf("\n");
EVP_MD_CTX_cleanup(ctx);
return 0;
}
I am using the following 21-byte file as input:
$ xxd testfile
0000000: 8c18 8425 ea30 2236 d472 47a0 38b9 003e ...%.0"6.rG.8..>
0000010: 85ca 547e b1
Unfortunately, my generated SHA does not match what sha1sum
returns:
$ sha1sum testfile
05a5e29ba59164ceee6bffbaec283ae5a6ecd66f testfile
$ myhashprog < testfile
d8e5c7f4360beb2cabf7275d15293a711e5dfeb3
What am I doing wrong?
I notice that there is a 0x00
in the file which will look like a string terminator but I am not sure how to handle it. Maybe fgets()
isn't the proper function to read from the file in this case...
Upvotes: 1
Views: 48
Reputation: 2682
I resolved this by using read()
instead of fgets()
:
while ((bytes = read(STDIN_FILENO, s, sizeof(s))) > 0)
{
EVP_DigestUpdate(ctx, s, bytes);
}
The problem is that, although fgets()
will read all the bytes, it does not return the number of bytes read so you can not reliably determine how much of the buffer is relevant unless you know the size of the input in advance.
Upvotes: 3