1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 
4 /* The implementation is based on:
5  * Public Domain poly1305 from Andrew Moon
6  * https://github.com/floodyberry/poly1305-donna
7  */
8 
9 #include "tomcrypt_private.h"
10 
11 #ifdef LTC_POLY1305
12 
13 /**
14   POLY1305 a file
15   @param fname    The name of the file you wish to POLY1305
16   @param key      The secret key
17   @param keylen   The length of the secret key
18   @param mac      [out] The POLY1305 authentication tag
19   @param maclen   [in/out]  The max size and resulting size of the authentication tag
20   @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled
21 */
poly1305_file(const char * fname,const unsigned char * key,unsigned long keylen,unsigned char * mac,unsigned long * maclen)22 int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen)
23 {
24 #ifdef LTC_NO_FILE
25    LTC_UNUSED_PARAM(fname);
26    LTC_UNUSED_PARAM(key);
27    LTC_UNUSED_PARAM(keylen);
28    LTC_UNUSED_PARAM(mac);
29    LTC_UNUSED_PARAM(maclen);
30    return CRYPT_NOP;
31 #else
32    poly1305_state st;
33    FILE *in;
34    unsigned char *buf;
35    size_t x;
36    int err;
37 
38    LTC_ARGCHK(fname  != NULL);
39    LTC_ARGCHK(key    != NULL);
40    LTC_ARGCHK(mac    != NULL);
41    LTC_ARGCHK(maclen != NULL);
42 
43    if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) {
44       return CRYPT_MEM;
45    }
46 
47    if ((err = poly1305_init(&st, key, keylen)) != CRYPT_OK) {
48       goto LBL_ERR;
49    }
50 
51    in = fopen(fname, "rb");
52    if (in == NULL) {
53       err = CRYPT_FILE_NOTFOUND;
54       goto LBL_ERR;
55    }
56 
57    do {
58       x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in);
59       if ((err = poly1305_process(&st, buf, (unsigned long)x)) != CRYPT_OK) {
60          fclose(in);
61          goto LBL_CLEANBUF;
62       }
63    } while (x == LTC_FILE_READ_BUFSIZE);
64 
65    if (fclose(in) != 0) {
66       err = CRYPT_ERROR;
67       goto LBL_CLEANBUF;
68    }
69 
70    err = poly1305_done(&st, mac, maclen);
71 
72 LBL_CLEANBUF:
73    zeromem(buf, LTC_FILE_READ_BUFSIZE);
74 LBL_ERR:
75 #ifdef LTC_CLEAN_STACK
76    zeromem(&st, sizeof(poly1305_state));
77 #endif
78    XFREE(buf);
79    return err;
80 #endif
81 }
82 
83 #endif
84