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 #include "tomcrypt_private.h"
12
13 #ifdef LTC_CHACHA20POLY1305_MODE
14
15 /**
16 Process an entire GCM packet in one call.
17 @param key The secret key
18 @param keylen The length of the secret key
19 @param iv The initialization vector
20 @param ivlen The length of the initialization vector
21 @param aad The additional authentication data (header)
22 @param aadlen The length of the aad
23 @param in The plaintext
24 @param inlen The length of the plaintext (ciphertext length is the same)
25 @param out The ciphertext
26 @param tag [out] The MAC tag
27 @param taglen [in/out] The MAC tag length
28 @param direction Encrypt or Decrypt mode (CHACHA20POLY1305_ENCRYPT or CHACHA20POLY1305_DECRYPT)
29 @return CRYPT_OK on success
30 */
chacha20poly1305_memory(const unsigned char * key,unsigned long keylen,const unsigned char * iv,unsigned long ivlen,const unsigned char * aad,unsigned long aadlen,const unsigned char * in,unsigned long inlen,unsigned char * out,unsigned char * tag,unsigned long * taglen,int direction)31 int chacha20poly1305_memory(const unsigned char *key, unsigned long keylen,
32 const unsigned char *iv, unsigned long ivlen,
33 const unsigned char *aad, unsigned long aadlen,
34 const unsigned char *in, unsigned long inlen,
35 unsigned char *out,
36 unsigned char *tag, unsigned long *taglen,
37 int direction)
38 {
39 chacha20poly1305_state st;
40 int err;
41
42 LTC_ARGCHK(key != NULL);
43 LTC_ARGCHK(iv != NULL);
44 LTC_ARGCHK(in != NULL);
45 LTC_ARGCHK(out != NULL);
46 LTC_ARGCHK(tag != NULL);
47 LTC_ARGCHK(taglen != NULL);
48
49 if ((err = chacha20poly1305_init(&st, key, keylen)) != CRYPT_OK) { goto LBL_ERR; }
50 if ((err = chacha20poly1305_setiv(&st, iv, ivlen)) != CRYPT_OK) { goto LBL_ERR; }
51 if (aad && aadlen > 0) {
52 if ((err = chacha20poly1305_add_aad(&st, aad, aadlen)) != CRYPT_OK) { goto LBL_ERR; }
53 }
54 if (direction == CHACHA20POLY1305_ENCRYPT) {
55 if ((err = chacha20poly1305_encrypt(&st, in, inlen, out)) != CRYPT_OK) { goto LBL_ERR; }
56 if ((err = chacha20poly1305_done(&st, tag, taglen)) != CRYPT_OK) { goto LBL_ERR; }
57 }
58 else if (direction == CHACHA20POLY1305_DECRYPT) {
59 unsigned char buf[MAXBLOCKSIZE];
60 unsigned long buflen = sizeof(buf);
61 if ((err = chacha20poly1305_decrypt(&st, in, inlen, out)) != CRYPT_OK) { goto LBL_ERR; }
62 if ((err = chacha20poly1305_done(&st, buf, &buflen)) != CRYPT_OK) { goto LBL_ERR; }
63 if (buflen != *taglen || XMEM_NEQ(buf, tag, buflen) != 0) {
64 err = CRYPT_ERROR;
65 goto LBL_ERR;
66 }
67 }
68 else {
69 err = CRYPT_INVALID_ARG;
70 goto LBL_ERR;
71 }
72 LBL_ERR:
73 #ifdef LTC_CLEAN_STACK
74 zeromem(&st, sizeof(chacha20poly1305_state));
75 #endif
76 return err;
77 }
78
79 #endif
80
81 /* ref: $Format:%D$ */
82 /* git commit: $Format:%H$ */
83 /* commit time: $Format:%ai$ */
84