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