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