progs/perftest.c: Use from Glibc syscall numbers.
[catacomb] / symm / chacha.h
CommitLineData
55d81656
MW
1/* -*-c-*-
2 *
3 * ChaCha stream cipher
4 *
5 * (c) 2015 Straylight/Edgeware
6 */
7
8/*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of Catacomb.
11 *
12 * Catacomb is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Library General Public License as
14 * published by the Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version.
16 *
17 * Catacomb is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with Catacomb; if not, write to the Free
24 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 * MA 02111-1307, USA.
26 */
27
28#ifndef CATACOMB_CHACHA_H
29#define CATACOMB_CHACHA_H
30
31#ifdef __cplusplus
32 extern "C" {
33#endif
34
35/*----- Header files ------------------------------------------------------*/
36
37#include <mLib/bits.h>
38
39#ifndef CATACOMB_GCIPHER_H
40# include "gcipher.h"
41#endif
42
43#ifndef CATACOMB_GRAND_H
44# include "grand.h"
45#endif
46
47/*----- Constants ---------------------------------------------------------*/
48
49#define CHACHA_NONCESZ 8u
1778ca95 50#define CHACHA_IETF_NONCESZ 12u
55d81656
MW
51#define CHACHA_KEYSZ 32u
52#define CHACHA_OUTSZ 64u
53
54#define HCHACHA_INSZ 16u
55#define HCHACHA_OUTSZ 32u
56
57#define XCHACHA_NONCESZ 24u
58#define XCHACHA_KEYSZ CHACHA_KEYSZ
59#define XCHACHA_OUTSZ CHACHA_OUTSZ
60
61/*----- Data structures ---------------------------------------------------*/
62
63typedef uint32 chacha_matrix[16];
64
65typedef struct chacha_ctx {
66 chacha_matrix a;
0fee61eb
MW
67 octet b[CHACHA_OUTSZ];
68 unsigned off;
55d81656
MW
69} chacha_ctx;
70
71#define XCHACHA_DEFCTX(name) \
72 typedef struct name { chacha_ctx s; chacha_matrix k; } name
73XCHACHA_DEFCTX(xchacha20_ctx);
74XCHACHA_DEFCTX(xchacha12_ctx);
75XCHACHA_DEFCTX(xchacha8_ctx);
76
77/*----- The ChaCha stream cipher ------------------------------------------*/
78
79/* --- @chacha_init@ --- *
80 *
81 * Arguments: @chacha_ctx *ctx@ = context to fill in
82 * @const void *key@ = pointer to key material
83 * @size_t ksz@ = size of key (either 32 or 16)
84 * @const void *nonce@ = initial nonce, or null
85 *
86 * Returns: ---
87 *
88 * Use: Initializes a ChaCha context ready for use.
89 */
90
91extern void chacha_init(chacha_ctx */*ctx*/,
de7f54d2
MW
92 const void */*key*/, size_t /*ksz*/,
93 const void */*nonce*/);
55d81656 94
1778ca95 95/* --- @chacha_setnonce{,_ietf}@ --- *
55d81656
MW
96 *
97 * Arguments: @chacha_ctx *ctx@ = pointer to context
1778ca95
MW
98 * @const void *nonce@ = the nonce (@CHACHA_NONCESZ@ or
99 * @CHACHA_IETF_NONCESZ@ bytes)
55d81656
MW
100 *
101 * Returns: ---
102 *
103 * Use: Set a new nonce in the context @ctx@, e.g., for processing a
104 * different message. The stream position is reset to zero (see
105 * @chacha_seek@ etc.).
106 */
107
108extern void chacha_setnonce(chacha_ctx */*ctx*/, const void */*nonce*/);
1778ca95 109extern void chacha_setnonce_ietf(chacha_ctx */*ctx*/, const void */*nonce*/);
55d81656 110
1778ca95 111/* --- @chacha_seek{,u64,_ietf}@ --- *
55d81656
MW
112 *
113 * Arguments: @chacha_ctx *ctx@ = pointer to context
1778ca95 114 * @unsigned long i@, @kludge64 i@, @uint32 i@ = new position
55d81656
MW
115 *
116 * Returns: ---
117 *
1778ca95 118 * Use: Sets a new stream position, in units of Chacha output
55d81656 119 * blocks, which are @CHACHA_OUTSZ@ bytes each. Byte
1778ca95 120 * granularity can be achieved by calling @chachaR_encrypt@
55d81656
MW
121 * appropriately.
122 */
123
124extern void chacha_seek(chacha_ctx */*ctx*/, unsigned long /*i*/);
125extern void chacha_seeku64(chacha_ctx */*ctx*/, kludge64 /*i*/);
1778ca95 126extern void chacha_seek_ietf(chacha_ctx */*ctx*/, uint32 /*i*/);
55d81656 127
1778ca95 128/* --- @chacha_tell{,u64,_ietf}@ --- *
55d81656
MW
129 *
130 * Arguments: @chacha_ctx *ctx@ = pointer to context
131 *
132 * Returns: The current position in the output stream, in blocks,
133 * rounding upwards.
134 */
135
136extern unsigned long chacha_tell(chacha_ctx */*ctx*/);
137extern kludge64 chacha_tellu64(chacha_ctx */*ctx*/);
1778ca95 138extern uint32 chacha_tell_ietf(chacha_ctx */*ctx*/);
55d81656
MW
139
140/* --- @chacha{20,12,8}_encrypt@ --- *
141 *
142 * Arguments: @chacha_ctx *ctx@ = pointer to context
143 * @const void *src@ = source buffer (or null)
144 * @void *dest@ = destination buffer (or null)
145 * @size_t sz@ = size of the buffers
146 *
147 * Returns: ---
148 *
149 * Use: Encrypts or decrypts @sz@ bytes of data from @src@ to @dest@.
150 * ChaCha works by XORing plaintext with a keystream, so
151 * encryption and decryption are the same operation. If @dest@
152 * is null then ignore @src@ and skip @sz@ bytes of the
153 * keystream. If @src@ is null, then just write the keystream
154 * to @dest@.
155 */
156
157extern void chacha20_encrypt(chacha_ctx */*ctx*/,
158 const void */*src*/, void */*dest*/,
159 size_t /*sz*/);
160extern void chacha12_encrypt(chacha_ctx */*ctx*/,
161 const void */*src*/, void */*dest*/,
162 size_t /*sz*/);
163extern void chacha8_encrypt(chacha_ctx */*ctx*/,
164 const void */*src*/, void */*dest*/,
165 size_t /*sz*/);
166
167/*----- The HChaCha pseudorandom function ---------------------------------*/
168
169/* --- @hchacha{20,12,8}_prf@ --- *
170 *
171 * Arguments: @chacha_ctx *ctx@ = pointer to context
172 * @const void *src@ = the input (@HCHACHA_INSZ@ bytes)
173 * @void *dest@ = the output (@HCHACHA_OUTSZ@ bytes)
174 *
175 * Returns: ---
176 *
177 * Use: Apply the HChaCha/r pseudorandom function to @src@, writing
178 * the result to @out@.
179 */
180
181extern void hchacha20_prf(chacha_ctx */*ctx*/,
182 const void */*src*/, void */*dest*/);
183extern void hchacha12_prf(chacha_ctx */*ctx*/,
184 const void */*src*/, void */*dest*/);
185extern void hchacha8_prf(chacha_ctx */*ctx*/,
186 const void */*src*/, void */*dest*/);
187
188/*----- The XChaCha stream cipher ----------------------------------------*/
189
190/* --- @xchacha{20,12,8}_init@ --- *
191 *
192 * Arguments: @xchachaR_ctx *ctx@ = the context to fill in
193 * @const void *key@ = pointer to key material
194 * @size_t ksz@ = size of key (either 32 or 16)
195 * @const void *nonce@ = initial nonce, or null
196 *
197 * Returns: ---
198 *
199 * Use: Initializes an XChaCha/r context ready for use.
200 *
201 * There is a different function for each number of rounds,
202 * unlike for plain ChaCha.
203 */
204
205extern void xchacha20_init(xchacha20_ctx */*ctx*/,
206 const void */*key*/, size_t /*ksz*/,
207 const void */*nonce*/);
208extern void xchacha12_init(xchacha12_ctx */*ctx*/,
209 const void */*key*/, size_t /*ksz*/,
210 const void */*nonce*/);
211extern void xchacha8_init(xchacha8_ctx */*ctx*/,
212 const void */*key*/, size_t /*ksz*/,
213 const void */*nonce*/);
214
215/* --- @xchacha{20,12,8}_setnonce@ --- *
216 *
217 * Arguments: @xchachaR_ctx *ctx@ = pointer to context
218 * @const void *nonce@ = the nonce (@XCHACHA_NONCESZ@ bytes)
219 *
220 * Returns: ---
221 *
222 * Use: Set a new nonce in the context @ctx@, e.g., for processing a
223 * different message. The stream position is reset to zero (see
224 * @chacha_seek@ etc.).
225 *
226 * There is a different function for each number of rounds,
227 * unlike for plain ChaCha.
228 */
229
230extern void xchacha20_setnonce(xchacha20_ctx */*ctx*/,
231 const void */*nonce*/);
232extern void xchacha12_setnonce(xchacha12_ctx */*ctx*/,
233 const void */*nonce*/);
234extern void xchacha8_setnonce(xchacha8_ctx */*ctx*/,
235 const void */*nonce*/);
236
d022e630 237/* --- @xchacha{20,12,8}_seek{,u64}@ --- *
55d81656
MW
238 *
239 * Arguments: @xchachaR_ctx *ctx@ = pointer to context
240 * @unsigned long i@, @kludge64 i@ = new position to set
241 *
242 * Returns: ---
243 *
244 * Use: Sets a new stream position, in units of ChaCha output
245 * blocks, which are @XCHACHA_OUTSZ@ bytes each. Byte
246 * granularity can be achieved by calling @xchachaR_encrypt@
247 * appropriately.
248 *
249 * There is a different function for each number of rounds,
250 * unlike for plain ChaCha, because the context structures are
251 * different.
252 */
253
254extern void xchacha20_seek(xchacha20_ctx */*ctx*/, unsigned long /*i*/);
255extern void xchacha12_seek(xchacha12_ctx */*ctx*/, unsigned long /*i*/);
256extern void xchacha8_seek(xchacha8_ctx */*ctx*/, unsigned long /*i*/);
257extern void xchacha20_seeku64(xchacha20_ctx */*ctx*/, kludge64 /*i*/);
258extern void xchacha12_seeku64(xchacha12_ctx */*ctx*/, kludge64 /*i*/);
259extern void xchacha8_seeku64(xchacha8_ctx */*ctx*/, kludge64 /*i*/);
260
d022e630 261/* --- @xchacha{20,12,8}_tell{,u64}@ --- *
55d81656
MW
262 *
263 * Arguments: @chacha_ctx *ctx@ = pointer to context
264 *
265 * Returns: The current position in the output stream, in blocks,
266 * rounding upwards.
267 *
268 * There is a different function for each number of rounds,
269 * unlike for plain ChaCha, because the context structures are
270 * different.
271 */
272
273extern unsigned long xchacha20_tell(xchacha20_ctx */*ctx*/);
274extern unsigned long xchacha12_tell(xchacha12_ctx */*ctx*/);
275extern unsigned long xchacha8_tell(xchacha8_ctx */*ctx*/);
276extern kludge64 xchacha20_tellu64(xchacha20_ctx */*ctx*/);
277extern kludge64 xchacha12_tellu64(xchacha12_ctx */*ctx*/);
278extern kludge64 xchacha8_tellu64(xchacha8_ctx */*ctx*/);
279
280/* --- @xchacha{20,12,8}_encrypt@ --- *
281 *
282 * Arguments: @xchachaR_ctx *ctx@ = pointer to context
283 * @const void *src@ = source buffer (or null)
284 * @void *dest@ = destination buffer (or null)
285 * @size_t sz@ = size of the buffers
286 *
287 * Returns: ---
288 *
289 * Use: Encrypts or decrypts @sz@ bytes of data from @src@ to @dest@.
290 * XChaCha works by XORing plaintext with a keystream, so
291 * encryption and decryption are the same operation. If @dest@
292 * is null then ignore @src@ and skip @sz@ bytes of the
293 * keystream. If @src@ is null, then just write the keystream
294 * to @dest@.
295 */
296
297extern void xchacha20_encrypt(xchacha20_ctx */*ctx*/,
298 const void */*src*/, void */*dest*/,
299 size_t /*sz*/);
300extern void xchacha12_encrypt(xchacha12_ctx */*ctx*/,
301 const void */*src*/, void */*dest*/,
302 size_t /*sz*/);
303extern void xchacha8_encrypt(xchacha8_ctx */*ctx*/,
304 const void */*src*/, void */*dest*/,
305 size_t /*sz*/);
306
307/*----- Generic cipher interface ------------------------------------------*/
308
309extern const octet chacha_keysz[];
310#define chacha20_keysz chacha_keysz
311#define chacha12_keysz chacha_keysz
312#define chacha8_keysz chacha_keysz
1778ca95
MW
313#define chacha_ietf_keysz chacha_keysz
314#define chacha20_ietf_keysz chacha_keysz
315#define chacha12_ietf_keysz chacha_keysz
316#define chacha8_ietf_keysz chacha_keysz
55d81656
MW
317#define xchacha_keysz chacha_keysz
318#define xchacha20_keysz chacha_keysz
319#define xchacha12_keysz chacha_keysz
320#define xchacha8_keysz chacha_keysz
321
6a265416
MW
322extern const gccipher chacha20, chacha12, chacha8;
323extern const gccipher chacha20_ietf, chacha12_ietf, chacha8_ietf;
324extern const gccipher xchacha20, xchacha12, xchacha8;
55d81656
MW
325
326/*----- Generic random number generator interface -------------------------*/
327
1778ca95 328/* --- @chacha{20,12,8}{,_ietf}_rand@, @xchacha{20,12,8}_rand@ --- *
55d81656
MW
329 *
330 * Arguments: @const void *k@ = pointer to key material
331 * @size_t ksz@ = size of key material
332 * @const void *n@ = pointer to nonce or null
1778ca95
MW
333 * (@CHACHA_NONCESZ@, @CHACHA_IETF_NONCESZ@, or
334 * @XCHACHA_NONCESZ@)
55d81656
MW
335 *
336 * Returns: Pointer to generic random number generator instance.
337 *
338 * Use: Creates a random number interface wrapper around
339 * the ChaCha or XChaCha stream ciphers.
340 */
341
342extern grand *chacha20_rand(const void */*k*/, size_t /*ksz*/,
343 const void */*n*/);
344extern grand *chacha12_rand(const void */*k*/, size_t /*ksz*/,
345 const void */*n*/);
346extern grand *chacha8_rand(const void */*k*/, size_t /*ksz*/,
347 const void */*n*/);
1778ca95
MW
348extern grand *chacha20_ietf_rand(const void */*k*/, size_t /*ksz*/,
349 const void */*n*/);
350extern grand *chacha12_ietf_rand(const void */*k*/, size_t /*ksz*/,
351 const void */*n*/);
352extern grand *chacha8_ietf_rand(const void */*k*/, size_t /*ksz*/,
353 const void */*n*/);
55d81656
MW
354extern grand *xchacha20_rand(const void */*k*/, size_t /*ksz*/,
355 const void */*n*/);
356extern grand *xchacha12_rand(const void */*k*/, size_t /*ksz*/,
357 const void */*n*/);
358extern grand *xchacha8_rand(const void */*k*/, size_t /*ksz*/,
359 const void */*n*/);
360
361enum {
362 CHACHA_SEEK = GRAND_SPECIFIC('S'), /* @unsigned long pos@ */
363 CHACHA_SEEKU64, /* @kludge64 pos@ */
364 CHACHA_TELL, /* @unsigned long *pos@ */
365 CHACHA_TELLU64 /* @kludge64 *pos@ */
366};
367
368/*----- That's all, folks -------------------------------------------------*/
369
370#ifdef __cplusplus
371 }
372#endif
373
374#endif