xref: /xnu-8796.121.2/EXTERNAL_HEADERS/corecrypto/ccchacha20poly1305.h (revision c54f35ca767986246321eb901baf8f5ff7923f6a)
1 /* Copyright (c) (2016-2019,2021) Apple Inc. All rights reserved.
2  *
3  * corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which
4  * is contained in the License.txt file distributed with corecrypto) and only to
5  * people who accept that license. IMPORTANT:  Any license rights granted to you by
6  * Apple Inc. (if any) are limited to internal use within your organization only on
7  * devices and computers you own or control, for the sole purpose of verifying the
8  * security characteristics and correct functioning of the Apple Software.  You may
9  * not, directly or indirectly, redistribute the Apple Software or any portions thereof.
10  */
11 
12 #ifndef _CORECRYPTO_CCCHACHA20POLY1305_H_
13 #define _CORECRYPTO_CCCHACHA20POLY1305_H_
14 
15 #include <corecrypto/cc_config.h>
16 #include <stdbool.h>
17 #include <stddef.h>
18 #include <stdint.h>
19 
20 CC_PTRCHECK_CAPABLE_HEADER()
21 
22 #define CCCHACHA20_KEY_NBYTES 32
23 #define CCCHACHA20_BLOCK_NBYTES 64
24 #define CCCHACHA20_BLOCK_NBITS (CCCHACHA20_BLOCK_NBYTES * 8)
25 #define CCCHACHA20_NONCE_NBYTES 12
26 
27 typedef struct {
28 	uint32_t state[16];
29 	uint8_t	buffer[CCCHACHA20_BLOCK_NBYTES];
30 	size_t leftover;
31 } ccchacha20_ctx;
32 
33 #define CCPOLY1305_TAG_NBYTES 16
34 #define CCPOLY1305_KEY_NBYTES 32
35 
36 typedef struct {
37 	uint32_t r0, r1, r2, r3, r4;
38 	uint32_t s1, s2, s3, s4;
39 	uint32_t h0, h1, h2, h3, h4;
40 	uint8_t	buf[16];
41 	size_t buf_used;
42 	uint8_t	key[16];
43 } ccpoly1305_ctx;
44 
45 
46 /*!
47  @group		ccchacha20poly1305
48  @abstract	Encrypts and authenticates or decrypts and verifies data.
49  @discussion	See RFC 7539 for details.
50 
51  @warning The key-nonce pair must be unique per encryption.
52 
53  @warning A single message can be at most (2^38 - 64) bytes in length.
54 
55  The correct sequence of calls to encrypt is:
56 
57  @code ccchacha20poly1305_init(...)
58  ccchacha20poly1305_setnonce(...)
59  ccchacha20poly1305_aad(...)       (may be called zero or more times)
60  ccchacha20poly1305_encrypt(...)   (may be called zero or more times)
61  ccchacha20poly1305_finalize(...)
62 
63  To reuse the context for additional encryptions, follow this sequence:
64 
65  @code ccchacha20poly1305_reset(...)
66  ccchacha20poly1305_setnonce(...)
67  ccchacha20poly1305_aad(...)       (may be called zero or more times)
68  ccchacha20poly1305_encrypt(...)   (may be called zero or more times)
69  ccchacha20poly1305_finalize(...)
70 
71  To decrypt, follow this call sequence:
72 
73  @code ccchacha20poly1305_init(...)
74  ccchacha20poly1305_setnonce(...)
75  ccchacha20poly1305_aad(...)       (may be called zero or more times)
76  ccchacha20poly1305_decrypt(...)   (may be called zero or more times)
77  ccchacha20poly1305_verify(...)    (returns zero on successful decryption)
78 
79  To reuse the context for additional encryptions, follow this sequence:
80 
81  @code ccchacha20poly1305_reset(...)
82  ccchacha20poly1305_setnonce(...)
83  ccchacha20poly1305_aad(...)       (may be called zero or more times)
84  ccchacha20poly1305_decrypt(...)   (may be called zero or more times)
85  ccchacha20poly1305_verify(...)    (returns zero on successful decryption)
86 */
87 
88 #define CCCHACHA20POLY1305_KEY_NBYTES (CCCHACHA20_KEY_NBYTES)
89 #define CCCHACHA20POLY1305_NONCE_NBYTES (CCCHACHA20_NONCE_NBYTES)
90 #define CCCHACHA20POLY1305_TAG_NBYTES (CCPOLY1305_TAG_NBYTES)
91 
92 /* (2^32 - 1) blocks */
93 /* (2^38 - 64) bytes */
94 /* (2^41 - 512) bits */
95 /* Exceeding this figure breaks confidentiality and authenticity. */
96 #define CCCHACHA20POLY1305_TEXT_MAX_NBYTES ((1ULL << 38) - 64ULL)
97 
98 #define CCCHACHA20POLY1305_STATE_SETNONCE 1
99 #define CCCHACHA20POLY1305_STATE_AAD 2
100 #define CCCHACHA20POLY1305_STATE_ENCRYPT 3
101 #define CCCHACHA20POLY1305_STATE_DECRYPT 4
102 #define CCCHACHA20POLY1305_STATE_FINAL 5
103 
104 typedef struct {
105 	ccchacha20_ctx chacha20_ctx;
106 	ccpoly1305_ctx poly1305_ctx;
107 	uint64_t aad_nbytes;
108 	uint64_t text_nbytes;
109     uint8_t state;
110 } ccchacha20poly1305_ctx;
111 
112 // This is just a stub right now.
113 // Eventually we will optimize by platform.
114 struct ccchacha20poly1305_info {
115 
116 };
117 
118 const struct ccchacha20poly1305_info *ccchacha20poly1305_info(void);
119 
120 /*!
121  @function   ccchacha20poly1305_init
122  @abstract   Initialize a chacha20poly1305 context.
123 
124  @param      info       Implementation descriptor
125  @param      ctx        Context for this instance
126  @param      key        Secret chacha20 key
127 
128  @result     0 iff successful.
129 
130  @discussion The key is 32 bytes in length.
131 
132  @warning The key-nonce pair must be unique per encryption.
133  */
134 int	ccchacha20poly1305_init(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, const uint8_t *cc_counted_by(CCCHACHA20POLY1305_KEY_NBYTES) key);
135 
136 /*!
137  @function   ccchacha20poly1305_reset
138  @abstract   Reset a chacha20poly1305 context for reuse.
139 
140  @param      info       Implementation descriptor
141  @param      ctx        Context for this instance
142 
143  @result     0 iff successful.
144  */
145 int ccchacha20poly1305_reset(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx);
146 
147 /*!
148  @function   ccchacha20poly1305_setnonce
149  @abstract   Set the nonce for encryption or decryption.
150 
151  @param      info       Implementation descriptor
152  @param      ctx        Context for this instance
153  @param      nonce      Unique nonce per encryption
154 
155  @result     0 iff successful.
156 
157  @discussion The nonce is 12 bytes in length.
158 
159  @warning The key-nonce pair must be unique per encryption.
160  */
161 int ccchacha20poly1305_setnonce(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, const uint8_t *cc_counted_by(CCCHACHA20POLY1305_NONCE_NBYTES) nonce);
162 int ccchacha20poly1305_incnonce(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, uint8_t *cc_counted_by(CCCHACHA20POLY1305_NONCE_NBYTES) nonce);
163 
164 /*!
165  @function   ccchacha20poly1305_aad
166  @abstract   Authenticate additional data.
167 
168  @param      info       Descriptor for the mode
169  @param      ctx        Context for this instance
170  @param      nbytes     Length of the additional data in bytes
171  @param      aad        Additional data to authenticate
172 
173  @result     0 iff successful.
174 
175  @discussion This is typically used to authenticate data that cannot be encrypted (e.g. packet headers).
176 
177  This function may be called zero or more times.
178  */
179 int	ccchacha20poly1305_aad(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, size_t nbytes, const void *cc_sized_by(nbytes) aad);
180 
181 /*!
182  @function   ccchacha20poly1305_encrypt
183  @abstract   Encrypt data.
184 
185  @param      info       Descriptor for the mode
186  @param      ctx        Context for this instance
187  @param      nbytes     Length of the plaintext in bytes
188  @param      ptext      Input plaintext
189  @param      ctext      Output ciphertext
190 
191  @result     0 iff successful.
192 
193  @discussion In-place processing is supported.
194 
195  This function may be called zero or more times.
196  */
197 int	ccchacha20poly1305_encrypt(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, size_t nbytes, const void *cc_sized_by(nbytes) ptext, void *cc_sized_by(nbytes) ctext);
198 
199 /*!
200  @function   ccchacha20poly1305_finalize
201  @abstract   Finalize encryption.
202 
203  @param      info       Descriptor for the mode
204  @param      ctx        Context for this instance
205  @param      tag        Generated authentication tag
206 
207  @result     0 iff successful.
208 
209  @discussion The generated tag is 16 bytes in length.
210  */
211 int	ccchacha20poly1305_finalize(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, uint8_t *cc_counted_by(CCCHACHA20POLY1305_TAG_NBYTES) tag);
212 
213 /*!
214  @function   ccchacha20poly1305_decrypt
215  @abstract   Decrypt data.
216 
217  @param      info       Descriptor for the mode
218  @param      ctx        Context for this instance
219  @param      nbytes     Length of the ciphertext in bytes
220  @param      ctext      Input ciphertext
221  @param      ptext      Output plaintext
222 
223  @result     0 iff successful.
224 
225  @discussion In-place processing is supported.
226 
227  This function may be called zero or more times.
228  */
229 int	ccchacha20poly1305_decrypt(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, size_t nbytes, const void *cc_sized_by(nbytes) ctext, void *cc_sized_by(nbytes) ptext);
230 
231 /*!
232  @function   ccchacha20poly1305_verify
233  @abstract   Verify authenticity.
234 
235  @param      info       Descriptor for the mode
236  @param      ctx        Context for this instance
237  @param      tag        Expected authentication tag
238 
239  @result     0 iff authentic and otherwise successful.
240 
241  @discussion The expected tag is 16 bytes in length.
242  */
243 int	ccchacha20poly1305_verify(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, const uint8_t *cc_counted_by(CCCHACHA20POLY1305_TAG_NBYTES) tag);
244 
245 /*!
246  @function      ccchacha20poly1305_encrypt_oneshot
247  @abstract      Encrypt with chacha20poly1305.
248 
249  @param      info           Descriptor for the mode
250  @param      key            Secret chacha20 key
251  @param      nonce          Unique nonce per encryption
252  @param      aad_nbytes     Length of the additional data in bytes
253  @param      aad            Additional data to authenticate
254  @param      ptext_nbytes   Length of the plaintext in bytes
255  @param      ptext          Input plaintext
256  @param      ctext          Output ciphertext
257  @param      tag            Generated authentication tag
258 
259  @discussion See RFC 7539 for details.
260 
261  The key is 32 bytes in length.
262 
263  The nonce is 12 bytes in length.
264 
265  The generated tag is 16 bytes in length.
266 
267  In-place processing is supported.
268 
269  @warning The key-nonce pair must be unique per encryption.
270 
271  @warning A single message can be at most (2^38 - 64) bytes in length.
272  */
273 int ccchacha20poly1305_encrypt_oneshot(const struct ccchacha20poly1305_info *info, const uint8_t *cc_counted_by(CCCHACHA20POLY1305_KEY_NBYTES) key, const uint8_t *cc_counted_by(CCCHACHA20POLY1305_NONCE_NBYTES) nonce, size_t aad_nbytes, const void *cc_sized_by(aad_nbytes) aad, size_t ptext_nbytes, const void *cc_sized_by(ptext_nbytes) ptext, void *cc_sized_by(ptext_nbytes) ctext, uint8_t *cc_counted_by(CCCHACHA20POLY1305_TAG_NBYTES) tag);
274 
275 /*!
276  @function      ccchacha20poly1305_decrypt_oneshot
277  @abstract      Decrypt with chacha20poly1305.
278 
279  @param      info           Descriptor for the mode
280  @param      key            Secret chacha20 key
281  @param      nonce          Unique nonce per encryption
282  @param      aad_nbytes     Length of the additional data in bytes
283  @param      aad            Additional data to authenticate
284  @param      ctext_nbytes   Length of the ciphertext in bytes
285  @param      ctext          Input ciphertext
286  @param      ptext          Output plaintext
287  @param      tag            Expected authentication tag
288 
289  @discussion See RFC 7539 for details.
290 
291  The key is 32 bytes in length.
292 
293  The nonce is 12 bytes in length.
294 
295  The generated tag is 16 bytes in length.
296 
297  In-place processing is supported.
298  */
299 int ccchacha20poly1305_decrypt_oneshot(const struct ccchacha20poly1305_info *info, const uint8_t *cc_counted_by(CCCHACHA20POLY1305_KEY_NBYTES) key, const uint8_t *cc_counted_by(CCCHACHA20POLY1305_NONCE_NBYTES) nonce, size_t aad_nbytes, const void *cc_sized_by(aad_nbytes) aad, size_t ctext_nbytes, const void *cc_sized_by(ctext_nbytes) ctext, void *cc_sized_by(ctext_nbytes) ptext, const uint8_t *cc_counted_by(CCCHACHA20POLY1305_TAG_NBYTES) tag);
300 
301 #endif
302