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