diff options
author | Niels Möller <nisse@lysator.liu.se> | 2014-01-27 13:42:42 +0100 |
---|---|---|
committer | Niels Möller <nisse@lysator.liu.se> | 2014-01-27 13:42:42 +0100 |
commit | 93fc1d1460fdba49c100f880dfab16aa6402d552 (patch) | |
tree | 5db9d1695580015bd3aa8a2e7571e118925b5118 | |
parent | e57d2fe2e0385f219e1e4f7adc051ad6b98905c1 (diff) | |
download | nettle-93fc1d1460fdba49c100f880dfab16aa6402d552.tar.gz |
Implemented chacha, based on contribution by Joachim Strömbergson.
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | Makefile.in | 9 | ||||
-rw-r--r-- | chacha-core-internal.c | 120 | ||||
-rw-r--r-- | chacha-crypt.c | 78 | ||||
-rw-r--r-- | chacha-set-iv.c | 53 | ||||
-rw-r--r-- | chacha-set-key.c | 43 | ||||
-rw-r--r-- | chacha.h | 97 | ||||
-rw-r--r-- | chacha128-set-key.c | 61 | ||||
-rw-r--r-- | chacha256-set-key.c | 65 | ||||
-rw-r--r-- | testsuite/.test-rules.make | 3 | ||||
-rw-r--r-- | testsuite/Makefile.in | 2 | ||||
-rw-r--r-- | testsuite/chacha-test.c | 344 |
12 files changed, 887 insertions, 4 deletions
@@ -1,3 +1,19 @@ +2014-01-27 Niels Möller <nisse@lysator.liu.se> + + Chacha implementation, based on contribution by Joachim + Strömbergson. + * chacha.h: New file. + * chacha256-set-key.c (chacha256_set_key): New file and function. + * chacha128-set-key.c (chacha128_set_key): New file and function. + * chacha-set-key.c (chacha_set_key): New file and function. + * chacha-set-iv.c (chacha_set_iv): New file and function. + * chacha-core-internal.c (_chacha_core): New file and function. + * chacha-crypt.c (chacha_crypt): New file and function. + * Makefile.in (nettle_SOURCES): Added chacha files. + (HEADERS): Added chacha.h. + * testsuite/chacha-test.c: New file. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added chacha-test.c. + 2014-01-26 Niels Möller <nisse@lysator.liu.se> * nettle-internal.h (_NETTLE_AEAD_FIX): Renamed to... diff --git a/Makefile.in b/Makefile.in index 7292ea26..1d339ace 100644 --- a/Makefile.in +++ b/Makefile.in @@ -86,8 +86,11 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \ camellia256-set-decrypt-key.c \ camellia256-meta.c \ cast128.c cast128-meta.c \ - blowfish.c \ - cbc.c ctr.c gcm.c \ + blowfish.c cbc.c \ + chacha-crypt.c chacha-core-internal.c \ + chacha-set-iv.c chacha-set-key.c \ + chacha128-set-key.c chacha256-set-key.c \ + ctr.c gcm.c \ gcm-aes.c gcm-aes128.c gcm-aes192.c gcm-aes256.c \ des.c des3.c des-compat.c eax.c \ hmac.c hmac-md5.c hmac-ripemd160.c hmac-sha1.c \ @@ -159,7 +162,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \ HEADERS = aes.h arcfour.h arctwo.h asn1.h bignum.h blowfish.h \ base16.h base64.h buffer.h camellia.h cast128.h \ - cbc.h ctr.h \ + cbc.h chacha.h ctr.h \ des.h des-compat.h dsa.h eax.h ecc-curve.h ecc.h ecdsa.h \ gcm.h gosthash94.h hmac.h \ knuth-lfib.h \ diff --git a/chacha-core-internal.c b/chacha-core-internal.c new file mode 100644 index 00000000..fb695ff5 --- /dev/null +++ b/chacha-core-internal.c @@ -0,0 +1,120 @@ +/* chacha-core-internal.c + * + * Core functionality of the ChaCha stream cipher. + * Heavily based on the Salsa20 implementation in Nettle. + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2013 Joachim Strömbergson + * Copyright (C) 2012 Simon Josefsson, Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02111-1301, USA. + */ + +/* Based on: + chacha-ref.c version 2008.01.20. + D. J. Bernstein + Public domain. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <assert.h> +#include <string.h> + +#include "chacha.h" + +#include "macros.h" + +#ifndef CHACHA_DEBUG +# define CHACHA_DEBUG 0 +#endif + +#if CHACHA_DEBUG +# include <stdio.h> +# define DEBUG(i) do { \ + unsigned debug_j; \ + for (debug_j = 0; debug_j < 16; debug_j++) \ + { \ + if (debug_j == 0) \ + fprintf(stderr, "%2d:", (i)); \ + else if (debug_j % 4 == 0) \ + fprintf(stderr, "\n "); \ + fprintf(stderr, " %8x", x[debug_j]); \ + } \ + fprintf(stderr, "\n"); \ + } while (0) +#else +# define DEBUG(i) +#endif + +#ifdef WORDS_BIGENDIAN +#define LE_SWAP32(v) \ + ((ROTL32(8, v) & 0x00FF00FFUL) | \ + (ROTL32(24, v) & 0xFF00FF00UL)) +#else +#define LE_SWAP32(v) (v) +#endif + +#define QROUND(x0, x1, x2, x3) do { \ + x0 = x0 + x1; x3 = ROTL32(16, (x0 ^ x3)); \ + x2 = x2 + x3; x1 = ROTL32(12, (x1 ^ x2)); \ + x0 = x0 + x1; x3 = ROTL32(8, (x0 ^ x3)); \ + x2 = x2 + x3; x1 = ROTL32(7, (x1 ^ x2)); \ + } while(0) + +void +_chacha_core(uint32_t *dst, const uint32_t *src, unsigned rounds) +{ + uint32_t x[_CHACHA_STATE_LENGTH]; + unsigned i; + + assert ( (rounds & 1) == 0); + + memcpy (x, src, sizeof(x)); + for (i = 0; i < rounds;i += 2) + { + DEBUG (i); + QROUND(x[0], x[4], x[8], x[12]); + QROUND(x[1], x[5], x[9], x[13]); + QROUND(x[2], x[6], x[10], x[14]); + QROUND(x[3], x[7], x[11], x[15]); + + DEBUG (i+1); + QROUND(x[0], x[5], x[10], x[15]); + QROUND(x[1], x[6], x[11], x[12]); + QROUND(x[2], x[7], x[8], x[13]); + QROUND(x[3], x[4], x[9], x[14]); + } + DEBUG (i); + + for (i = 0; i < _CHACHA_STATE_LENGTH; i++) + { + uint32_t t = x[i] + src[i]; + dst[i] = LE_SWAP32 (t); + } +} + + + + + + + diff --git a/chacha-crypt.c b/chacha-crypt.c new file mode 100644 index 00000000..2fb77777 --- /dev/null +++ b/chacha-crypt.c @@ -0,0 +1,78 @@ +/* chacha-crypt.c + * + * The crypt function in the ChaCha stream cipher. + * Heavily based on the Salsa20 implementation in Nettle. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2014 Niels Möller + * Copyright (C) 2013 Joachim Strömbergson + * Copyright (C) 2012 Simon Josefsson + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02111-1301, USA. + */ + +/* Based on: + chacha-ref.c version 2008.01.20. + D. J. Bernstein + Public domain. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <string.h> + +#include "chacha.h" + +#include "macros.h" +#include "memxor.h" + +#define CHACHA_ROUNDS 20 + +void +chacha_crypt(struct chacha_ctx *ctx, + size_t length, + uint8_t *c, + const uint8_t *m) +{ + if (!length) + return; + + for (;;) + { + uint32_t x[_CHACHA_STATE_LENGTH]; + + _chacha_core (x, ctx->state, CHACHA_ROUNDS); + + ctx->state[9] += (++ctx->state[8] == 0); + + /* stopping at 2^70 length per nonce is user's responsibility */ + + if (length <= CHACHA_BLOCK_SIZE) + { + memxor3 (c, m, x, length); + return; + } + memxor3 (c, m, x, CHACHA_BLOCK_SIZE); + + length -= CHACHA_BLOCK_SIZE; + c += CHACHA_BLOCK_SIZE; + m += CHACHA_BLOCK_SIZE; + } +} diff --git a/chacha-set-iv.c b/chacha-set-iv.c new file mode 100644 index 00000000..ab872bbe --- /dev/null +++ b/chacha-set-iv.c @@ -0,0 +1,53 @@ +/* chacha-set-iv.c + * + * Setting the IV the ChaCha stream cipher. + * Based on the Salsa20 implementation in Nettle. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2013 Joachim Strömbergon + * Copyright (C) 2012 Simon Josefsson + * Copyright (C) 2012, 2014 Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02111-1301, USA. + */ + +/* Based on: + ChaCha specification (doc id: 4027b5256e17b9796842e6d0f68b0b5e) and reference + implementation dated 2008.01.20 + D. J. Bernstein + Public domain. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <assert.h> + +#include "chacha.h" + +#include "macros.h" + +void +chacha_set_iv(struct chacha_ctx *ctx, const uint8_t *iv) +{ + ctx->state[12] = 0; + ctx->state[13] = 0; + ctx->state[14] = LE_READ_UINT32(iv + 0); + ctx->state[15] = LE_READ_UINT32(iv + 4); +} diff --git a/chacha-set-key.c b/chacha-set-key.c new file mode 100644 index 00000000..18c6109e --- /dev/null +++ b/chacha-set-key.c @@ -0,0 +1,43 @@ +/* chacha-set-key.c + * + * Copyright (C) 2014 Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02111-1301, USA. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdlib.h> + +#include "chacha.h" + +void +chacha_set_key(struct chacha_ctx *ctx, size_t length, const uint8_t *key) +{ + switch (length) + { + default: + abort (); + case CHACHA128_KEY_SIZE: + chacha128_set_key (ctx, key); + break; + case CHACHA256_KEY_SIZE: + chacha256_set_key (ctx, key); + break; + } +} diff --git a/chacha.h b/chacha.h new file mode 100644 index 00000000..c8ec92b0 --- /dev/null +++ b/chacha.h @@ -0,0 +1,97 @@ +/* chacha.h + * + * The ChaCha stream cipher. + * Heavily based on the Salsa20 source code in Nettle. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2013 Joachim Strömbergson + * Copyright (C) 2012 Simon Josefsson + * Copyright (C) 2014 Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02111-1301, USA. + */ + +#ifndef NETTLE_CHACHA_H_INCLUDED +#define NETTLE_CHACHA_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define chacha_set_key nettle_chacha_set_key +#define chacha128_set_key nettle_chacha128_set_key +#define chacha256_set_key nettle_chacha256_set_key +#define chacha_set_iv nettle_chacha_set_iv +#define chacha_crypt nettle_chacha_crypt +#define _chacha_core _nettle_chacha_core + +/* Possible keysizes, and a reasonable default. In octets. */ +#define CHACHA128_KEY_SIZE 16 +#define CHACHA256_KEY_SIZE 32 +#define CHACHA_KEY_SIZE 32 + +#define CHACHA_BLOCK_SIZE 64 + +#define CHACHA_IV_SIZE 8 + +#define _CHACHA_STATE_LENGTH 16 + +struct chacha_ctx +{ + /* Indices 0-3 holds a constant (SIGMA or TAU). + Indices 4-11 holds the key. + Indices 12-13 holds the block counter. + Indices 14-15 holds the IV: + + This creates the state matrix: + C C C C + K K K K + K K K K + B B I I + */ + uint32_t state[_CHACHA_STATE_LENGTH]; +}; + +void +chacha128_set_key(struct chacha_ctx *ctx, const uint8_t *key); + +void +chacha256_set_key(struct chacha_ctx *ctx, const uint8_t *key); + +void +chacha_set_key(struct chacha_ctx *ctx, + size_t length, const uint8_t *key); + +void +chacha_set_iv(struct chacha_ctx *ctx, const uint8_t *iv); + +void +chacha_crypt(struct chacha_ctx *ctx, size_t length, + uint8_t *dst, const uint8_t *src); + +void +_chacha_core(uint32_t *dst, const uint32_t *src, unsigned rounds); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_CHACHA_H_INCLUDED */ diff --git a/chacha128-set-key.c b/chacha128-set-key.c new file mode 100644 index 00000000..569e801c --- /dev/null +++ b/chacha128-set-key.c @@ -0,0 +1,61 @@ +/* chacha128-set-key.c + * + * ChaCha key setup for 128-bit keys. + * Based on the Salsa20 implementation in Nettle. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2013 Joachim Strömbergon + * Copyright (C) 2012 Simon Josefsson + * Copyright (C) 2012, 2014 Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02111-1301, USA. + */ + +/* Based on: + ChaCha specification (doc id: 4027b5256e17b9796842e6d0f68b0b5e) and reference + implementation dated 2008.01.20 + D. J. Bernstein + Public domain. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <assert.h> +#include <string.h> + +#include "chacha.h" + +#include "macros.h" + +void +chacha128_set_key(struct chacha_ctx *ctx, const uint8_t *key) +{ + static const uint32_t tau[4] = { + /* "expand 16-byte k" */ + 0x61707865, 0x3120646e, 0x79622d36, 0x6b206574 + }; + + ctx->state[8] = ctx->state[4] = LE_READ_UINT32(key + 0); + ctx->state[9] = ctx->state[5] = LE_READ_UINT32(key + 4); + ctx->state[10] = ctx->state[6] = LE_READ_UINT32(key + 8); + ctx->state[11] = ctx->state[7] = LE_READ_UINT32(key + 12); + + memcpy (ctx->state, tau, sizeof(tau)); +} diff --git a/chacha256-set-key.c b/chacha256-set-key.c new file mode 100644 index 00000000..66e314b0 --- /dev/null +++ b/chacha256-set-key.c @@ -0,0 +1,65 @@ +/* chacha256-set-key.c + * + * ChaCha key setup for 256-bit keys. + * Based on the Salsa20 implementation in Nettle. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2013 Joachim Strömbergon + * Copyright (C) 2012 Simon Josefsson + * Copyright (C) 2012, 2014 Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02111-1301, USA. + */ + +/* Based on: + ChaCha specification (doc id: 4027b5256e17b9796842e6d0f68b0b5e) and reference + implementation dated 2008.01.20 + D. J. Bernstein + Public domain. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <assert.h> +#include <string.h> + +#include "chacha.h" + +#include "macros.h" + +void +chacha256_set_key(struct chacha_ctx *ctx, const uint8_t *key) +{ + static const uint32_t sigma[4] = { + /* "expand 32-byte k" */ + 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 + }; + ctx->state[4] = LE_READ_UINT32(key + 0); + ctx->state[5] = LE_READ_UINT32(key + 4); + ctx->state[6] = LE_READ_UINT32(key + 8); + ctx->state[7] = LE_READ_UINT32(key + 12); + + ctx->state[8] = LE_READ_UINT32(key + 16); + ctx->state[9] = LE_READ_UINT32(key + 20); + ctx->state[10] = LE_READ_UINT32(key + 24); + ctx->state[11] = LE_READ_UINT32(key + 28); + + memcpy (ctx->state, sigma, sizeof(sigma)); +} diff --git a/testsuite/.test-rules.make b/testsuite/.test-rules.make index 2900468b..ccd8e5a9 100644 --- a/testsuite/.test-rules.make +++ b/testsuite/.test-rules.make @@ -22,6 +22,9 @@ base64-test$(EXEEXT): base64-test.$(OBJEXT) camellia-test$(EXEEXT): camellia-test.$(OBJEXT) $(LINK) camellia-test.$(OBJEXT) $(TEST_OBJS) -o camellia-test$(EXEEXT) +chacha-test$(EXEEXT): chacha-test.$(OBJEXT) + $(LINK) chacha-test.$(OBJEXT) $(TEST_OBJS) -o chacha-test$(EXEEXT) + des-test$(EXEEXT): des-test.$(OBJEXT) $(LINK) des-test.$(OBJEXT) $(TEST_OBJS) -o des-test$(EXEEXT) diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in index ea85ef95..8860ba5c 100644 --- a/testsuite/Makefile.in +++ b/testsuite/Makefile.in @@ -13,7 +13,7 @@ PRE_LDFLAGS = -L.. TS_NETTLE_SOURCES = aes-test.c arcfour-test.c arctwo-test.c \ blowfish-test.c cast128-test.c \ base16-test.c base64-test.c \ - camellia-test.c \ + camellia-test.c chacha-test.c \ des-test.c des3-test.c des-compat-test.c \ md2-test.c md4-test.c md5-test.c md5-compat-test.c \ memxor-test.c gosthash94-test.c \ diff --git a/testsuite/chacha-test.c b/testsuite/chacha-test.c new file mode 100644 index 00000000..e8732fa7 --- /dev/null +++ b/testsuite/chacha-test.c @@ -0,0 +1,344 @@ +/* chacha-test.c + * + * Test program for the ChaCha stream cipher implementation. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2013 Joachim Strömbergson + * Copyright (C) 2012, 2014 Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02111-1301, USA. + */ + +#include "testutils.h" + +#include "chacha.h" + +static void +test_chacha(const struct tstring *key, const struct tstring *iv, + const struct tstring *expected, unsigned rounds) +{ + /* Uses the _chacha_core function to be able to test different + numbers of rounds. */ + /* FIXME: For rounds == 20, use crypt function, support more than + one block, and test various short lengths. */ + uint32_t out[_CHACHA_STATE_LENGTH]; + + struct chacha_ctx ctx; + + ASSERT (expected->length == CHACHA_BLOCK_SIZE); + + chacha_set_key (&ctx, key->length, key->data); + ASSERT (iv->length == CHACHA_IV_SIZE); + chacha_set_iv(&ctx, iv->data); + + _chacha_core (out, ctx.state, rounds); + + if (!MEMEQ(CHACHA_BLOCK_SIZE, out, expected->data)) + { + printf("Error, expected:\n"); + tstring_print_hex (expected); + printf("Got:\n"); + print_hex(CHACHA_BLOCK_SIZE, (uint8_t *) out); + FAIL (); + } + + if (verbose) + { + printf("Result after encryption:\n"); + print_hex(CHACHA_BLOCK_SIZE, (uint8_t *) out); + } +} + +void +test_main(void) +{ + /* Test vectors from draft-strombergson-chacha-test-vectors */ + + /* TC1: All zero key and IV. 128 bit key and 8 rounds. */ + test_chacha (SHEX("0000000000000000 0000000000000000"), + SHEX("0000000000000000"), + SHEX("e28a5fa4a67f8c5d efed3e6fb7303486" + "aa8427d31419a729 572d777953491120" + "b64ab8e72b8deb85 cd6aea7cb6089a10" + "1824beeb08814a42 8aab1fa2c816081b"), + 8); + test_chacha (SHEX("0000000000000000 0000000000000000"), + SHEX("0000000000000000"), + SHEX("e1047ba9476bf8ff 312c01b4345a7d8c" + "a5792b0ad467313f 1dc412b5fdce3241" + "0dea8b68bd774c36 a920f092a04d3f95" + "274fbeff97bc8491 fcef37f85970b450"), + 12); + + test_chacha (SHEX("0000000000000000 0000000000000000"), + SHEX("0000000000000000"), + SHEX("89670952608364fd 00b2f90936f031c8" + "e756e15dba04b849 3d00429259b20f46" + "cc04f111246b6c2c e066be3bfb32d9aa" + "0fddfbc12123d4b9 e44f34dca05a103f"), + 20); + + test_chacha (SHEX("0000000000000000 0000000000000000" + "0000000000000000 0000000000000000"), + SHEX("0000000000000000"), + SHEX("76b8e0ada0f13d90 405d6ae55386bd28" + "bdd219b8a08ded1a a836efcc8b770dc7" + "da41597c5157488d 7724e03fb8d84a37" + "6a43b8f41518a11c c387b669b2ee6586"), + 20); + + + /* TC2: Single bit in key set. All zero IV */ + test_chacha (SHEX("0100000000000000 0000000000000000"), + SHEX("0000000000000000"), + SHEX("03a7669888605a07 65e8357475e58673" + "f94fc8161da76c2a 3aa2f3caf9fe5449" + "e0fcf38eb882656a f83d430d410927d5" + "5c972ac4c92ab9da 3713e19f761eaa14"), + 8); + + test_chacha (SHEX("0100000000000000 0000000000000000"), + SHEX("0000000000000000"), + SHEX("2a865a3b8999fa83 ae8aacf33fc6be4f" + "32c8aa9762738d26 963270052f4eef8b" + "86af758f7867560a f6d0eeb973b5542b" + "b24c8abceac8b1f3 6d026963d6c8a9b2"), + 12); + + test_chacha (SHEX("0100000000000000 0000000000000000"), + SHEX("0000000000000000"), + SHEX("ae56060d04f5b597 897ff2af1388dbce" + "ff5a2a4920335dc1 7a3cb1b1b10fbe70" + "ece8f4864d8c7cdf 0076453a8291c7db" + "eb3aa9c9d10e8ca3 6be4449376ed7c42"), + 20); + + test_chacha (SHEX("0100000000000000 0000000000000000" + "0000000000000000 0000000000000000"), + SHEX("0000000000000000"), + SHEX("c5d30a7ce1ec1193 78c84f487d775a85" + "42f13ece238a9455 e8229e888de85bbd" + "29eb63d0a17a5b99 9b52da22be4023eb" + "07620a54f6fa6ad8 737b71eb0464dac0"), + 20); + + /* TC3: Single bit in IV set. All zero key */ + test_chacha (SHEX("0000000000000000 0000000000000000"), + SHEX("0100000000000000"), + SHEX("25f5bec6683916ff 44bccd12d102e692" + "176663f4cac53e71 9509ca74b6b2eec8" + "5da4236fb2990201 2adc8f0d86c8187d" + "25cd1c486966930d 0204c4ee88a6ab35"), + 8); + + test_chacha (SHEX("0000000000000000 0000000000000000"), + SHEX("0100000000000000"), + SHEX("91cdb2f180bc89cf e86b8b6871cd6b3a" + "f61abf6eba01635d b619c40a0b2e19ed" + "fa8ce5a9bd7f53cc 2c9bcfea181e9754" + "a9e245731f658cc2 82c2ae1cab1ae02c"), + 12); + + test_chacha (SHEX("0000000000000000 0000000000000000"), + SHEX("0100000000000000"), + SHEX("1663879eb3f2c994 9e2388caa343d361" + "bb132771245ae6d0 27ca9cb010dc1fa7" + "178dc41f8278bc1f 64b3f12769a24097" + "f40d63a86366bdb3 6ac08abe60c07fe8"), + 20); + + test_chacha (SHEX("0000000000000000 0000000000000000" + "0000000000000000 0000000000000000"), + SHEX("0100000000000000"), + SHEX("ef3fdfd6c61578fb f5cf35bd3dd33b80" + "09631634d21e42ac 33960bd138e50d32" + "111e4caf237ee53c a8ad6426194a8854" + "5ddc497a0b466e7d 6bbdb0041b2f586b"), + 20); + + /* TC4: All bits in key and IV are set. */ + test_chacha (SHEX("ffffffffffffffff ffffffffffffffff"), + SHEX("ffffffffffffffff"), + SHEX("2204d5b81ce66219 3e00966034f91302" + "f14a3fb047f58b6e 6ef0d72113230416" + "3e0fb640d76ff9c3 b9cd99996e6e38fa" + "d13f0e31c82244d3 3abbc1b11e8bf12d"), + 8); + + test_chacha (SHEX("ffffffffffffffff ffffffffffffffff"), + SHEX("ffffffffffffffff"), + SHEX("60e349e60c38b328 c4baab90d44a7c72" + "7662770d36350d65 a1433bd92b00ecf4" + "83d5597d7a616258 ec3c5d5b30e1c5c8" + "5c5dfe2f92423b8e 36870f3185b6add9"), + 12); + + test_chacha (SHEX("ffffffffffffffff ffffffffffffffff"), + SHEX("ffffffffffffffff"), + SHEX("992947c3966126a0 e660a3e95db048de" + "091fb9e0185b1e41 e41015bb7ee50150" + "399e4760b262f9d5 3f26d8dd19e56f5c" + "506ae0c3619fa67f b0c408106d0203ee"), + 20); + + test_chacha (SHEX("ffffffffffffffff ffffffffffffffff" + "ffffffffffffffff ffffffffffffffff"), + SHEX("ffffffffffffffff"), + SHEX("d9bf3f6bce6ed0b5 4254557767fb5744" + "3dd4778911b60605 5c39cc25e674b836" + "3feabc57fde54f79 0c52c8ae43240b79" + "d49042b777bfd6cb 80e931270b7f50eb"), + 20); + + /* TC5: Every even bit set in key and IV. */ + test_chacha (SHEX("5555555555555555 5555555555555555"), + SHEX("5555555555555555"), + SHEX("f0a23bc36270e18e d0691dc384374b9b" + "2c5cb60110a03f56 fa48a9fbbad961aa" + "6bab4d892e96261b 6f1a0919514ae56f" + "86e066e17c71a417 6ac684af1c931996"), + 8); + + test_chacha (SHEX("5555555555555555 5555555555555555"), + SHEX("5555555555555555"), + SHEX("90ec7a49ee0b20a8 08af3d463c1fac6c" + "2a7c897ce8f6e60d 793b62ddbebcf980" + "ac917f091e52952d b063b1d2b947de04" + "aac087190ca99a35 b5ea501eb535d570"), + 12); + + test_chacha (SHEX("5555555555555555 5555555555555555"), + SHEX("5555555555555555"), + SHEX("357d7d94f966778f 5815a2051dcb0413" + "3b26b0ead9f57dd0 9927837bc3067e4b" + "6bf299ad81f7f50c 8da83c7810bfc17b" + "b6f4813ab6c32695 7045fd3fd5e19915" + ), + 20); + + test_chacha (SHEX("5555555555555555 5555555555555555" + "5555555555555555 5555555555555555"), + SHEX("5555555555555555"), + SHEX("bea9411aa453c543 4a5ae8c92862f564" + "396855a9ea6e22d6 d3b50ae1b3663311" + "a4a3606c671d605c e16c3aece8e61ea1" + "45c59775017bee2f a6f88afc758069f7"), + 20); + + /* TC6: Every odd bit set in key and IV. */ + test_chacha (SHEX("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"), + SHEX("aaaaaaaaaaaaaaaa"), + SHEX("312d95c0bc38eff4 942db2d50bdc500a" + "30641ef7132db1a8 ae838b3bea3a7ab0" + "3815d7a4cc09dbf5 882a3433d743aced" + "48136ebab7329950 6855c0f5437a36c6"), + 8); + + test_chacha (SHEX("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"), + SHEX("aaaaaaaaaaaaaaaa"), + SHEX("057fe84fead13c24 b76bb2a6fdde66f2" + "688e8eb6268275c2 2c6bcb90b85616d7" + "fe4d3193a1036b70 d7fb864f01453641" + "851029ecdb60ac38 79f56496f16213f4"), + 12); + + test_chacha (SHEX("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"), + SHEX("aaaaaaaaaaaaaaaa"), + SHEX("fc79acbd58526103 862776aab20f3b7d" + "8d3149b2fab65766 299316b6e5b16684" + "de5de548c1b7d083 efd9e3052319e0c6" + "254141da04a6586d f800f64d46b01c87"), + 20); + + test_chacha (SHEX("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"), + SHEX("aaaaaaaaaaaaaaaa"), + SHEX("9aa2a9f656efde5a a7591c5fed4b35ae" + "a2895dec7cb4543b 9e9f21f5e7bcbcf3" + "c43c748a970888f8 248393a09d43e0b7" + "e164bc4d0b0fb240 a2d72115c4808906"), + 20); + + /* TC7: Sequence patterns in key and IV. */ + test_chacha (SHEX("0011223344556677 8899aabbccddeeff"), + SHEX("0f1e2d3c4b5a6978"), + SHEX("29560d280b452840 0a8f4b795369fb3a" + "01105599e9f1ed58 279cfc9ece2dc5f9" + "9f1c2e52c98238f5 42a5c0a881d850b6" + "15d3acd9fbdb026e 9368565da50e0d49"), + 8); + + test_chacha (SHEX("0011223344556677 8899aabbccddeeff"), + SHEX("0f1e2d3c4b5a6978"), + SHEX("5eddc2d9428fceee c50a52a964eae0ff" + "b04b2de006a9b04c ff368ffa921116b2" + "e8e264babd2efa0d e43ef2e3b6d065e8" + "f7c0a17837b0a40e b0e2c7a3742c8753"), + 12); + + test_chacha (SHEX("0011223344556677 8899aabbccddeeff"), + SHEX("0f1e2d3c4b5a6978"), + SHEX("d1abf630467eb4f6 7f1cfb47cd626aae" + "8afedbbe4ff8fc5f e9cfae307e74ed45" + "1f1404425ad2b545 69d5f18148939971" + "abb8fafc88ce4ac7 fe1c3d1f7a1eb7ca"), + 20); + + test_chacha (SHEX("0011223344556677 8899aabbccddeeff" + "ffeeddccbbaa9988 7766554433221100"), + SHEX("0f1e2d3c4b5a6978"), + SHEX("db43ad9d1e842d12 72e4530e276b3f56" + "8f8859b3f7cf6d9d 2c74fa53808cb515" + "7a8ebf46ad3dcc4b 6c7dadde131784b0" + "120e0e22f6d5f9ff a7407d4a21b695d9"), + 8); + + /* TC8: hashed string patterns */ + test_chacha(SHEX("c46ec1b18ce8a878 725a37e780dfb735"), + SHEX("1ada31d5cf688221"), + SHEX("6a870108859f6791 18f3e205e2a56a68" + "26ef5a60a4102ac8 d4770059fcb7c7ba" + "e02f5ce004a6bfbb ea53014dd82107c0" + "aa1c7ce11b7d78f2 d50bd3602bbd2594"), + 8); + + test_chacha(SHEX("c46ec1b18ce8a878 725a37e780dfb735"), + SHEX("1ada31d5cf688221"), + SHEX("b02bd81eb55c8f68 b5e9ca4e307079bc" + "225bd22007eddc67 02801820709ce098" + "07046a0d2aa552bf dbb49466176d56e3" + "2d519e10f5ad5f27 46e241e09bdf9959"), + 12); + + test_chacha(SHEX("c46ec1b18ce8a878 725a37e780dfb735"), + SHEX("1ada31d5cf688221"), + SHEX("826abdd84460e2e9 349f0ef4af5b179b" + "426e4b2d109a9c5b b44000ae51bea90a" + "496beeef62a76850 ff3f0402c4ddc99f" + "6db07f151c1c0dfa c2e56565d6289625"), + 20); + + test_chacha(SHEX("c46ec1b18ce8a878 725a37e780dfb735" + "1f68ed2e194c79fb c6aebee1a667975d"), + SHEX("1ada31d5cf688221"), + SHEX("f63a89b75c2271f9 368816542ba52f06" + "ed49241792302b00 b5e8f80ae9a473af" + "c25b218f519af0fd d406362e8d69de7f" + "54c604a6e00f353f 110f771bdca8ab92"), + 20); +} |