1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4 #include <stdarg.h>
5 
6 /**
7   @file f9_memory_multi.c
8   f9 support, process multiple blocks of memory, Tom St Denis
9 */
10 
11 #ifdef LTC_F9_MODE
12 
13 /**
14    f9 multiple blocks of memory
15    @param cipher    The index of the desired cipher
16    @param key       The secret key
17    @param keylen    The length of the secret key (octets)
18    @param out       [out] The destination of the authentication tag
19    @param outlen    [in/out]  The max size and resulting size of the authentication tag (octets)
20    @param in        The data to send through f9
21    @param inlen     The length of the data to send through f9 (octets)
22    @param ...       tuples of (data,len) pairs to f9, terminated with a (NULL,x) (x=don't care)
23    @return CRYPT_OK if successful
24 */
f9_memory_multi(int cipher,const unsigned char * key,unsigned long keylen,unsigned char * out,unsigned long * outlen,const unsigned char * in,unsigned long inlen,...)25 int f9_memory_multi(int cipher,
26                 const unsigned char *key, unsigned long keylen,
27                       unsigned char *out, unsigned long *outlen,
28                 const unsigned char *in,  unsigned long inlen, ...)
29 {
30    int                  err;
31    f9_state          *f9;
32    va_list              args;
33    const unsigned char *curptr;
34    unsigned long        curlen;
35 
36    LTC_ARGCHK(key    != NULL);
37    LTC_ARGCHK(in     != NULL);
38    LTC_ARGCHK(out    != NULL);
39    LTC_ARGCHK(outlen != NULL);
40 
41    /* allocate ram for f9 state */
42    f9 = XMALLOC(sizeof(f9_state));
43    if (f9 == NULL) {
44       return CRYPT_MEM;
45    }
46 
47    /* f9 process the message */
48    if ((err = f9_init(f9, cipher, key, keylen)) != CRYPT_OK) {
49       goto LBL_ERR;
50    }
51    va_start(args, inlen);
52    curptr = in;
53    curlen = inlen;
54    for (;;) {
55       /* process buf */
56       if ((err = f9_process(f9, curptr, curlen)) != CRYPT_OK) {
57          goto LBL_ERR;
58       }
59       /* step to next */
60       curptr = va_arg(args, const unsigned char*);
61       if (curptr == NULL) {
62          break;
63       }
64       curlen = va_arg(args, unsigned long);
65    }
66    if ((err = f9_done(f9, out, outlen)) != CRYPT_OK) {
67       goto LBL_ERR;
68    }
69 LBL_ERR:
70 #ifdef LTC_CLEAN_STACK
71    zeromem(f9, sizeof(f9_state));
72 #endif
73    XFREE(f9);
74    va_end(args);
75    return err;
76 }
77 
78 #endif
79