chiark / gitweb /
symm/{chacha,salsa20}.h: Mark the cipher classes as `extern'.
[catacomb] / symm / chacha.h
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
50 #define CHACHA_IETF_NONCESZ 12u
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
63 typedef uint32 chacha_matrix[16];
64
65 typedef struct chacha_ctx {
66   chacha_matrix a;
67   octet buf[CHACHA_OUTSZ];
68   size_t bufi;
69 } chacha_ctx;
70
71 #define XCHACHA_DEFCTX(name)                                            \
72   typedef struct name { chacha_ctx s; chacha_matrix k; } name
73 XCHACHA_DEFCTX(xchacha20_ctx);
74 XCHACHA_DEFCTX(xchacha12_ctx);
75 XCHACHA_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
91 extern void chacha_init(chacha_ctx */*ctx*/,
92                          const void */*key*/, size_t /*ksz*/,
93                          const void */*nonce*/);
94
95 /* --- @chacha_setnonce{,_ietf}@ --- *
96  *
97  * Arguments:   @chacha_ctx *ctx@ = pointer to context
98  *              @const void *nonce@ = the nonce (@CHACHA_NONCESZ@ or
99  *                      @CHACHA_IETF_NONCESZ@ bytes)
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
108 extern void chacha_setnonce(chacha_ctx */*ctx*/, const void */*nonce*/);
109 extern void chacha_setnonce_ietf(chacha_ctx */*ctx*/, const void */*nonce*/);
110
111 /* --- @chacha_seek{,u64,_ietf}@ --- *
112  *
113  * Arguments:   @chacha_ctx *ctx@ = pointer to context
114  *              @unsigned long i@, @kludge64 i@, @uint32 i@ = new position
115  *
116  * Returns:     ---
117  *
118  * Use:         Sets a new stream position, in units of Chacha output
119  *              blocks, which are @CHACHA_OUTSZ@ bytes each.  Byte
120  *              granularity can be achieved by calling @chachaR_encrypt@
121  *              appropriately.
122  */
123
124 extern void chacha_seek(chacha_ctx */*ctx*/, unsigned long /*i*/);
125 extern void chacha_seeku64(chacha_ctx */*ctx*/, kludge64 /*i*/);
126 extern void chacha_seek_ietf(chacha_ctx */*ctx*/, uint32 /*i*/);
127
128 /* --- @chacha_tell{,u64,_ietf}@ --- *
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
136 extern unsigned long chacha_tell(chacha_ctx */*ctx*/);
137 extern kludge64 chacha_tellu64(chacha_ctx */*ctx*/);
138 extern uint32 chacha_tell_ietf(chacha_ctx */*ctx*/);
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
157 extern void chacha20_encrypt(chacha_ctx */*ctx*/,
158                              const void */*src*/, void */*dest*/,
159                              size_t /*sz*/);
160 extern void chacha12_encrypt(chacha_ctx */*ctx*/,
161                               const void */*src*/, void */*dest*/,
162                               size_t /*sz*/);
163 extern 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
181 extern void hchacha20_prf(chacha_ctx */*ctx*/,
182                           const void */*src*/, void */*dest*/);
183 extern void hchacha12_prf(chacha_ctx */*ctx*/,
184                           const void */*src*/, void */*dest*/);
185 extern 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
205 extern void xchacha20_init(xchacha20_ctx */*ctx*/,
206                            const void */*key*/, size_t /*ksz*/,
207                            const void */*nonce*/);
208 extern void xchacha12_init(xchacha12_ctx */*ctx*/,
209                             const void */*key*/, size_t /*ksz*/,
210                             const void */*nonce*/);
211 extern 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
230 extern void xchacha20_setnonce(xchacha20_ctx */*ctx*/,
231                                const void */*nonce*/);
232 extern void xchacha12_setnonce(xchacha12_ctx */*ctx*/,
233                                 const void */*nonce*/);
234 extern void xchacha8_setnonce(xchacha8_ctx */*ctx*/,
235                                const void */*nonce*/);
236
237 /* --- @xchacha{20,12,8}_seek{,u64}@ --- *
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
254 extern void xchacha20_seek(xchacha20_ctx */*ctx*/, unsigned long /*i*/);
255 extern void xchacha12_seek(xchacha12_ctx */*ctx*/, unsigned long /*i*/);
256 extern void xchacha8_seek(xchacha8_ctx */*ctx*/, unsigned long /*i*/);
257 extern void xchacha20_seeku64(xchacha20_ctx */*ctx*/, kludge64 /*i*/);
258 extern void xchacha12_seeku64(xchacha12_ctx */*ctx*/, kludge64 /*i*/);
259 extern void xchacha8_seeku64(xchacha8_ctx */*ctx*/, kludge64 /*i*/);
260
261 /* --- @xchacha{20,12,8}_tell{,u64}@ --- *
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
273 extern unsigned long xchacha20_tell(xchacha20_ctx */*ctx*/);
274 extern unsigned long xchacha12_tell(xchacha12_ctx */*ctx*/);
275 extern unsigned long xchacha8_tell(xchacha8_ctx */*ctx*/);
276 extern kludge64 xchacha20_tellu64(xchacha20_ctx */*ctx*/);
277 extern kludge64 xchacha12_tellu64(xchacha12_ctx */*ctx*/);
278 extern 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
297 extern void xchacha20_encrypt(xchacha20_ctx */*ctx*/,
298                             const void */*src*/, void */*dest*/,
299                             size_t /*sz*/);
300 extern void xchacha12_encrypt(xchacha12_ctx */*ctx*/,
301                               const void */*src*/, void */*dest*/,
302                               size_t /*sz*/);
303 extern void xchacha8_encrypt(xchacha8_ctx */*ctx*/,
304                               const void */*src*/, void */*dest*/,
305                               size_t /*sz*/);
306
307 /*----- Generic cipher interface ------------------------------------------*/
308
309 extern const octet chacha_keysz[];
310 #define chacha20_keysz chacha_keysz
311 #define chacha12_keysz chacha_keysz
312 #define chacha8_keysz chacha_keysz
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
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
322 extern const gccipher chacha20, chacha12, chacha8;
323 extern const gccipher chacha20_ietf, chacha12_ietf, chacha8_ietf;
324 extern const gccipher xchacha20, xchacha12, xchacha8;
325
326 /*----- Generic random number generator interface -------------------------*/
327
328 /* --- @chacha{20,12,8}{,_ietf}_rand@, @xchacha{20,12,8}_rand@ --- *
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
333  *                              (@CHACHA_NONCESZ@, @CHACHA_IETF_NONCESZ@, or
334  *                              @XCHACHA_NONCESZ@)
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
342 extern grand *chacha20_rand(const void */*k*/, size_t /*ksz*/,
343                             const void */*n*/);
344 extern grand *chacha12_rand(const void */*k*/, size_t /*ksz*/,
345                             const void */*n*/);
346 extern grand *chacha8_rand(const void */*k*/, size_t /*ksz*/,
347                            const void */*n*/);
348 extern grand *chacha20_ietf_rand(const void */*k*/, size_t /*ksz*/,
349                                  const void */*n*/);
350 extern grand *chacha12_ietf_rand(const void */*k*/, size_t /*ksz*/,
351                                  const void */*n*/);
352 extern grand *chacha8_ietf_rand(const void */*k*/, size_t /*ksz*/,
353                                 const void */*n*/);
354 extern grand *xchacha20_rand(const void */*k*/, size_t /*ksz*/,
355                              const void */*n*/);
356 extern grand *xchacha12_rand(const void */*k*/, size_t /*ksz*/,
357                              const void */*n*/);
358 extern grand *xchacha8_rand(const void */*k*/, size_t /*ksz*/,
359                             const void */*n*/);
360
361 enum {
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