Skip to content

Commit bb10ffe

Browse files
chleroyzx2c4
authored andcommitted
selftests: vDSO: also test counter in vdso_test_chacha
The chacha vDSO selftest doesn't check the way the counter is handled by __arch_chacha20_blocks_nostack(). It indirectly checks that the counter is writen on exit and read back on new entry, but it doesn't check that the format is correct. When implementing this function on powerpc, I missed a case where the counter was writen and read in wrong byte order. Also, the counter uses two words, but the tests with a zero counter and uses a small amount of blocks, so at the end the upper part of the counter is always 0, so it is not checked. Add a verification of counter's content in addition to the verification of the output. Also add two tests where the counter crosses the u32 upper limit. The first test verifies that the function properly writes back the upper word, the second test verifies that the function properly reads back the upper word. Signed-off-by: Christophe Leroy <[email protected]> Signed-off-by: Jason A. Donenfeld <[email protected]>
1 parent ecb8bd7 commit bb10ffe

File tree

1 file changed

+27
-9
lines changed

1 file changed

+27
-9
lines changed

tools/testing/selftests/vDSO/vdso_test_chacha.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ static uint32_t rol32(uint32_t word, unsigned int shift)
1515
return (word << (shift & 31)) | (word >> ((-shift) & 31));
1616
}
1717

18-
static void reference_chacha20_blocks(uint8_t *dst_bytes, const uint32_t *key, size_t nblocks)
18+
static void reference_chacha20_blocks(uint8_t *dst_bytes, const uint32_t *key, uint32_t *counter, size_t nblocks)
1919
{
2020
uint32_t s[16] = {
2121
0x61707865U, 0x3320646eU, 0x79622d32U, 0x6b206574U,
22-
key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7]
22+
key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7],
23+
counter[0], counter[1], 0, 0
2324
};
2425

2526
while (nblocks--) {
@@ -50,6 +51,8 @@ static void reference_chacha20_blocks(uint8_t *dst_bytes, const uint32_t *key, s
5051
if (!++s[12])
5152
++s[13];
5253
}
54+
counter[0] = s[12];
55+
counter[1] = s[13];
5356
}
5457

5558
typedef uint8_t u8;
@@ -60,8 +63,7 @@ typedef uint64_t u64;
6063
int main(int argc, char *argv[])
6164
{
6265
enum { TRIALS = 1000, BLOCKS = 128, BLOCK_SIZE = 64 };
63-
uint32_t counter[2];
64-
uint32_t key[8];
66+
uint32_t key[8], counter1[2], counter2[2];
6567
uint8_t output1[BLOCK_SIZE * BLOCKS], output2[BLOCK_SIZE * BLOCKS];
6668

6769
ksft_print_header();
@@ -72,17 +74,33 @@ int main(int argc, char *argv[])
7274
printf("getrandom() failed!\n");
7375
return KSFT_SKIP;
7476
}
75-
reference_chacha20_blocks(output1, key, BLOCKS);
77+
memset(counter1, 0, sizeof(counter1));
78+
reference_chacha20_blocks(output1, key, counter1, BLOCKS);
7679
for (unsigned int split = 0; split < BLOCKS; ++split) {
7780
memset(output2, 'X', sizeof(output2));
78-
memset(counter, 0, sizeof(counter));
81+
memset(counter2, 0, sizeof(counter2));
7982
if (split)
80-
__arch_chacha20_blocks_nostack(output2, key, counter, split);
81-
__arch_chacha20_blocks_nostack(output2 + split * BLOCK_SIZE, key, counter, BLOCKS - split);
82-
if (memcmp(output1, output2, sizeof(output1)))
83+
__arch_chacha20_blocks_nostack(output2, key, counter2, split);
84+
__arch_chacha20_blocks_nostack(output2 + split * BLOCK_SIZE, key, counter2, BLOCKS - split);
85+
if (memcmp(output1, output2, sizeof(output1)) || memcmp(counter1, counter2, sizeof(counter1)))
8386
return KSFT_FAIL;
8487
}
8588
}
89+
memset(counter1, 0, sizeof(counter1));
90+
counter1[0] = (uint32_t)-BLOCKS + 2;
91+
memset(counter2, 0, sizeof(counter2));
92+
counter2[0] = (uint32_t)-BLOCKS + 2;
93+
94+
reference_chacha20_blocks(output1, key, counter1, BLOCKS);
95+
__arch_chacha20_blocks_nostack(output2, key, counter2, BLOCKS);
96+
if (memcmp(output1, output2, sizeof(output1)) || memcmp(counter1, counter2, sizeof(counter1)))
97+
return KSFT_FAIL;
98+
99+
reference_chacha20_blocks(output1, key, counter1, BLOCKS);
100+
__arch_chacha20_blocks_nostack(output2, key, counter2, BLOCKS);
101+
if (memcmp(output1, output2, sizeof(output1)) || memcmp(counter1, counter2, sizeof(counter1)))
102+
return KSFT_FAIL;
103+
86104
ksft_test_result_pass("chacha: PASS\n");
87105
return KSFT_PASS;
88106
}

0 commit comments

Comments
 (0)