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