mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
2cf4253710
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.
143 lines
5.1 KiB
C
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;
|
|
}
|