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 
12 /**
13   @file xcbc_file.c
14   XCBC support, process a file, Tom St Denis
15 */
16 
17 #ifdef LTC_XCBC
18 
19 /**
20    XCBC a file
21    @param cipher   The index of the cipher desired
22    @param key      The secret key
23    @param keylen   The length of the secret key (octets)
24    @param filename The name of the file you wish to XCBC
25    @param out      [out] Where the authentication tag is to be stored
26    @param outlen   [in/out] The max size and resulting size of the authentication tag
27    @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled
28 */
xcbc_file(int cipher,const unsigned char * key,unsigned long keylen,const char * filename,unsigned char * out,unsigned long * outlen)29 int xcbc_file(int cipher,
30               const unsigned char *key, unsigned long keylen,
31               const char *filename,
32                     unsigned char *out, unsigned long *outlen)
33 {
34 #ifdef LTC_NO_FILE
35    LTC_UNUSED_PARAM(cipher);
36    LTC_UNUSED_PARAM(key);
37    LTC_UNUSED_PARAM(keylen);
38    LTC_UNUSED_PARAM(filename);
39    LTC_UNUSED_PARAM(out);
40    LTC_UNUSED_PARAM(outlen);
41    return CRYPT_NOP;
42 #else
43    size_t x;
44    int err;
45    xcbc_state xcbc;
46    FILE *in;
47    unsigned char *buf;
48 
49    LTC_ARGCHK(key      != NULL);
50    LTC_ARGCHK(filename != NULL);
51    LTC_ARGCHK(out      != NULL);
52    LTC_ARGCHK(outlen   != NULL);
53 
54    if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) {
55       return CRYPT_MEM;
56    }
57 
58    if ((err = xcbc_init(&xcbc, cipher, key, keylen)) != CRYPT_OK) {
59       goto LBL_ERR;
60    }
61 
62    in = fopen(filename, "rb");
63    if (in == NULL) {
64       err = CRYPT_FILE_NOTFOUND;
65       goto LBL_ERR;
66    }
67 
68    do {
69       x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in);
70       if ((err = xcbc_process(&xcbc, buf, (unsigned long)x)) != CRYPT_OK) {
71          fclose(in);
72          goto LBL_CLEANBUF;
73       }
74    } while (x == LTC_FILE_READ_BUFSIZE);
75 
76    if (fclose(in) != 0) {
77       err = CRYPT_ERROR;
78       goto LBL_CLEANBUF;
79    }
80 
81    err = xcbc_done(&xcbc, out, outlen);
82 
83 LBL_CLEANBUF:
84    zeromem(buf, LTC_FILE_READ_BUFSIZE);
85 LBL_ERR:
86 #ifdef LTC_CLEAN_STACK
87    zeromem(&xcbc, sizeof(xcbc_state));
88 #endif
89    XFREE(buf);
90    return err;
91 #endif
92 }
93 
94 #endif
95 
96 /* ref:         $Format:%D$ */
97 /* git commit:  $Format:%H$ */
98 /* commit time: $Format:%ai$ */
99