chiark / gitweb /
pub/, progs/: Add support for X448 key exchange, defined in RFC7748.
[catacomb] / symm / salsa20.h
1 /* -*-c-*-
2  *
3  * Salsa20 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_SALSA20_H
29 #define CATACOMB_SALSA20_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 SALSA20_NONCESZ 8u
50 #define SALSA20_KEYSZ 32u
51 #define SALSA20_OUTSZ 64u
52
53 #define HSALSA20_INSZ 16u
54 #define HSALSA20_OUTSZ 32u
55
56 #define XSALSA20_NONCESZ 24u
57 #define XSALSA20_KEYSZ SALSA20_KEYSZ
58 #define XSALSA20_OUTSZ SALSA20_OUTSZ
59
60 /*----- Data structures ---------------------------------------------------*/
61
62 typedef uint32 salsa20_matrix[16];
63
64 typedef struct salsa20_ctx {
65   salsa20_matrix a;
66   octet buf[SALSA20_OUTSZ];
67   size_t bufi;
68 } salsa20_ctx;
69
70 #define XSALSA20_DEFCTX(name)                                           \
71   typedef struct name { salsa20_ctx s; salsa20_matrix k; } name
72 XSALSA20_DEFCTX(xsalsa20_ctx);
73 XSALSA20_DEFCTX(xsalsa2012_ctx);
74 XSALSA20_DEFCTX(xsalsa208_ctx);
75
76 /*----- The Salsa20 stream cipher -----------------------------------------*/
77
78 /* --- @salsa20_init@ --- *
79  *
80  * Arguments:   @salsa20_ctx *ctx@ = context to fill in
81  *              @const void *key@ = pointer to key material
82  *              @size_t ksz@ = size of key (either 32 or 16)
83  *              @const void *nonce@ = initial nonce, or null
84  *
85  * Returns:     ---
86  *
87  * Use:         Initializes a Salsa20 context ready for use.
88  */
89
90 extern void salsa20_init(salsa20_ctx */*ctx*/,
91                          const void */*key*/, size_t /*ksz*/,
92                          const void */*nonce*/);
93
94 /* --- @salsa20_setnonce@ --- *
95  *
96  * Arguments:   @salsa20_ctx *ctx@ = pointer to context
97  *              @const void *nonce@ = the nonce (@SALSA20_NONCESZ@ bytes)
98  *
99  * Returns:     ---
100  *
101  * Use:         Set a new nonce in the context @ctx@, e.g., for processing a
102  *              different message.  The stream position is reset to zero (see
103  *              @salsa20_seek@ etc.).
104  */
105
106 extern void salsa20_setnonce(salsa20_ctx */*ctx*/, const void */*nonce*/);
107
108 /* --- @salsa20_seek@, @salsa20_seeku64@ --- *
109  *
110  * Arguments:   @salsa20_ctx *ctx@ = pointer to context
111  *              @unsigned long i@, @kludge64 i@ = new position to set
112  *
113  * Returns:     ---
114  *
115  * Use:         Sets a new stream position, in units of Salsa20 output
116  *              blocks, which are @SALSA20_OUTSZ@ bytes each.  Byte
117  *              granularity can be achieved by calling @salsa20_encrypt@
118  *              appropriately.
119  */
120
121 extern void salsa20_seek(salsa20_ctx */*ctx*/, unsigned long /*i*/);
122 extern void salsa20_seeku64(salsa20_ctx */*ctx*/, kludge64 /*i*/);
123
124 /* --- @salsa20_tell@, @salsa20_tellu64@ --- *
125  *
126  * Arguments:   @salsa20_ctx *ctx@ = pointer to context
127  *
128  * Returns:     The current position in the output stream, in blocks,
129  *              rounding upwards.
130  */
131
132 extern unsigned long salsa20_tell(salsa20_ctx */*ctx*/);
133 extern kludge64 salsa20_tellu64(salsa20_ctx */*ctx*/);
134
135 /* --- @salsa20{,12,8}_encrypt@ --- *
136  *
137  * Arguments:   @salsa20_ctx *ctx@ = pointer to context
138  *              @const void *src@ = source buffer (or null)
139  *              @void *dest@ = destination buffer (or null)
140  *              @size_t sz@ = size of the buffers
141  *
142  * Returns:     ---
143  *
144  * Use:         Encrypts or decrypts @sz@ bytes of data from @src@ to @dest@.
145  *              Salsa20 works by XORing plaintext with a keystream, so
146  *              encryption and decryption are the same operation.  If @dest@
147  *              is null then ignore @src@ and skip @sz@ bytes of the
148  *              keystream.  If @src@ is null, then just write the keystream
149  *              to @dest@.
150  */
151
152 extern void salsa20_encrypt(salsa20_ctx */*ctx*/,
153                             const void */*src*/, void */*dest*/,
154                             size_t /*sz*/);
155 extern void salsa2012_encrypt(salsa20_ctx */*ctx*/,
156                               const void */*src*/, void */*dest*/,
157                               size_t /*sz*/);
158 extern void salsa208_encrypt(salsa20_ctx */*ctx*/,
159                               const void */*src*/, void */*dest*/,
160                               size_t /*sz*/);
161
162 /*----- The HSalsa20 pseudorandom function --------------------------------*/
163
164 /* --- @hsalsa20{,12,8}_prf@ --- *
165  *
166  * Arguments:   @salsa20_ctx *ctx@ = pointer to context
167  *              @const void *src@ = the input (@HSALSA20_INSZ@ bytes)
168  *              @void *dest@ = the output (@HSALSA20_OUTSZ@ bytes)
169  *
170  * Returns:     ---
171  *
172  * Use:         Apply the HSalsa20/r pseudorandom function to @src@, writing
173  *              the result to @out@.
174  */
175
176 extern void hsalsa20_prf(salsa20_ctx */*ctx*/,
177                          const void */*src*/, void */*dest*/);
178 extern void hsalsa2012_prf(salsa20_ctx */*ctx*/,
179                            const void */*src*/, void */*dest*/);
180 extern void hsalsa208_prf(salsa20_ctx */*ctx*/,
181                           const void */*src*/, void */*dest*/);
182
183 /*----- The XSalsa20 stream cipher ----------------------------------------*/
184
185 /* --- @xsalsa20{,12,8}_init@ --- *
186  *
187  * Arguments:   @xsalsa20R_ctx *ctx@ = the context to fill in
188  *              @const void *key@ = pointer to key material
189  *              @size_t ksz@ = size of key (either 32 or 16)
190  *              @const void *nonce@ = initial nonce, or null
191  *
192  * Returns:     ---
193  *
194  * Use:         Initializes an XSalsa20/r context ready for use.
195  *
196  *              There is a different function for each number of rounds,
197  *              unlike for plain Salsa20.
198  */
199
200 extern void xsalsa20_init(xsalsa20_ctx */*ctx*/,
201                           const void */*key*/, size_t /*ksz*/,
202                           const void */*nonce*/);
203 extern void xsalsa2012_init(xsalsa2012_ctx */*ctx*/,
204                             const void */*key*/, size_t /*ksz*/,
205                             const void */*nonce*/);
206 extern void xsalsa208_init(xsalsa208_ctx */*ctx*/,
207                            const void */*key*/, size_t /*ksz*/,
208                            const void */*nonce*/);
209
210 /* --- @xsalsa20{,12,8}_setnonce@ --- *
211  *
212  * Arguments:   @xsalsa20R_ctx *ctx@ = pointer to context
213  *              @const void *nonce@ = the nonce (@XSALSA20_NONCESZ@ bytes)
214  *
215  * Returns:     ---
216  *
217  * Use:         Set a new nonce in the context @ctx@, e.g., for processing a
218  *              different message.  The stream position is reset to zero (see
219  *              @salsa20_seek@ etc.).
220  *
221  *              There is a different function for each number of rounds,
222  *              unlike for plain Salsa20.
223  */
224
225 extern void xsalsa20_setnonce(xsalsa20_ctx */*ctx*/,
226                               const void */*nonce*/);
227 extern void xsalsa2012_setnonce(xsalsa2012_ctx */*ctx*/,
228                                 const void */*nonce*/);
229 extern void xsalsa208_setnonce(xsalsa208_ctx */*ctx*/,
230                                const void */*nonce*/);
231
232 /* --- @xsalsa20{,12,8}_seek@, @xsalsa20{,12,8}_seeku64@ --- *
233  *
234  * Arguments:   @xsalsa20R_ctx *ctx@ = pointer to context
235  *              @unsigned long i@, @kludge64 i@ = new position to set
236  *
237  * Returns:     ---
238  *
239  * Use:         Sets a new stream position, in units of Salsa20 output
240  *              blocks, which are @XSALSA20_OUTSZ@ bytes each.  Byte
241  *              granularity can be achieved by calling @xsalsa20R_encrypt@
242  *              appropriately.
243  *
244  *              There is a different function for each number of rounds,
245  *              unlike for plain Salsa20, because the context structures are
246  *              different.
247  */
248
249 extern void xsalsa20_seek(xsalsa20_ctx */*ctx*/, unsigned long /*i*/);
250 extern void xsalsa2012_seek(xsalsa2012_ctx */*ctx*/, unsigned long /*i*/);
251 extern void xsalsa208_seek(xsalsa208_ctx */*ctx*/, unsigned long /*i*/);
252 extern void xsalsa20_seeku64(xsalsa20_ctx */*ctx*/, kludge64 /*i*/);
253 extern void xsalsa2012_seeku64(xsalsa2012_ctx */*ctx*/, kludge64 /*i*/);
254 extern void xsalsa208_seeku64(xsalsa208_ctx */*ctx*/, kludge64 /*i*/);
255
256 /* --- @xsalsa20{,12,8}_tell@, @xsalsa20{,12,8}_tellu64@ --- *
257  *
258  * Arguments:   @salsa20_ctx *ctx@ = pointer to context
259  *
260  * Returns:     The current position in the output stream, in blocks,
261  *              rounding upwards.
262  *
263  *              There is a different function for each number of rounds,
264  *              unlike for plain Salsa20, because the context structures are
265  *              different.
266  */
267
268 extern unsigned long xsalsa20_tell(xsalsa20_ctx */*ctx*/);
269 extern unsigned long xsalsa2012_tell(xsalsa2012_ctx */*ctx*/);
270 extern unsigned long xsalsa208_tell(xsalsa208_ctx */*ctx*/);
271 extern kludge64 xsalsa20_tellu64(xsalsa20_ctx */*ctx*/);
272 extern kludge64 xsalsa2012_tellu64(xsalsa2012_ctx */*ctx*/);
273 extern kludge64 xsalsa208_tellu64(xsalsa208_ctx */*ctx*/);
274
275 /* --- @xsalsa20{,12,8}_encrypt@ --- *
276  *
277  * Arguments:   @xsalsa20R_ctx *ctx@ = pointer to context
278  *              @const void *src@ = source buffer (or null)
279  *              @void *dest@ = destination buffer (or null)
280  *              @size_t sz@ = size of the buffers
281  *
282  * Returns:     ---
283  *
284  * Use:         Encrypts or decrypts @sz@ bytes of data from @src@ to @dest@.
285  *              XSalsa20 works by XORing plaintext with a keystream, so
286  *              encryption and decryption are the same operation.  If @dest@
287  *              is null then ignore @src@ and skip @sz@ bytes of the
288  *              keystream.  If @src@ is null, then just write the keystream
289  *              to @dest@.
290  */
291
292 extern void xsalsa20_encrypt(xsalsa20_ctx */*ctx*/,
293                             const void */*src*/, void */*dest*/,
294                             size_t /*sz*/);
295 extern void xsalsa2012_encrypt(xsalsa2012_ctx */*ctx*/,
296                               const void */*src*/, void */*dest*/,
297                               size_t /*sz*/);
298 extern void xsalsa208_encrypt(xsalsa208_ctx */*ctx*/,
299                               const void */*src*/, void */*dest*/,
300                               size_t /*sz*/);
301
302 /*----- Generic cipher interface ------------------------------------------*/
303
304 extern const octet salsa20_keysz[];
305 #define salsa2012_keysz salsa20_keysz
306 #define salsa208_keysz salsa20_keysz
307 #define xsalsa20_keysz salsa20_keysz
308 #define xsalsa2012_keysz salsa20_keysz
309 #define xsalsa208_keysz salsa20_keysz
310
311 const gccipher salsa20, salsa2012, salsa208;
312 const gccipher xsalsa20, xsalsa2012, xsalsa208;
313
314 /*----- Generic random number generator interface -------------------------*/
315
316 /* --- @salsa20{,12,8}_rand@, @xsalsa20{,12,8}_rand@ --- *
317  *
318  * Arguments:           @const void *k@ = pointer to key material
319  *                      @size_t ksz@ = size of key material
320  *                      @const void *n@ = pointer to nonce or null
321  *                              (@SALSA20_NONCESZ@ or @XSALSA20_NONCESZ@)
322  *
323  * Returns:             Pointer to generic random number generator instance.
324  *
325  * Use:                 Creates a random number interface wrapper around
326  *                      the Salsa20/r or XSalsa20/r stream ciphers.
327  */
328
329 extern grand *salsa20_rand(const void */*k*/, size_t /*ksz*/,
330                            const void */*n*/);
331 extern grand *salsa2012_rand(const void */*k*/, size_t /*ksz*/,
332                              const void */*n*/);
333 extern grand *salsa208_rand(const void */*k*/, size_t /*ksz*/,
334                             const void */*n*/);
335 extern grand *xsalsa20_rand(const void */*k*/, size_t /*ksz*/,
336                             const void */*n*/);
337 extern grand *xsalsa2012_rand(const void */*k*/, size_t /*ksz*/,
338                               const void */*n*/);
339 extern grand *xsalsa208_rand(const void */*k*/, size_t /*ksz*/,
340                              const void */*n*/);
341
342 enum {
343   SALSA20_SEEK = GRAND_SPECIFIC('S'),   /* @unsigned long pos@ */
344   SALSA20_SEEKU64,                      /* @kludge64 pos@ */
345   SALSA20_TELL,                         /* @unsigned long *pos@ */
346   SALSA20_TELLU64                       /* @kludge64 *pos@ */
347 };
348
349 /*----- That's all, folks -------------------------------------------------*/
350
351 #ifdef __cplusplus
352   }
353 #endif
354
355 #endif