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 
11 /* The implementation is based on:
12  * Public Domain poly1305 from Andrew Moon
13  * https://github.com/floodyberry/poly1305-donna
14  */
15 
16 #include "tomcrypt_private.h"
17 
18 #ifdef LTC_POLY1305
19 
20 /**
21   POLY1305 a file
22   @param fname    The name of the file you wish to POLY1305
23   @param key      The secret key
24   @param keylen   The length of the secret key
25   @param mac      [out] The POLY1305 authentication tag
26   @param maclen   [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 */
poly1305_file(const char * fname,const unsigned char * key,unsigned long keylen,unsigned char * mac,unsigned long * maclen)29 int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen)
30 {
31 #ifdef LTC_NO_FILE
32    LTC_UNUSED_PARAM(fname);
33    LTC_UNUSED_PARAM(key);
34    LTC_UNUSED_PARAM(keylen);
35    LTC_UNUSED_PARAM(mac);
36    LTC_UNUSED_PARAM(maclen);
37    return CRYPT_NOP;
38 #else
39    poly1305_state st;
40    FILE *in;
41    unsigned char *buf;
42    size_t x;
43    int err;
44 
45    LTC_ARGCHK(fname  != NULL);
46    LTC_ARGCHK(key    != NULL);
47    LTC_ARGCHK(mac    != NULL);
48    LTC_ARGCHK(maclen != NULL);
49 
50    if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) {
51       return CRYPT_MEM;
52    }
53 
54    if ((err = poly1305_init(&st, key, keylen)) != CRYPT_OK) {
55       goto LBL_ERR;
56    }
57 
58    in = fopen(fname, "rb");
59    if (in == NULL) {
60       err = CRYPT_FILE_NOTFOUND;
61       goto LBL_ERR;
62    }
63 
64    do {
65       x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in);
66       if ((err = poly1305_process(&st, buf, (unsigned long)x)) != CRYPT_OK) {
67          fclose(in);
68          goto LBL_CLEANBUF;
69       }
70    } while (x == LTC_FILE_READ_BUFSIZE);
71 
72    if (fclose(in) != 0) {
73       err = CRYPT_ERROR;
74       goto LBL_CLEANBUF;
75    }
76 
77    err = poly1305_done(&st, mac, maclen);
78 
79 LBL_CLEANBUF:
80    zeromem(buf, LTC_FILE_READ_BUFSIZE);
81 LBL_ERR:
82 #ifdef LTC_CLEAN_STACK
83    zeromem(&st, sizeof(poly1305_state));
84 #endif
85    XFREE(buf);
86    return err;
87 #endif
88 }
89 
90 #endif
91 
92 /* ref:         $Format:%D$ */
93 /* git commit:  $Format:%H$ */
94 /* commit time: $Format:%ai$ */
95