// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2022-2024 Jason A. Donenfeld <[email protected]>. All Rights Reserved.
*/
#include <sodium/crypto_stream_chacha20.h>
#include <sys/random.h>
#include <string.h>
#include <stdint.h>
#include "../kselftest.h"
extern void __arch_chacha20_blocks_nostack(uint8_t *dst_bytes, const uint8_t *key, uint32_t *counter, size_t nblocks);
int main(int argc, char *argv[])
{
enum { TRIALS = 1000, BLOCKS = 128, BLOCK_SIZE = 64 };
static const uint8_t nonce[8] = { 0 };
uint32_t counter[2];
uint8_t key[32];
uint8_t output1[BLOCK_SIZE * BLOCKS], output2[BLOCK_SIZE * BLOCKS];
ksft_print_header();
ksft_set_plan(1);
for (unsigned int trial = 0; trial < TRIALS; ++trial) {
if (getrandom(key, sizeof(key), 0) != sizeof(key)) {
printf("getrandom() failed!\n");
return KSFT_SKIP;
}
crypto_stream_chacha20(output1, sizeof(output1), nonce, key);
for (unsigned int split = 0; split < BLOCKS; ++split) {
memset(output2, 'X', sizeof(output2));
memset(counter, 0, sizeof(counter));
if (split)
__arch_chacha20_blocks_nostack(output2, key, counter, split);
__arch_chacha20_blocks_nostack(output2 + split * BLOCK_SIZE, key, counter, BLOCKS - split);
if (memcmp(output1, output2, sizeof(output1)))
return KSFT_FAIL;
}
}
ksft_test_result_pass("chacha: PASS\n");
return KSFT_PASS;
}