1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4 
5 #ifndef LTC_NO_FILE
6 /**
7    @file hash_filehandle.c
8    Hash open files, Tom St Denis
9 */
10 
11 /**
12   Hash data from an open file handle.
13   @param hash   The index of the hash you want to use
14   @param in     The FILE* handle of the file you want to hash
15   @param out    [out] The destination of the digest
16   @param outlen [in/out] The max size and resulting size of the digest
17   @result CRYPT_OK if successful
18 */
hash_filehandle(int hash,FILE * in,unsigned char * out,unsigned long * outlen)19 int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen)
20 {
21     hash_state md;
22     unsigned char *buf;
23     size_t x;
24     int err;
25 
26     LTC_ARGCHK(out    != NULL);
27     LTC_ARGCHK(outlen != NULL);
28     LTC_ARGCHK(in     != NULL);
29 
30     if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) {
31         return CRYPT_MEM;
32     }
33 
34     if ((err = hash_is_valid(hash)) != CRYPT_OK) {
35         goto LBL_ERR;
36     }
37 
38     if (*outlen < hash_descriptor[hash]->hashsize) {
39        *outlen = hash_descriptor[hash]->hashsize;
40        err = CRYPT_BUFFER_OVERFLOW;
41        goto LBL_ERR;
42     }
43     if ((err = hash_descriptor[hash]->init(&md)) != CRYPT_OK) {
44        goto LBL_ERR;
45     }
46 
47     do {
48         x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in);
49         if ((err = hash_descriptor[hash]->process(&md, buf, (unsigned long)x)) != CRYPT_OK) {
50            goto LBL_CLEANBUF;
51         }
52     } while (x == LTC_FILE_READ_BUFSIZE);
53     if ((err = hash_descriptor[hash]->done(&md, out)) == CRYPT_OK) {
54        *outlen = hash_descriptor[hash]->hashsize;
55     }
56 
57 LBL_CLEANBUF:
58     zeromem(buf, LTC_FILE_READ_BUFSIZE);
59 LBL_ERR:
60     XFREE(buf);
61     return err;
62 }
63 #endif /* #ifndef LTC_NO_FILE */
64 
65