Linking to libsodium makes building this test annoying in cross
compilation environments and is just way too much. Since this is just a
basic correctness test, simply open code a simple, unoptimized, dumb
chacha, rather than linking to libsodium.

Signed-off-by: Jason A. Donenfeld <ja...@zx2c4.com>
---
 tools/testing/selftests/vDSO/Makefile         |  7 +--
 .../testing/selftests/vDSO/vdso_test_chacha.c | 46 ++++++++++++++++++-
 2 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/tools/testing/selftests/vDSO/Makefile 
b/tools/testing/selftests/vDSO/Makefile
index 13a626ef64f7..93c50a462858 100644
--- a/tools/testing/selftests/vDSO/Makefile
+++ b/tools/testing/selftests/vDSO/Makefile
@@ -1,8 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 uname_M := $(shell uname -m 2>/dev/null || echo not)
 ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
-SODIUM_LIBS := $(shell pkg-config --libs libsodium 2>/dev/null)
-SODIUM_CFLAGS := $(shell pkg-config --cflags libsodium 2>/dev/null)
 
 TEST_GEN_PROGS := vdso_test_gettimeofday
 TEST_GEN_PROGS += vdso_test_getcpu
@@ -14,10 +12,8 @@ endif
 TEST_GEN_PROGS += vdso_test_correctness
 ifeq ($(uname_M),x86_64)
 TEST_GEN_PROGS += vdso_test_getrandom
-ifneq ($(SODIUM_LIBS),)
 TEST_GEN_PROGS += vdso_test_chacha
 endif
-endif
 
 CFLAGS := -std=gnu99
 
@@ -43,8 +39,7 @@ $(OUTPUT)/vdso_test_getrandom: CFLAGS += -isystem 
$(top_srcdir)/tools/include \
                                          -isystem $(top_srcdir)/include/uapi
 
 $(OUTPUT)/vdso_test_chacha: 
$(top_srcdir)/tools/arch/$(ARCH)/vdso/vgetrandom-chacha.S
-$(OUTPUT)/vdso_test_chacha: LDLIBS += $(SODIUM_LIBS)
 $(OUTPUT)/vdso_test_chacha: CFLAGS += -idirafter $(top_srcdir)/tools/include \
                                       -idirafter 
$(top_srcdir)/arch/$(ARCH)/include \
                                       -idirafter $(top_srcdir)/include \
-                                      -D__ASSEMBLY__ -Wa,--noexecstack 
$(SODIUM_CFLAGS)
+                                      -D__ASSEMBLY__ -Wa,--noexecstack
diff --git a/tools/testing/selftests/vDSO/vdso_test_chacha.c 
b/tools/testing/selftests/vDSO/vdso_test_chacha.c
index ca5639d02969..019e8fbdf570 100644
--- a/tools/testing/selftests/vDSO/vdso_test_chacha.c
+++ b/tools/testing/selftests/vDSO/vdso_test_chacha.c
@@ -3,7 +3,6 @@
  * Copyright (C) 2022-2024 Jason A. Donenfeld <ja...@zx2c4.com>. All Rights 
Reserved.
  */
 
-#include <sodium/crypto_stream_chacha20.h>
 #include <sys/random.h>
 #include <string.h>
 #include <stdint.h>
@@ -14,6 +13,49 @@ typedef uint8_t u8;
 typedef uint32_t u32;
 typedef uint64_t u64;
 #include <vdso/getrandom.h>
+#include <tools/le_byteshift.h>
+
+static u32 rol32(u32 word, unsigned int shift)
+{
+       return (word << (shift & 31)) | (word >> ((-shift) & 31));
+}
+
+static void reference_chacha20_blocks(u8 *dst_bytes, const u32 *key, size_t 
nblocks)
+{
+       u32 s[16] = {
+               0x61707865U, 0x3320646eU, 0x79622d32U, 0x6b206574U,
+               key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7]
+       };
+
+       while (nblocks--) {
+               u32 x[16];
+               memcpy(x, s, sizeof(x));
+               for (unsigned int r = 0; r < 20; r += 2) {
+               #define QR(a, b, c, d) ( \
+                       x[a] += x[b], \
+                       x[d] = rol32(x[d] ^ x[a], 16), \
+                       x[c] += x[d], \
+                       x[b] = rol32(x[b] ^ x[c], 12), \
+                       x[a] += x[b], \
+                       x[d] = rol32(x[d] ^ x[a], 8), \
+                       x[c] += x[d], \
+                       x[b] = rol32(x[b] ^ x[c], 7))
+
+                       QR(0, 4, 8, 12);
+                       QR(1, 5, 9, 13);
+                       QR(2, 6, 10, 14);
+                       QR(3, 7, 11, 15);
+                       QR(0, 5, 10, 15);
+                       QR(1, 6, 11, 12);
+                       QR(2, 7, 8, 13);
+                       QR(3, 4, 9, 14);
+               }
+               for (unsigned int i = 0; i < 16; ++i, dst_bytes += sizeof(u32))
+                       put_unaligned_le32(x[i] + s[i], dst_bytes);
+               if (!++s[12])
+                       ++s[13];
+       }
+}
 
 int main(int argc, char *argv[])
 {
@@ -31,7 +73,7 @@ int main(int argc, char *argv[])
                        printf("getrandom() failed!\n");
                        return KSFT_SKIP;
                }
-               crypto_stream_chacha20(output1, sizeof(output1), nonce, 
(uint8_t *)key);
+               reference_chacha20_blocks(output1, key, BLOCKS);
                for (unsigned int split = 0; split < BLOCKS; ++split) {
                        memset(output2, 'X', sizeof(output2));
                        memset(counter, 0, sizeof(counter));
-- 
2.46.0


Reply via email to