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
17CC_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
24typedef 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
33typedef 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
101typedef 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.
111struct ccchacha20poly1305_info {
112
113};
114
115const 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 */
131int 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 */
142int 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 */
158int ccchacha20poly1305_setnonce(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, const uint8_t *cc_counted_by(CCCHACHA20POLY1305_NONCE_NBYTES) nonce);
159int 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 */
176int 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 */
194int 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 */
208int 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 */
226int 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 */
240int 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 */
270int 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 */
296int 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