doc/disorder_options.5.html
doc/disorder_actions.5.in
doc/disorder_templates.5.in
-libtests/t-arcfour
libtests/t-charset
libtests/t-event
libtests/t-dateparse
.dirstamp
tests/*.trs
/common/Makefile
+libtests/t-salsa208
libdisorder_a_SOURCES=charset.c charsetf.c charset.h \
addr.c addr.h \
- arcfour.c arcfour.h \
authhash.c authhash.h \
basen.c basen.h \
base64.c base64.h \
resample.c resample.h \
rights.c queue-rights.c rights.h \
rtp.h \
+ salsa208.c salsa208.h \
selection.c selection.h \
sendmail.c sendmail.h \
signame.c signame.h \
+++ /dev/null
-/* arcfour.c --- The arcfour stream cipher
- * Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006 Free Software
- * Foundation, Inc.
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * This file is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this file; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- */
-/** @file lib/arcfour.c
- * @brief Arcfour (RC4-compatible) stream cipher implementation
- *
- * Code from Libgcrypt adapted for gnulib by Simon Josefsson.
- *
- * For a description of the algorithm, see:
- *
- * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
- * ISBN 0-471-11709-9. Pages 397 ff.
- */
-
-#include "arcfour.h"
-
-/** @brief Encrypt using Arcfour stream cipher
- * @param context Context structure
- * @param inbuf Input buffer
- * @param outbuf Output buffer
- * @param length Number of bytes in @p inbuf
- *
- * Copies from @p inbuf to @p outbuf, encrypting (or decrypting) using
- * the stream controlled by @p context.
- */
-void
-arcfour_stream (arcfour_context * context, const char *inbuf, char *outbuf,
- size_t length)
-{
- uint8_t i = context->idx_i;
- uint8_t j = context->idx_j;
- char *sbox = context->sbox;
-
- for (; length > 0; length--)
- {
- char t;
-
- i++;
- j += sbox[i];
- t = sbox[i];
- sbox[i] = sbox[j];
- sbox[j] = t;
- *outbuf++ = (*inbuf++
- ^ sbox[(0U + sbox[i] + sbox[j]) % ARCFOUR_SBOX_SIZE]);
- }
-
- context->idx_i = i;
- context->idx_j = j;
-}
-
-/** @brief Initialize an @ref arcfour_context
- * @param context Context structure
- * @param key Key data
- * @param keylen Length of key
- *
- * Initializes @p context using @p key.
- */
-void
-arcfour_setkey (arcfour_context * context, const char *key, size_t keylen)
-{
- size_t i, j, k;
- char *sbox = context->sbox;
-
- context->idx_i = context->idx_j = 0;
- for (i = 0; i < ARCFOUR_SBOX_SIZE; i++)
- sbox[i] = i;
- for (i = j = k = 0; i < ARCFOUR_SBOX_SIZE; i++)
- {
- char t;
- j = (j + sbox[i] + key[k]) % ARCFOUR_SBOX_SIZE;
- t = sbox[i];
- sbox[i] = sbox[j];
- sbox[j] = t;
- if (++k == keylen)
- k = 0;
- }
-}
+++ /dev/null
-/* arcfour.h --- The arcfour stream cipher
- * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
- * Free Software Foundation, Inc.
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * This file is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this file; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- */
-/** @file lib/arcfour.h
- * @brief Arcfour (RC4-compatible) stream cipher implementation
- */
-
-/* Code from Libgcrypt adapted for gnulib by Simon Josefsson. */
-
-#ifndef ARCFOUR_H
-# define ARCFOUR_H
-
-# include <stddef.h>
-# include <stdint.h>
-
-#define ARCFOUR_SBOX_SIZE 256
-
-/** @brief Context structture for Arcfour stream cipher */
-typedef struct
-{
- char sbox[ARCFOUR_SBOX_SIZE];
- uint8_t idx_i, idx_j;
-} arcfour_context;
-
-/* Apply ARCFOUR stream to INBUF placing the result in OUTBUF, both of
- LENGTH size. CONTEXT must be initialized with arcfour_setkey
- before this function is called. */
-extern void
-arcfour_stream (arcfour_context * context,
- const char *inbuf, char *outbuf, size_t length);
-
-/* Initialize CONTEXT using encryption KEY of KEYLEN bytes. KEY
- should be 40 bits (5 bytes) or longer. The KEY cannot be zero
- length. */
-extern void
-arcfour_setkey (arcfour_context * context, const char *key, size_t keylen);
-
-#endif /* ARCFOUR_H */
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="addr.c" />
- <ClCompile Include="arcfour.c" />
<ClCompile Include="asprintf.c" />
<ClCompile Include="authhash.c" />
<ClCompile Include="base64.c" />
<ClCompile Include="queue-rights.c" />
<ClCompile Include="queue.c" />
<ClCompile Include="rights.c" />
+ <ClCompile Include="salsa208.c" />
<ClCompile Include="selection.c" />
<ClCompile Include="signame.c" />
<ClCompile Include="sink.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="addr.h" />
- <ClInclude Include="arcfour.h" />
<ClInclude Include="authhash.h" />
<ClInclude Include="base64.h" />
<ClInclude Include="basen.h" />
<ClInclude Include="printf.h" />
<ClInclude Include="queue.h" />
<ClInclude Include="rights.h" />
+ <ClInclude Include="salsa208.h" />
<ClInclude Include="selection.h" />
<ClInclude Include="signame.h" />
<ClInclude Include="sink.h" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<ClCompile Include="table.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="arcfour.c">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="asprintf.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="versionstring.c">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="salsa208.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="common.h">
<ClInclude Include="table.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="arcfour.h">
- <Filter>Header Files</Filter>
- </ClInclude>
<ClInclude Include="authhash.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="defs.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="salsa208.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
#include "random.h"
#include "log.h"
-#include "arcfour.h"
+#include "salsa208.h"
#include "basen.h"
#include "mem.h"
static int random_count;
static int random_fd = -1;
-static arcfour_context random_ctx[1];
+static salsa208_context random_ctx[1];
/** @brief Rekey the RNG
*
* Resets the RNG's key to a random one read from /dev/urandom
*/
static void random__rekey(void) {
- char key[128];
+ char key[32];
int n;
if(random_fd < 0) {
disorder_fatal(errno, "reading from /dev/urandom");
if((size_t)n < sizeof key)
disorder_fatal(0, "reading from /dev/urandom: short read");
- arcfour_setkey(random_ctx, key, sizeof key);
- random_count = 8 * 1024 * 1024;
+ salsa208_setkey(random_ctx, key, sizeof key);
+ random_count = 256 * 1024 * 1024;
}
/** @brief Get random bytes
void random_get(void *ptr, size_t bytes) {
if(random_count == 0)
random__rekey();
- /* Encrypting 0s == just returning the keystream */
- memset(ptr, 0, bytes);
- arcfour_stream(random_ctx, (char *)ptr, (char *)ptr, bytes);
+ salsa208_stream(random_ctx, 0, ptr, bytes);
if(bytes > (size_t)random_count)
random_count = 0;
else
--- /dev/null
+/* salsa208.c --- The Salsa20/8 stream cipher
+ * Copyright (C) Mark Wooding
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+/** @file lib/salsa208.c
+ * @brief Salsa20/8 stream cipher implementation
+ *
+ * For a description of the algorithm, see:
+ *
+ * Daniel J. Bernstein, `The Salsa20 family of stream ciphers', in Matthew
+ * Robshaw and Olivier Billet (eds.), `New Stream Cipher Designs',
+ * Springer--Verlag 2008, pp. 84--97;
+ * http://cr.yp.to/snuffle/salsafamily-20071225.pdf
+ *
+ * As far as I know, the best attack against all 8 rounds of Salsa20/8 is by
+ * Aumasson, Fischer, Khazaei, Meier, and Rechberger, which takes 2^251
+ * operations to recover a 256-bit key, which is hopelessly impractical.
+ * Much more effective attacks are known against Salsa20/7, so we would have
+ * a tiny security margin if we were trying for security -- but we aren't.
+ * Instead, we want high-quality randomness for queue ids and for selecting
+ * random tracks. (The cookie machinery, which does want cryptographic
+ * security, makes its own arrangements.) Specifically, the intention is to
+ * replace RC4, which (a) is slow because it has a long dependency chain
+ * which plays badly with the deep pipelines in modern CPUs, and (b) has
+ * well-known and rather embarassing biases. On the other hand, Salsa20/8
+ * has no known biases, and admits considerable instruction-level
+ * parallelism. In practice, Salsa20/8 is about 30% faster than RC4 even
+ * without a fancy SIMD implementation (which is good, because this isn't one
+ * of those); a vectorized implementation acting on multiple blocks at a time
+ * would be even faster.
+ *
+ * Salsa20/8 has a number of other attractive features, such as being
+ * trivially seekable, but we don't need those here and the necessary
+ * machinery is not implemented.
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include "salsa208.h"
+
+static inline uint32_t ld16(const void *p) {
+ const unsigned char *q = p;
+ return ((uint32_t)q[0] << 0) | ((uint32_t)q[1] << 8);
+}
+
+static inline uint32_t ld32(const void *p) {
+ const unsigned char *q = p;
+ return ((uint32_t)q[0] << 0) | ((uint32_t)q[1] << 8) |
+ ((uint32_t)q[2] << 16) | ((uint32_t)q[3] << 24);
+}
+
+static inline void st32(void *p, uint32_t x) {
+ unsigned char *q = p;
+ q[0] = (x >> 0)&0xff; q[1] = (x >> 8)&0xff;
+ q[2] = (x >> 16)&0xff; q[3] = (x >> 24)&0xff;
+}
+
+static inline uint32_t rol32(uint32_t x, unsigned n)
+ { return (x << n) | (x >> (32 - n)); }
+
+static inline void quarterround(uint32_t m[16], int a, int b, int c, int d) {
+ m[b] ^= rol32(m[a] + m[d], 7); m[c] ^= rol32(m[b] + m[a], 9);
+ m[d] ^= rol32(m[c] + m[b], 13); m[a] ^= rol32(m[d] + m[c], 18);
+}
+
+static void core(salsa208_context *context) {
+ unsigned i;
+ uint32_t t[16];
+
+ /* Copy the state. */
+ for(i = 0; i < 16; i++) t[i] = context->m[i];
+
+ /* Hack on the state. */
+ for(i = 0; i < 4; i++) {
+
+ /* Vertical quarter-rounds. */
+ quarterround(t, 0, 4, 8, 12);
+ quarterround(t, 5, 9, 13, 1);
+ quarterround(t, 10, 14, 2, 6);
+ quarterround(t, 15, 3, 7, 11);
+
+ /* Horizontal quarter-rounds. */
+ quarterround(t, 0, 1, 2, 3);
+ quarterround(t, 5, 6, 7, 4);
+ quarterround(t, 10, 11, 8, 9);
+ quarterround(t, 15, 12, 13, 14);
+ }
+
+ /* Final feedforward. */
+ for(i = 0; i < 16; i++) t[i] += context->m[i];
+
+ /* Output. */
+ for(i = 0; i < 16; i++) st32(context->buf + 4*i, t[i]);
+}
+
+static inline void xorbuf(void *z, const void *x, const void *y, size_t sz) {
+ unsigned char *zz = z;
+ const unsigned char *xx = x, *yy = y;
+
+ if(!xx) memcpy(zz, yy, sz);
+ else while(sz--) *zz++ = *xx++ ^ *yy++;
+}
+
+static inline void step(salsa208_context *context)
+ { if(!++context->m[8]) context->m[9]++; }
+
+/** @brief Encrypt or decrypt data using Salsa20/8.
+ *
+ * @param context The Salsa20/8 context, initialized using salsa208_setkey().
+ * @param inbuf Pointer to input buffer
+ * @param outbuf Pointer to output buffer
+ * @param length Common size of both buffers
+ *
+ * Encrypt or decrypt (the operations are the same) @p length bytes of input
+ * data, writing the result, of the same length, to @p outbuf. The input and
+ * output pointers may be equal; the two buffers may not otherwise overlap.
+ *
+ * If @p inbuf is null, then simply write the next @p length bytes of
+ * Salsa20/8 output to @p outbuf.
+ */
+void salsa208_stream(salsa208_context *context,
+ const void *inbuf, void *outbuf, size_t length) {
+ size_t left = 64 - context->i;
+ unsigned char *z = outbuf;
+ const unsigned char *x = inbuf;
+
+ /* If we can satisfy the request from our buffer then we should do that. */
+ if(length <= left) {
+ xorbuf(z, x, context->buf + context->i, length);
+ context->i += length;
+ return;
+ }
+
+ /* Drain the buffer of what we currently have and cycle the state. */
+ xorbuf(z, x, context->buf + context->i, left);
+ length -= left; z += left; if(x) x += left;
+ core(context); step(context);
+
+ /* Take multiple complete blocks directly. */
+ while(length > 64) {
+ xorbuf(z, x, context->buf, 64);
+ length -= 64; z += 64; if(x) x += 64;
+ core(context); step(context);
+ }
+
+ /* And the final tail end. */
+ xorbuf(z, x, context->buf, length);
+ context->i = length;
+}
+
+/** @brief Initialize a Salsa20/8 context.
+ *
+ * @param context The Salsa20/8 context to initialize
+ * @param key A pointer to the key material
+ * @param keylen The length of the key data, in bytes (must be 10, 16, or 32)
+ *
+ * The context is implicitly initialized with a zero nonce, which is fine if
+ * the key will be used only for a single message. Otherwise, a fresh nonce
+ * should be chosen somehow and set using salsa208_setnonce().
+ */
+void salsa208_setkey(salsa208_context *context,
+ const void *key, size_t keylen) {
+ const unsigned char *k = key;
+ switch(keylen) {
+ case 32:
+ context->m[ 0] = 0x61707865;
+ context->m[ 1] = ld32(k + 0);
+ context->m[ 2] = ld32(k + 4);
+ context->m[ 3] = ld32(k + 8);
+ context->m[ 4] = ld32(k + 12);
+ context->m[ 5] = 0x3320646e;
+ context->m[ 6] = 0;
+ context->m[ 7] = 0;
+ context->m[ 8] = 0;
+ context->m[ 9] = 0;
+ context->m[10] = 0x79622d32;
+ context->m[11] = ld32(k + 16);
+ context->m[12] = ld32(k + 20);
+ context->m[13] = ld32(k + 24);
+ context->m[14] = ld32(k + 28);
+ context->m[15] = 0x6b206574;
+ break;
+ case 16:
+ context->m[ 0] = 0x61707865;
+ context->m[ 1] = ld32(k + 0);
+ context->m[ 2] = ld32(k + 4);
+ context->m[ 3] = ld32(k + 8);
+ context->m[ 4] = ld32(k + 12);
+ context->m[ 5] = 0x3120646e;
+ context->m[ 6] = 0;
+ context->m[ 7] = 0;
+ context->m[ 8] = 0;
+ context->m[ 9] = 0;
+ context->m[10] = 0x79622d36;
+ context->m[11] = context->m[1];
+ context->m[12] = context->m[2];
+ context->m[13] = context->m[3];
+ context->m[14] = context->m[4];
+ context->m[15] = 0x6b206574;
+ break;
+ case 10:
+ context->m[ 0] = 0x61707865;
+ context->m[ 1] = ld32(k + 0);
+ context->m[ 2] = ld32(k + 4);
+ context->m[ 3] = ld16(k + 8);
+ context->m[ 4] = 0;
+ context->m[ 5] = 0x3120646e;
+ context->m[ 6] = 0;
+ context->m[ 7] = 0;
+ context->m[ 8] = 0;
+ context->m[ 9] = 0;
+ context->m[10] = 0x79622d30;
+ context->m[11] = context->m[1];
+ context->m[12] = context->m[2];
+ context->m[13] = context->m[3];
+ context->m[14] = 0;
+ context->m[15] = 0x6b206574;
+ break;
+ default:
+ assert(!"bad Salsa20 key length");
+ }
+ context->i = 64;
+}
+
+/** @brief Set the Salsa20/8 nonce.
+ *
+ * @param context The Salsa20/8 context
+ * @param nonce A pointer to the nonce
+ * @param noncelen The length of the nonce data, in bytes (must be exactly 8)
+ *
+ * The context is automatically rewound to the start of the stream
+ * corresponding to this nonce.
+ */
+void salsa208_setnonce(salsa208_context *context,
+ const void *nonce, size_t noncelen) {
+ const unsigned char *n = nonce;
+ assert(noncelen == 8);
+ context->m[6] = ld32(n + 0);
+ context->m[7] = ld32(n + 4);
+ context->m[8] = context->m[9] = 0;
+ context->i = 64;
+}
--- /dev/null
+/* salsa208.h --- The Salsa20/8 stream cipher
+ * Copyright (C) 2018 Mark Wooding
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+/** @file lib/salsa208.h
+ * @brief Salsa20/8 stream cipher implementation
+ */
+
+#ifndef SALSA208_H
+# define SALSA208_H
+
+# include <stddef.h>
+# include <stdint.h>
+
+/** @brief Context structure for Salsa208 stream cipher */
+typedef struct {
+ uint32_t m[16]; /* the raw state matrix */
+ uint8_t buf[64]; /* current output buffer */
+ unsigned i; /* cursor in output buffer */
+} salsa208_context;
+
+extern void salsa208_stream(salsa208_context *context,
+ const void *inbuf, void *outbuf, size_t length);
+extern void salsa208_setkey(salsa208_context *context,
+ const void *key, size_t keylen);
+extern void salsa208_setnonce(salsa208_context *context,
+ const void *nonce, size_t noncelen);
+
+#endif /* SALSA208_H */
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-TESTS=t-addr t-arcfour t-basen t-bits t-cache t-casefold t-charset \
+TESTS=t-addr t-basen t-bits t-cache t-casefold t-charset \
t-cookies t-dateparse t-event t-filepart t-hash t-heap t-hex \
t-kvp t-mime t-printf t-regsub t-selection t-signame t-sink \
t-split t-syscalls t-trackname t-unicode t-url t-utf8 t-vector \
t-words t-wstat t-macros t-cgi t-eventdist t-resample \
- t-configuration t-timeval
+ t-configuration t-timeval t-salsa208
noinst_PROGRAMS=$(TESTS)
LDADD=../lib/libdisorder.a $(LIBPCRE) $(LIBICONV) $(LIBGC)
t_addr_SOURCES=t-addr.c test.c test.h
-t_arcfour_SOURCES=t-arcfour.c test.c test.h
t_basen_SOURCES=t-basen.c test.c test.h
t_bits_SOURCES=t-bits.c test.c test.h
t_cache_SOURCES=t-cache.c test.c test.h
t_configuration_SOURCES=t-configuration.c test.c test.h
t_configuration_LDADD=$(LDADD) $(LIBGCRYPT)
t_timeval_SOURCES=t-timeval.c test.c test.h
+t_salsa208_SOURCES=t-salsa208.c test.c test.h
check-report: before-check check make-coverage-reports
before-check:
+++ /dev/null
-/*
- * This file is part of DisOrder.
- * Copyright (C) 2008 Richard Kettlewell
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#include "test.h"
-#include "arcfour.h"
-
-#define TEST_ARCFOUR(K, P, C) do { \
- arcfour_setkey(ac, K, strlen(K)); \
- arcfour_stream(ac, P, (char *)output, strlen(P)); \
- output_hex = hex(output, strlen(P)); \
- check_string(output_hex, C); \
-} while(0)
-
-static void test_arcfour(void) {
- arcfour_context ac[1];
- uint8_t output[64];
- char *output_hex;
-
- /* from wikipedia */
- TEST_ARCFOUR("Key", "Plaintext", "bbf316e8d940af0ad3");
- TEST_ARCFOUR("Wiki", "pedia", "1021bf0420");
- TEST_ARCFOUR("Secret", "Attack at dawn", "45a01f645fc35b383552544b9bf5");
-
-}
-
-TEST(arcfour);
-
-/*
-Local Variables:
-c-basic-offset:2
-comment-column:40
-fill-column:79
-indent-tabs-mode:nil
-End:
-*/
--- /dev/null
+/*
+ * This file is part of DisOrder.
+ * Copyright (C) 2008 Richard Kettlewell, 2018 Mark Wooding
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "test.h"
+#include "salsa208.h"
+
+#define TEST_SALSA208(K, N, P, C) do { \
+ Kbytes = unhex(K, &Klen); \
+ salsa208_setkey(ac, Kbytes, Klen); \
+ Nbytes = unhex(N, &Nlen); \
+ salsa208_setnonce(ac, Nbytes, Nlen); \
+ Pbytes = unhex(P, &Plen); \
+ salsa208_stream(ac, Pbytes, output, Plen); \
+ output_hex = hex(output, Plen); \
+ check_string(output_hex, C); \
+} while(0)
+
+static void test_salsa208(void) {
+ salsa208_context ac[1];
+ uint8_t output[80], *Kbytes, *Nbytes, *Pbytes;
+ char *output_hex;
+ size_t Klen, Nlen, Plen;
+
+ /* from the eStream submission */
+ TEST_SALSA208("0f62b5085bae0154a7fa4da0f34699ec3f92e5388bde3184d72a7dd02376c91c",
+ "288ff65dc42b92f9",
+ "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "36ceb42e23ce2fed61d1a4e5a6e0a600dcca12ce4f1316c175c0bde0825d90972f574a7a25665fe6c3b91a70f1b83795330f5cfa8922c8f9b0589beade0b1432");
+
+ /* test against Catacomb implementation; checks XOR, state stepping */
+ TEST_SALSA208("ce9b04eeb18bb1434d6f534880d8516ff65158f60832325269b5c5e517adb27e",
+ "41f4e1e0db3ef6f2",
+ "d3df3ab24ce7ef617148fdd461757d81b1b3abecb808b4e3ebb542675597c0ab6a4ae3888a7717a8eb2f80b8a3ca33e8c4280757b2f71d409c8618ee50648e35810dfdcbb3ad9436368fde5e645ef019",
+ "3132381a28814d1989bcf09656e64a0ee8c6dd723a3ba5f6a02111f86f5156321ea7300976b2393821d44c425754f6cc08b755ea07287cc77fead40c581259d24d127880b7597fc6a9ea8fba89dd3f4c");
+}
+
+TEST(salsa208);
+
+/*
+Local Variables:
+c-basic-offset:2
+comment-column:40
+fill-column:79
+indent-tabs-mode:nil
+End:
+*/