1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2022-2024 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. 4 */ 5 6 #include <sodium/crypto_stream_chacha20.h> 7 #include <sys/random.h> 8 #include <string.h> 9 #include <stdint.h> 10 #include "../kselftest.h" 11 12 extern void __arch_chacha20_blocks_nostack(uint8_t *dst_bytes, const uint8_t *key, uint32_t *counter, size_t nblocks); 13 14 int main(int argc, char *argv[]) 15 { 16 enum { TRIALS = 1000, BLOCKS = 128, BLOCK_SIZE = 64 }; 17 static const uint8_t nonce[8] = { 0 }; 18 uint32_t counter[2]; 19 uint8_t key[32]; 20 uint8_t output1[BLOCK_SIZE * BLOCKS], output2[BLOCK_SIZE * BLOCKS]; 21 22 ksft_print_header(); 23 ksft_set_plan(1); 24 25 for (unsigned int trial = 0; trial < TRIALS; ++trial) { 26 if (getrandom(key, sizeof(key), 0) != sizeof(key)) { 27 printf("getrandom() failed!\n"); 28 return KSFT_SKIP; 29 } 30 crypto_stream_chacha20(output1, sizeof(output1), nonce, key); 31 for (unsigned int split = 0; split < BLOCKS; ++split) { 32 memset(output2, 'X', sizeof(output2)); 33 memset(counter, 0, sizeof(counter)); 34 if (split) 35 __arch_chacha20_blocks_nostack(output2, key, counter, split); 36 __arch_chacha20_blocks_nostack(output2 + split * BLOCK_SIZE, key, counter, BLOCKS - split); 37 if (memcmp(output1, output2, sizeof(output1))) 38 return KSFT_FAIL; 39 } 40 } 41 ksft_test_result_pass("chacha: PASS\n"); 42 return KSFT_PASS; 43 } 44