Hello,
I apologize if my last question was too involved to test easily.
I've attached a new version of the test code that is much more direct in its use of a message digest.
The program opens /dev/zero and reads four bytes, one byte at a time, and after each byte retrieves the digest using BIO_gets().
As you can see from the output, the first digest is not equal to the following three.
Why is this? Am I misusing the BIO_gets() api? Is there an initial value injected into the BIO stream for digests that must be cleared before a first call to BIO_gets can be made?
Any help you can provide would be appreciated.
Thank you, Stephen.
$ gcc -o s_bio s_bio.c ./local/lib/libcrypto.a
$ ./s_bio read 1 byte(s): 00 hash: 93b885adfe0da089cdf634904fd59f71 hash: b0e641c998cc3eae6fa2f8726d98cddd read 1 byte(s): 00 hash: 013b1a00c5739a37fa9a5a89337ec241 hash: b0e641c998cc3eae6fa2f8726d98cddd read 1 byte(s): 00 hash: 013b1a00c5739a37fa9a5a89337ec241 hash: b0e641c998cc3eae6fa2f8726d98cddd read 1 byte(s): 00 hash: 013b1a00c5739a37fa9a5a89337ec241 hash: b0e641c998cc3eae6fa2f8726d98cddd
#include <openssl/evp.h>
#include <stdio.h> int print_digest(BIO *b) { char digest[EVP_MAX_MD_SIZE]; int len; int i; memset(digest, 0, EVP_MAX_MD_SIZE); len = BIO_gets(b, digest, EVP_MAX_MD_SIZE); if ( len <= 0 ) { fprintf(stderr, "error getting hash.\n"); return -1; } else { fprintf(stderr, "hash: "); for (i=0; i < len; i++) { fprintf(stderr, "%02x", (unsigned char)digest[i]); } fprintf(stderr, "\n"); } return 0; } int filter(char *input_file, int blocksize, int length) { BIO *bi = NULL; BIO *digest=NULL; int ret; char *buf; int l_read = 0; int i; buf = (char *)malloc(blocksize); digest = BIO_new(BIO_f_md()); BIO_set_md(digest, EVP_md5()); /*BIO_set_md(digest, EVP_sha1());*/ /* INPUT */ bi = BIO_new_file(input_file, "r"); if ( bi == NULL) { fprintf(stderr, "bio new error\n"); return -1; } BIO_push(digest, bi); bi = digest; BIO_reset(digest); while ( l_read < length ) { ret = BIO_read(bi, buf, blocksize); if ( ret > 0 ) { fprintf(stderr, "read %d byte(s): ", ret); for (i=0; i < ret; i++) { fprintf(stderr, "%02X", buf[i]); } fprintf(stderr, "\n"); /* Do stuff with input */ print_digest(digest); print_digest(digest); l_read += ret; } else { fprintf(stderr, "done reading: %d\n", ret); break; } } BIO_free_all(bi); return 0; } int main(int argc, char **argv) { OpenSSL_add_all_algorithms(); if ( filter("/dev/zero", 1, 4) != 0 ) { fprintf(stderr, "error:\n"); exit(1); } return 0; }