1 /* chacha20_poly1305.h
2  *
3  * Copyright (C) 2006-2021 wolfSSL Inc.
4  *
5  * This file is part of wolfSSL.
6  *
7  * wolfSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * wolfSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20  */
21 /*
22 
23 DESCRIPTION
24 This library contains implementation for the ChaCha20 stream cipher and
25 the Poly1305 authenticator, both as as combined-mode,
26 or Authenticated Encryption with Additional Data (AEAD) algorithm.
27 
28 */
29 
30 /*!
31     \file wolfssl/wolfcrypt/chacha20_poly1305.h
32 */
33 
34 #ifndef WOLF_CRYPT_CHACHA20_POLY1305_H
35 #define WOLF_CRYPT_CHACHA20_POLY1305_H
36 
37 #include <wolfssl/wolfcrypt/types.h>
38 #include <wolfssl/wolfcrypt/chacha.h>
39 #include <wolfssl/wolfcrypt/poly1305.h>
40 
41 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
42 
43 #ifdef __cplusplus
44     extern "C" {
45 #endif
46 
47 #define CHACHA20_POLY1305_AEAD_KEYSIZE      32
48 #define CHACHA20_POLY1305_AEAD_IV_SIZE      12
49 #define CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE 16
50 #define CHACHA20_POLY1305_MAX               4294967295U
51 #define XCHACHA20_POLY1305_AEAD_NONCE_SIZE  24
52 
53 enum {
54     CHACHA20_POLY_1305_ENC_TYPE = 8,    /* cipher unique type */
55 
56     /* AEAD Cipher Direction */
57     CHACHA20_POLY1305_AEAD_DECRYPT = 0,
58     CHACHA20_POLY1305_AEAD_ENCRYPT = 1,
59 
60     /* AEAD State */
61     CHACHA20_POLY1305_STATE_INIT = 0,
62     CHACHA20_POLY1305_STATE_READY = 1,
63     CHACHA20_POLY1305_STATE_AAD = 2,
64     CHACHA20_POLY1305_STATE_DATA = 3,
65 };
66 
67 typedef struct ChaChaPoly_Aead {
68     ChaCha   chacha;
69     Poly1305 poly;
70 
71     word32   aadLen;
72     word32   dataLen;
73 
74     byte     state;
75     byte     isEncrypt:1;
76 } ChaChaPoly_Aead;
77 
78 
79 /*
80  * The IV for this implementation is 96 bits to give the most flexibility.
81  *
82  * Some protocols may have unique per-invocation inputs that are not
83  * 96-bit in length. For example, IPsec may specify a 64-bit nonce. In
84  * such a case, it is up to the protocol document to define how to
85  * transform the protocol nonce into a 96-bit nonce, for example by
86  * concatenating a constant value.
87  */
88 
89 WOLFSSL_API
90 int wc_ChaCha20Poly1305_Encrypt(
91                 const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE],
92                 const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE],
93                 const byte* inAAD, const word32 inAADLen,
94                 const byte* inPlaintext, const word32 inPlaintextLen,
95                 byte* outCiphertext,
96                 byte outAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]);
97 
98 WOLFSSL_API
99 int wc_ChaCha20Poly1305_Decrypt(
100                 const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE],
101                 const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE],
102                 const byte* inAAD, const word32 inAADLen,
103                 const byte* inCiphertext, const word32 inCiphertextLen,
104                 const byte inAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE],
105                 byte* outPlaintext);
106 
107 WOLFSSL_API
108 int wc_ChaCha20Poly1305_CheckTag(
109     const byte authTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE],
110     const byte authTagChk[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]);
111 
112 
113 
114 /* Implementation of AEAD, which includes support for adding
115     data, then final calculation of authentication tag */
116 WOLFSSL_API int wc_ChaCha20Poly1305_Init(ChaChaPoly_Aead* aead,
117     const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE],
118     const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE],
119     int isEncrypt);
120 WOLFSSL_API int wc_ChaCha20Poly1305_UpdateAad(ChaChaPoly_Aead* aead,
121     const byte* inAAD, word32 inAADLen);
122 WOLFSSL_API int wc_ChaCha20Poly1305_UpdateData(ChaChaPoly_Aead* aead,
123     const byte* inData, byte* outData, word32 dataLen);
124 WOLFSSL_API int wc_ChaCha20Poly1305_Final(ChaChaPoly_Aead* aead,
125     byte outAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]);
126 
127 #ifdef HAVE_XCHACHA
128 
129 WOLFSSL_API int wc_XChaCha20Poly1305_Init(
130     ChaChaPoly_Aead* aead,
131     const byte *ad, word32 ad_len,
132     const byte *inKey, word32 inKeySz,
133     const byte *inIV, word32 inIVSz,
134     int isEncrypt);
135 
136 WOLFSSL_API int wc_XChaCha20Poly1305_Encrypt(
137     byte *dst, const size_t dst_space,
138     const byte *src, const size_t src_len,
139     const byte *ad, const size_t ad_len,
140     const byte *nonce, const size_t nonce_len,
141     const byte *key, const size_t key_len);
142 
143 WOLFSSL_API int wc_XChaCha20Poly1305_Decrypt(
144     byte *dst, const size_t dst_space,
145     const byte *src, const size_t src_len,
146     const byte *ad, const size_t ad_len,
147     const byte *nonce, const size_t nonce_len,
148     const byte *key, const size_t key_len);
149 
150 #endif /* HAVE_XCHACHA */
151 
152 #ifdef __cplusplus
153     } /* extern "C" */
154 #endif
155 
156 #endif /* HAVE_CHACHA && HAVE_POLY1305 */
157 #endif /* WOLF_CRYPT_CHACHA20_POLY1305_H */
158