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 | |
20 | typedef 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 | |
28 | typedef 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 | |
96 | typedef 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. |
106 | struct ccchacha20poly1305_info { |
107 | |
108 | }; |
109 | |
110 | const 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 | */ |
126 | int 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 | */ |
137 | int 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 | */ |
153 | int ccchacha20poly1305_setnonce(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, const uint8_t *nonce); |
154 | int 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 | */ |
171 | int 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 | */ |
189 | int 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 | */ |
203 | int 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 | */ |
221 | int 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 | */ |
235 | int 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 | */ |
265 | int 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 | */ |
291 | int 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 | |