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