1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4 #include <stdarg.h>
5 
6 #ifdef LTC_HASH_HELPERS
7 /**
8   @file hash_memory_multi.c
9   Hash (multiple buffers) memory helper, Tom St Denis
10 */
11 
12 /**
13   Hash multiple (non-adjacent) blocks of memory at once.
14   @param hash   The index of the hash you wish to use
15   @param out    [out] Where to store the digest
16   @param outlen [in/out] Max size and resulting size of the digest
17   @param in     The data you wish to hash
18   @param inlen  The length of the data to hash (octets)
19   @param ...    tuples of (data,len) pairs to hash, terminated with a (NULL,x) (x=don't care)
20   @return CRYPT_OK if successful
21 */
hash_memory_multi(int hash,unsigned char * out,unsigned long * outlen,const unsigned char * in,unsigned long inlen,...)22 int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen,
23                       const unsigned char *in, unsigned long inlen, ...)
24 {
25     hash_state          *md;
26     int                  err;
27     va_list              args;
28     const unsigned char *curptr;
29     unsigned long        curlen;
30 
31     LTC_ARGCHK(in     != NULL);
32     LTC_ARGCHK(out    != NULL);
33     LTC_ARGCHK(outlen != NULL);
34 
35     if ((err = hash_is_valid(hash)) != CRYPT_OK) {
36         return err;
37     }
38 
39     if (*outlen < hash_descriptor[hash]->hashsize) {
40        *outlen = hash_descriptor[hash]->hashsize;
41        return CRYPT_BUFFER_OVERFLOW;
42     }
43 
44     md = XMALLOC(sizeof(hash_state));
45     if (md == NULL) {
46        return CRYPT_MEM;
47     }
48 
49     if ((err = hash_descriptor[hash]->init(md)) != CRYPT_OK) {
50        goto LBL_ERR;
51     }
52 
53     va_start(args, inlen);
54     curptr = in;
55     curlen = inlen;
56     for (;;) {
57        /* process buf */
58        if ((err = hash_descriptor[hash]->process(md, curptr, curlen)) != CRYPT_OK) {
59           goto LBL_ERR;
60        }
61        /* step to next */
62        curptr = va_arg(args, const unsigned char*);
63        if (curptr == NULL) {
64           break;
65        }
66        curlen = va_arg(args, unsigned long);
67     }
68     err = hash_descriptor[hash]->done(md, out);
69     *outlen = hash_descriptor[hash]->hashsize;
70 LBL_ERR:
71 #ifdef LTC_CLEAN_STACK
72     zeromem(md, sizeof(hash_state));
73 #endif
74     XFREE(md);
75     va_end(args);
76     return err;
77 }
78 #endif /* #ifdef LTC_HASH_HELPERS */
79