1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/tests/unittests/tests-crypto/tests-crypto-chacha.c
René Kijewski 2cf4253710 sys: add ChaCha stream cipher and PRNG
This implementation is optimized for a little code and data size, not
for speed. IMO the code is more readable than in the reference
implementation.

The biggest advantage of ChaCha over other stream ciphers is the very
little data usage with only 64 bytes of context, and its good encryption
speed.

Also part of this PR is pseudo-random number generator, that just
returns the keystream of a randomly initialized ChaCha context.
2015-06-28 18:32:04 +02:00

143 lines
5.1 KiB
C

/*
* Copyright (C) 2015 René Kijewski <rene.kijewski@fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
#include "embUnit/embUnit.h"
#include "tests-crypto.h"
#include "crypto/chacha.h"
#include <string.h>
static const uint8_t TC8_KEY[32] = {
0xc4, 0x6e, 0xc1, 0xb1, 0x8c, 0xe8, 0xa8, 0x78,
0x72, 0x5a, 0x37, 0xe7, 0x80, 0xdf, 0xb7, 0x35,
};
static const uint8_t TC8_IV[8] = {
0x1a, 0xda, 0x31, 0xd5, 0xcf, 0x68, 0x82, 0x21,
};
static const uint32_t TC8_AFTER_INIT[16] = {
0x61707865, 0x3120646e, 0x79622d36, 0x6b206574,
0xb1c16ec4, 0x78a8e88c, 0xe7375a72, 0x35b7df80,
0xb1c16ec4, 0x78a8e88c, 0xe7375a72, 0x35b7df80,
0x00000000, 0x00000000, 0xd531da1a, 0x218268cf,
};
static const uint8_t TC8_CHACHA8_BLOCK0[64] = {
0x6a, 0x87, 0x01, 0x08, 0x85, 0x9f, 0x67, 0x91,
0x18, 0xf3, 0xe2, 0x05, 0xe2, 0xa5, 0x6a, 0x68,
0x26, 0xef, 0x5a, 0x60, 0xa4, 0x10, 0x2a, 0xc8,
0xd4, 0x77, 0x00, 0x59, 0xfc, 0xb7, 0xc7, 0xba,
0xe0, 0x2f, 0x5c, 0xe0, 0x04, 0xa6, 0xbf, 0xbb,
0xea, 0x53, 0x01, 0x4d, 0xd8, 0x21, 0x07, 0xc0,
0xaa, 0x1c, 0x7c, 0xe1, 0x1b, 0x7d, 0x78, 0xf2,
0xd5, 0x0b, 0xd3, 0x60, 0x2b, 0xbd, 0x25, 0x94,
};
static const uint8_t TC8_CHACHA8_BLOCK1[64] = {
0x05, 0x60, 0xbb, 0x6a, 0x84, 0x28, 0x9e, 0x0b,
0x38, 0xf5, 0xdd, 0x21, 0xd6, 0xef, 0x6d, 0x77,
0x37, 0xe3, 0xec, 0x0f, 0xb7, 0x72, 0xda, 0x2c,
0x71, 0xc2, 0x39, 0x77, 0x62, 0xe5, 0xdb, 0xbb,
0xf4, 0x49, 0xe3, 0xd1, 0x63, 0x9c, 0xcb, 0xfa,
0x3e, 0x06, 0x9c, 0x4d, 0x87, 0x1e, 0xd6, 0x39,
0x5b, 0x22, 0xaa, 0xf3, 0x5c, 0x8d, 0xa6, 0xde,
0x2d, 0xec, 0x3d, 0x77, 0x88, 0x0d, 0xa8, 0xe8,
};
static const uint8_t TC8_CHACHA12_BLOCK0[64] = {
0xb0, 0x2b, 0xd8, 0x1e, 0xb5, 0x5c, 0x8f, 0x68,
0xb5, 0xe9, 0xca, 0x4e, 0x30, 0x70, 0x79, 0xbc,
0x22, 0x5b, 0xd2, 0x20, 0x07, 0xed, 0xdc, 0x67,
0x02, 0x80, 0x18, 0x20, 0x70, 0x9c, 0xe0, 0x98,
0x07, 0x04, 0x6a, 0x0d, 0x2a, 0xa5, 0x52, 0xbf,
0xdb, 0xb4, 0x94, 0x66, 0x17, 0x6d, 0x56, 0xe3,
0x2d, 0x51, 0x9e, 0x10, 0xf5, 0xad, 0x5f, 0x27,
0x46, 0xe2, 0x41, 0xe0, 0x9b, 0xdf, 0x99, 0x59,
};
static const uint8_t TC8_CHACHA12_BLOCK1[64] = {
0x17, 0xbe, 0x08, 0x73, 0xed, 0xde, 0x9a, 0xf5,
0xb8, 0x62, 0x46, 0x44, 0x1c, 0xe4, 0x10, 0x19,
0x5b, 0xae, 0xde, 0x41, 0xf8, 0xbd, 0xab, 0x6a,
0xd2, 0x53, 0x22, 0x63, 0x82, 0xee, 0x38, 0x3e,
0x34, 0x72, 0xf9, 0x45, 0xa5, 0xe6, 0xbd, 0x62,
0x8c, 0x7a, 0x58, 0x2b, 0xcf, 0x8f, 0x89, 0x98,
0x70, 0x59, 0x6a, 0x58, 0xda, 0xb8, 0x3b, 0x51,
0xa5, 0x0c, 0x7d, 0xbb, 0x4f, 0x3e, 0x6e, 0x76,
};
static const uint8_t TC8_CHACHA20_BLOCK0[64] = {
0x82, 0x6a, 0xbd, 0xd8, 0x44, 0x60, 0xe2, 0xe9,
0x34, 0x9f, 0x0e, 0xf4, 0xaf, 0x5b, 0x17, 0x9b,
0x42, 0x6e, 0x4b, 0x2d, 0x10, 0x9a, 0x9c, 0x5b,
0xb4, 0x40, 0x00, 0xae, 0x51, 0xbe, 0xa9, 0x0a,
0x49, 0x6b, 0xee, 0xef, 0x62, 0xa7, 0x68, 0x50,
0xff, 0x3f, 0x04, 0x02, 0xc4, 0xdd, 0xc9, 0x9f,
0x6d, 0xb0, 0x7f, 0x15, 0x1c, 0x1c, 0x0d, 0xfa,
0xc2, 0xe5, 0x65, 0x65, 0xd6, 0x28, 0x96, 0x25,
};
static const uint8_t TC8_CHACHA20_BLOCK1[64] = {
0x5b, 0x23, 0x13, 0x2e, 0x7b, 0x46, 0x9c, 0x7b,
0xfb, 0x88, 0xfa, 0x95, 0xd4, 0x4c, 0xa5, 0xae,
0x3e, 0x45, 0xe8, 0x48, 0xa4, 0x10, 0x8e, 0x98,
0xba, 0xd7, 0xa9, 0xeb, 0x15, 0x51, 0x27, 0x84,
0xa6, 0xa9, 0xe6, 0xe5, 0x91, 0xdc, 0xe6, 0x74,
0x12, 0x0a, 0xca, 0xf9, 0x04, 0x0f, 0xf5, 0x0f,
0xf3, 0xac, 0x30, 0xcc, 0xfb, 0x5e, 0x14, 0x20,
0x4f, 0x5e, 0x42, 0x68, 0xb9, 0x0a, 0x88, 0x04,
};
static void _test_crypto_chacha(unsigned rounds, unsigned keylen,
const uint8_t key[32], const uint8_t iv[8],
const uint32_t after_init[16],
const uint8_t block0[64], const uint8_t block1[64])
{
chacha_ctx ctx;
uint8_t block[64];
TEST_ASSERT_EQUAL_INT(0, chacha_init(&ctx, rounds, key, keylen, iv));
TEST_ASSERT_EQUAL_INT(0, memcmp(ctx.state, after_init, 64));
chacha_keystream_bytes(&ctx, block);
TEST_ASSERT_EQUAL_INT(0, memcmp(block, block0, 64));
chacha_keystream_bytes(&ctx, block);
TEST_ASSERT_EQUAL_INT(0, memcmp(block, block1, 64));
}
static void test_crypto_chacha8_tc8(void)
{
_test_crypto_chacha(8, 16, TC8_KEY, TC8_IV, TC8_AFTER_INIT,
TC8_CHACHA8_BLOCK0, TC8_CHACHA8_BLOCK1);
}
static void test_crypto_chacha12_tc8(void)
{
_test_crypto_chacha(12, 16, TC8_KEY, TC8_IV, TC8_AFTER_INIT,
TC8_CHACHA12_BLOCK0, TC8_CHACHA12_BLOCK1);
}
static void test_crypto_chacha20_tc8(void)
{
_test_crypto_chacha(20, 16, TC8_KEY, TC8_IV, TC8_AFTER_INIT,
TC8_CHACHA20_BLOCK0, TC8_CHACHA20_BLOCK1);
}
Test *tests_crypto_chacha_tests(void)
{
EMB_UNIT_TESTFIXTURES(fixtures) {
new_TestFixture(test_crypto_chacha8_tc8),
new_TestFixture(test_crypto_chacha12_tc8),
new_TestFixture(test_crypto_chacha20_tc8),
};
EMB_UNIT_TESTCALLER(crypto_chacha_tests, NULL, NULL, fixtures);
return (Test *) &crypto_chacha_tests;
}