Module Name:    src
Committed By:   riastradh
Date:           Sat Jul 25 22:46:35 UTC 2020

Modified Files:
        src/sys/conf: files
Added Files:
        src/sys/crypto/chacha: chacha.h chacha_impl.c chacha_impl.h
            chacha_ref.c chacha_ref.h chacha_selftest.c files.chacha

Log Message:
New ChaCha API in kernel.

This will enable us to adopt MD vectorized implementations of ChaCha.


To generate a diff of this commit:
cvs rdiff -u -r1.1272 -r1.1273 src/sys/conf/files
cvs rdiff -u -r0 -r1.1 src/sys/crypto/chacha/chacha.h \
    src/sys/crypto/chacha/chacha_impl.c src/sys/crypto/chacha/chacha_impl.h \
    src/sys/crypto/chacha/chacha_ref.c src/sys/crypto/chacha/chacha_ref.h \
    src/sys/crypto/chacha/chacha_selftest.c \
    src/sys/crypto/chacha/files.chacha

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/conf/files
diff -u src/sys/conf/files:1.1272 src/sys/conf/files:1.1273
--- src/sys/conf/files:1.1272	Sat Jul 25 22:26:23 2020
+++ src/sys/conf/files	Sat Jul 25 22:46:34 2020
@@ -1,4 +1,4 @@
-#	$NetBSD: files,v 1.1272 2020/07/25 22:26:23 riastradh Exp $
+#	$NetBSD: files,v 1.1273 2020/07/25 22:46:34 riastradh Exp $
 #	@(#)files.newconf	7.5 (Berkeley) 5/10/93
 
 version 	20171118
@@ -202,6 +202,7 @@ defflag	opt_machdep.h		MACHDEP
 # Individual crypto transforms
 include "crypto/adiantum/files.adiantum"
 include "crypto/aes/files.aes"
+include "crypto/chacha/files.chacha"
 include "crypto/des/files.des"
 include "crypto/blowfish/files.blowfish"
 include "crypto/cast128/files.cast128"

Added files:

Index: src/sys/crypto/chacha/chacha.h
diff -u /dev/null src/sys/crypto/chacha/chacha.h:1.1
--- /dev/null	Sat Jul 25 22:46:35 2020
+++ src/sys/crypto/chacha/chacha.h	Sat Jul 25 22:46:34 2020
@@ -0,0 +1,85 @@
+/*	$NetBSD: chacha.h,v 1.1 2020/07/25 22:46:34 riastradh Exp $	*/
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef	_SYS_CRYPTO_CHACHA_CHACHA_H
+#define	_SYS_CRYPTO_CHACHA_CHACHA_H
+
+#include <sys/types.h>
+
+#define	CHACHA_KEYBYTES			32
+
+#define	CHACHA_CORE_KEYBYTES		CHACHA_KEYBYTES
+#define	CHACHA_CORE_INBYTES		16
+#define	CHACHA_CORE_CONSTBYTES		16
+#define	CHACHA_CORE_OUTBYTES		64
+
+#define	HCHACHA_KEYBYTES		CHACHA_KEYBYTES
+#define	HCHACHA_INBYTES			16
+#define	HCHACHA_CONSTBYTES		16
+#define	HCHACHA_OUTBYTES		32
+
+#define	CHACHA_STREAM_KEYBYTES		CHACHA_KEYBYTES
+#define	CHACHA_STREAM_NONCEBYTES	12
+
+#define	XCHACHA_STREAM_KEYBYTES		CHACHA_KEYBYTES
+#define	XCHACHA_STREAM_NONCEBYTES	24
+
+extern const uint8_t chacha_const32[16];
+
+void	chacha_core(uint8_t[restrict static CHACHA_CORE_OUTBYTES],
+	    const uint8_t[static CHACHA_CORE_INBYTES],
+	    const uint8_t[static CHACHA_CORE_KEYBYTES],
+	    const uint8_t[static CHACHA_CORE_CONSTBYTES],
+	    unsigned);
+void	hchacha(uint8_t[restrict static HCHACHA_OUTBYTES],
+	    const uint8_t[static HCHACHA_INBYTES],
+	    const uint8_t[static HCHACHA_KEYBYTES],
+	    const uint8_t[static HCHACHA_CONSTBYTES],
+	    unsigned);
+void	chacha_stream(uint8_t *restrict, size_t,
+	    uint32_t,
+	    const uint8_t[static CHACHA_STREAM_NONCEBYTES],
+	    const uint8_t[static CHACHA_STREAM_KEYBYTES],
+	    unsigned);
+void	chacha_stream_xor(uint8_t *, const uint8_t *, size_t,
+	    uint32_t,
+	    const uint8_t[static CHACHA_STREAM_NONCEBYTES],
+	    const uint8_t[static CHACHA_STREAM_KEYBYTES],
+	    unsigned);
+void	xchacha_stream(uint8_t *restrict, size_t,
+	    uint32_t,
+	    const uint8_t[static XCHACHA_STREAM_NONCEBYTES],
+	    const uint8_t[static XCHACHA_STREAM_KEYBYTES],
+	    unsigned);
+void	xchacha_stream_xor(uint8_t *, const uint8_t *, size_t,
+	    uint32_t,
+	    const uint8_t[static XCHACHA_STREAM_NONCEBYTES],
+	    const uint8_t[static XCHACHA_STREAM_KEYBYTES],
+	    unsigned);
+
+#endif	/* _SYS_CRYPTO_CHACHA_CHACHA_H */
Index: src/sys/crypto/chacha/chacha_impl.c
diff -u /dev/null src/sys/crypto/chacha/chacha_impl.c:1.1
--- /dev/null	Sat Jul 25 22:46:35 2020
+++ src/sys/crypto/chacha/chacha_impl.c	Sat Jul 25 22:46:34 2020
@@ -0,0 +1,206 @@
+/*	$NetBSD: chacha_impl.c,v 1.1 2020/07/25 22:46:34 riastradh Exp $	*/
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <sys/errno.h>
+#include <sys/module.h>
+#include <sys/once.h>
+#include <sys/sysctl.h>
+
+#include <lib/libkern/libkern.h>
+
+#include "chacha.h"
+#include "chacha_ref.h"
+
+static const struct chacha_impl	*chacha_md_impl	__read_mostly;
+static const struct chacha_impl	*chacha_impl	__read_mostly;
+
+static int
+sysctl_hw_chacha_impl(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node;
+
+	KASSERTMSG(chacha_impl != NULL,
+	    "sysctl ran before ChaCha implementation was selected");
+
+	node = *rnode;
+	node.sysctl_data = __UNCONST(chacha_impl->ci_name);
+	node.sysctl_size = strlen(chacha_impl->ci_name) + 1;
+	return sysctl_lookup(SYSCTLFN_CALL(&node));
+}
+
+SYSCTL_SETUP(sysctl_hw_chacha_setup, "sysctl hw.chacha_impl setup")
+{
+
+	sysctl_createv(clog, 0, NULL, NULL,
+	    CTLFLAG_PERMANENT|CTLFLAG_READONLY, CTLTYPE_STRING, "chacha_impl",
+	    SYSCTL_DESCR("Selected ChaCha implementation"),
+	    sysctl_hw_chacha_impl, 0, NULL, 0,
+	    CTL_HW, CTL_CREATE, CTL_EOL);
+}
+
+static int
+chacha_select(void)
+{
+
+	KASSERT(chacha_impl == NULL);
+
+	if (chacha_md_impl) {
+		if (chacha_selftest(chacha_md_impl))
+			aprint_error("chacha: self-test failed: %s\n",
+			    chacha_md_impl->ci_name);
+		else
+			chacha_impl = chacha_md_impl;
+	}
+	if (chacha_impl == NULL) {
+		if (chacha_selftest(&chacha_ref_impl))
+			aprint_error("chacha: self-test failed: %s\n",
+			    chacha_ref_impl.ci_name);
+		else
+			chacha_impl = &chacha_ref_impl;
+	}
+	if (chacha_impl == NULL)
+		panic("ChaCha self-tests failed");
+
+	aprint_verbose("chacha: %s\n", chacha_impl->ci_name);
+	return 0;
+}
+
+MODULE(MODULE_CLASS_MISC, chacha, NULL);
+
+static int
+chacha_modcmd(modcmd_t cmd, void *opaque)
+{
+
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		return chacha_select();
+	case MODULE_CMD_FINI:
+		return 0;
+	default:
+		return ENOTTY;
+	}
+}
+
+static void
+chacha_guarantee_selected(void)
+{
+#if 0
+	static once_t once;
+	int error;
+
+	error = RUN_ONCE(&once, chacha_select);
+	KASSERT(error == 0);
+#endif
+}
+
+void
+chacha_md_init(const struct chacha_impl *impl)
+{
+
+	KASSERT(cold);
+	KASSERTMSG(chacha_impl == NULL,
+	    "ChaCha implementation `%s' already chosen, can't offer `%s'",
+	    chacha_impl->ci_name, impl->ci_name);
+	KASSERTMSG(chacha_md_impl == NULL,
+	    "ChaCha implementation `%s' already offered, can't offer `%s'",
+	    chacha_md_impl->ci_name, impl->ci_name);
+
+	chacha_md_impl = impl;
+}
+
+void
+chacha_core(uint8_t out[restrict static CHACHA_CORE_OUTBYTES],
+    const uint8_t in[static CHACHA_CORE_INBYTES],
+    const uint8_t k[static CHACHA_CORE_KEYBYTES],
+    const uint8_t c[static CHACHA_CORE_CONSTBYTES],
+    unsigned nr)
+{
+
+	chacha_guarantee_selected();
+	(*chacha_impl->ci_chacha_core)(out, in, k, c, nr);
+}
+
+void
+hchacha(uint8_t out[restrict static HCHACHA_OUTBYTES],
+    const uint8_t in[static HCHACHA_INBYTES],
+    const uint8_t k[static HCHACHA_KEYBYTES],
+    const uint8_t c[static HCHACHA_CONSTBYTES],
+    unsigned nr)
+{
+
+	chacha_guarantee_selected();
+	(*chacha_impl->ci_hchacha)(out, in, k, c, nr);
+}
+
+void
+chacha_stream(uint8_t *restrict s, size_t nbytes, uint32_t blkno,
+    const uint8_t nonce[static CHACHA_STREAM_NONCEBYTES],
+    const uint8_t key[static CHACHA_STREAM_KEYBYTES],
+    unsigned nr)
+{
+
+	chacha_guarantee_selected();
+	(*chacha_impl->ci_chacha_stream)(s, nbytes, blkno, nonce, key, nr);
+}
+
+void
+chacha_stream_xor(uint8_t *c, const uint8_t *p, size_t nbytes, uint32_t blkno,
+    const uint8_t nonce[static CHACHA_STREAM_NONCEBYTES],
+    const uint8_t key[static CHACHA_STREAM_KEYBYTES],
+    unsigned nr)
+{
+
+	chacha_guarantee_selected();
+	(*chacha_impl->ci_chacha_stream_xor)(c, p, nbytes, blkno, nonce, key,
+	    nr);
+}
+
+void
+xchacha_stream(uint8_t *restrict s, size_t nbytes, uint32_t blkno,
+    const uint8_t nonce[static XCHACHA_STREAM_NONCEBYTES],
+    const uint8_t key[static XCHACHA_STREAM_KEYBYTES],
+    unsigned nr)
+{
+
+	chacha_guarantee_selected();
+	(*chacha_impl->ci_xchacha_stream)(s, nbytes, blkno, nonce, key, nr);
+}
+
+void
+xchacha_stream_xor(uint8_t *c, const uint8_t *p, size_t nbytes, uint32_t blkno,
+    const uint8_t nonce[static XCHACHA_STREAM_NONCEBYTES],
+    const uint8_t key[static XCHACHA_STREAM_KEYBYTES],
+    unsigned nr)
+{
+
+	chacha_guarantee_selected();
+	(*chacha_impl->ci_xchacha_stream_xor)(c, p, nbytes, blkno, nonce, key,
+	    nr);
+}
Index: src/sys/crypto/chacha/chacha_impl.h
diff -u /dev/null src/sys/crypto/chacha/chacha_impl.h:1.1
--- /dev/null	Sat Jul 25 22:46:35 2020
+++ src/sys/crypto/chacha/chacha_impl.h	Sat Jul 25 22:46:34 2020
@@ -0,0 +1,83 @@
+/*	$NetBSD: chacha_impl.h,v 1.1 2020/07/25 22:46:34 riastradh Exp $	*/
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef	_SYS_CRYPTO_CHACHA_CHACHA_IMPL_H
+#define	_SYS_CRYPTO_CHACHA_CHACHA_IMPL_H
+
+#ifdef _KERNEL
+#include <sys/types.h>
+#include <sys/systm.h>
+#else
+#include <stdint.h>
+#include <string.h>
+#endif
+
+#include <crypto/chacha/chacha.h>
+
+struct chacha_impl {
+	const char *ci_name;
+	int	(*ci_probe)(void);
+	void	(*ci_chacha_core)(uint8_t[restrict static CHACHA_CORE_OUTBYTES],
+		    const uint8_t[static CHACHA_CORE_INBYTES],
+		    const uint8_t[static CHACHA_CORE_KEYBYTES],
+		    const uint8_t[static CHACHA_CORE_CONSTBYTES],
+		    unsigned);
+	void	(*ci_hchacha)(uint8_t[restrict static HCHACHA_OUTBYTES],
+		    const uint8_t[static HCHACHA_INBYTES],
+		    const uint8_t[static HCHACHA_KEYBYTES],
+		    const uint8_t[static HCHACHA_CONSTBYTES],
+		    unsigned);
+	void	(*ci_chacha_stream)(uint8_t *restrict, size_t,
+		    uint32_t,
+		    const uint8_t[static CHACHA_STREAM_NONCEBYTES],
+		    const uint8_t[static CHACHA_STREAM_KEYBYTES],
+		    unsigned);
+	void	(*ci_chacha_stream_xor)(uint8_t *, const uint8_t *,
+		    size_t,
+		    uint32_t,
+		    const uint8_t[static CHACHA_STREAM_NONCEBYTES],
+		    const uint8_t[static CHACHA_STREAM_KEYBYTES],
+		    unsigned);
+	void	(*ci_xchacha_stream)(uint8_t *restrict, size_t,
+		    uint32_t,
+		    const uint8_t[static XCHACHA_STREAM_NONCEBYTES],
+		    const uint8_t[static XCHACHA_STREAM_KEYBYTES],
+		    unsigned);
+	void	(*ci_xchacha_stream_xor)(uint8_t *, const uint8_t *,
+		    size_t,
+		    uint32_t,
+		    const uint8_t[static XCHACHA_STREAM_NONCEBYTES],
+		    const uint8_t[static XCHACHA_STREAM_KEYBYTES],
+		    unsigned);
+};
+
+int	chacha_selftest(const struct chacha_impl *);
+
+void	chacha_md_init(const struct chacha_impl *);
+
+#endif	/* _SYS_CRYPTO_CHACHA_CHACHA_IMPL_H */
Index: src/sys/crypto/chacha/chacha_ref.c
diff -u /dev/null src/sys/crypto/chacha/chacha_ref.c:1.1
--- /dev/null	Sat Jul 25 22:46:35 2020
+++ src/sys/crypto/chacha/chacha_ref.c	Sat Jul 25 22:46:34 2020
@@ -0,0 +1,466 @@
+/*	$NetBSD: chacha_ref.c,v 1.1 2020/07/25 22:46:34 riastradh Exp $	*/
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * ChaCha pseudorandom function family and stream cipher portable C
+ * implementation.  Derived from the specification,
+ *
+ *	Daniel J. Bernstein, `ChaCha, a variant of Salsa20', Workshop
+ *	Record of the State of the Art in Stream Ciphers -- SASC 2008.
+ *	https://cr.yp.to/papers.html#chacha
+ *
+ * which in turn builds on the specification of Salsa20 available at
+ * <https://cr.yp.to/snuffle.html>.  The particular parametrization of
+ * the stream cipher, with a 32-bit block counter and 96-bit nonce, is
+ * described in
+ *
+ *	Y. Nir and A. Langley, `ChaCha20 and Poly1305 for IETF
+ *	Protocols', IETF RFC 8439, June 2018.
+ *	https://tools.ietf.org/html/rfc8439
+ */
+
+#include "chacha_ref.h"
+
+static uint32_t
+rol32(uint32_t u, unsigned c)
+{
+
+	return (u << c) | (u >> (32 - c));
+}
+
+#define	CHACHA_QUARTERROUND(a, b, c, d) do				      \
+{									      \
+	(a) += (b); (d) ^= (a); (d) = rol32((d), 16);			      \
+	(c) += (d); (b) ^= (c); (b) = rol32((b), 12);			      \
+	(a) += (b); (d) ^= (a); (d) = rol32((d),  8);			      \
+	(c) += (d); (b) ^= (c); (b) = rol32((b),  7);			      \
+} while (/*CONSTCOND*/0)
+
+const uint8_t chacha_const32[16] = "expand 32-byte k";
+
+static void
+chacha_core_ref(uint8_t out[restrict static 64], const uint8_t in[static 16],
+    const uint8_t k[static 32], const uint8_t c[static 16], unsigned nr)
+{
+	uint32_t x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15;
+	uint32_t y0,y1,y2,y3,y4,y5,y6,y7,y8,y9,y10,y11,y12,y13,y14,y15;
+
+	x0 = y0 = le32dec(c + 0);
+	x1 = y1 = le32dec(c + 4);
+	x2 = y2 = le32dec(c + 8);
+	x3 = y3 = le32dec(c + 12);
+	x4 = y4 = le32dec(k + 0);
+	x5 = y5 = le32dec(k + 4);
+	x6 = y6 = le32dec(k + 8);
+	x7 = y7 = le32dec(k + 12);
+	x8 = y8 = le32dec(k + 16);
+	x9 = y9 = le32dec(k + 20);
+	x10 = y10 = le32dec(k + 24);
+	x11 = y11 = le32dec(k + 28);
+	x12 = y12 = le32dec(in + 0);
+	x13 = y13 = le32dec(in + 4);
+	x14 = y14 = le32dec(in + 8);
+	x15 = y15 = le32dec(in + 12);
+
+	for (; nr > 0; nr -= 2) {
+		CHACHA_QUARTERROUND( y0, y4, y8,y12);
+		CHACHA_QUARTERROUND( y1, y5, y9,y13);
+		CHACHA_QUARTERROUND( y2, y6,y10,y14);
+		CHACHA_QUARTERROUND( y3, y7,y11,y15);
+		CHACHA_QUARTERROUND( y0, y5,y10,y15);
+		CHACHA_QUARTERROUND( y1, y6,y11,y12);
+		CHACHA_QUARTERROUND( y2, y7, y8,y13);
+		CHACHA_QUARTERROUND( y3, y4, y9,y14);
+	}
+
+	le32enc(out + 0, x0 + y0);
+	le32enc(out + 4, x1 + y1);
+	le32enc(out + 8, x2 + y2);
+	le32enc(out + 12, x3 + y3);
+	le32enc(out + 16, x4 + y4);
+	le32enc(out + 20, x5 + y5);
+	le32enc(out + 24, x6 + y6);
+	le32enc(out + 28, x7 + y7);
+	le32enc(out + 32, x8 + y8);
+	le32enc(out + 36, x9 + y9);
+	le32enc(out + 40, x10 + y10);
+	le32enc(out + 44, x11 + y11);
+	le32enc(out + 48, x12 + y12);
+	le32enc(out + 52, x13 + y13);
+	le32enc(out + 56, x14 + y14);
+	le32enc(out + 60, x15 + y15);
+}
+
+/* ChaCha stream cipher (IETF style, 96-bit nonce and 32-bit block counter) */
+
+static void
+chacha_stream_ref(uint8_t *restrict s, size_t nbytes,
+    uint32_t blkno,
+    const uint8_t nonce[static 12],
+    const uint8_t k[static 32],
+    unsigned nr)
+{
+	const uint8_t *c = chacha_const32;
+	uint32_t x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15;
+	uint32_t y0,y1,y2,y3,y4,y5,y6,y7,y8,y9,y10,y11,y12,y13,y14,y15;
+	unsigned i;
+
+	x0 = le32dec(c + 0);
+	x1 = le32dec(c + 4);
+	x2 = le32dec(c + 8);
+	x3 = le32dec(c + 12);
+	x4 = le32dec(k + 0);
+	x5 = le32dec(k + 4);
+	x6 = le32dec(k + 8);
+	x7 = le32dec(k + 12);
+	x8 = le32dec(k + 16);
+	x9 = le32dec(k + 20);
+	x10 = le32dec(k + 24);
+	x11 = le32dec(k + 28);
+	/* x12 = blkno */
+	x13 = le32dec(nonce + 0);
+	x14 = le32dec(nonce + 4);
+	x15 = le32dec(nonce + 8);
+
+	for (; nbytes >= 64; nbytes -= 64, s += 64, blkno++) {
+		y0 = x0;
+		y1 = x1;
+		y2 = x2;
+		y3 = x3;
+		y4 = x4;
+		y5 = x5;
+		y6 = x6;
+		y7 = x7;
+		y8 = x8;
+		y9 = x9;
+		y10 = x10;
+		y11 = x11;
+		y12 = x12 = blkno;
+		y13 = x13;
+		y14 = x14;
+		y15 = x15;
+		for (i = nr; i > 0; i -= 2) {
+			CHACHA_QUARTERROUND( y0, y4, y8,y12);
+			CHACHA_QUARTERROUND( y1, y5, y9,y13);
+			CHACHA_QUARTERROUND( y2, y6,y10,y14);
+			CHACHA_QUARTERROUND( y3, y7,y11,y15);
+			CHACHA_QUARTERROUND( y0, y5,y10,y15);
+			CHACHA_QUARTERROUND( y1, y6,y11,y12);
+			CHACHA_QUARTERROUND( y2, y7, y8,y13);
+			CHACHA_QUARTERROUND( y3, y4, y9,y14);
+		}
+		le32enc(s + 0, x0 + y0);
+		le32enc(s + 4, x1 + y1);
+		le32enc(s + 8, x2 + y2);
+		le32enc(s + 12, x3 + y3);
+		le32enc(s + 16, x4 + y4);
+		le32enc(s + 20, x5 + y5);
+		le32enc(s + 24, x6 + y6);
+		le32enc(s + 28, x7 + y7);
+		le32enc(s + 32, x8 + y8);
+		le32enc(s + 36, x9 + y9);
+		le32enc(s + 40, x10 + y10);
+		le32enc(s + 44, x11 + y11);
+		le32enc(s + 48, x12 + y12);
+		le32enc(s + 52, x13 + y13);
+		le32enc(s + 56, x14 + y14);
+		le32enc(s + 60, x15 + y15);
+	}
+
+	if (nbytes) {
+		uint8_t buf[64];
+
+		y0 = x0;
+		y1 = x1;
+		y2 = x2;
+		y3 = x3;
+		y4 = x4;
+		y5 = x5;
+		y6 = x6;
+		y7 = x7;
+		y8 = x8;
+		y9 = x9;
+		y10 = x10;
+		y11 = x11;
+		y12 = x12 = blkno;
+		y13 = x13;
+		y14 = x14;
+		y15 = x15;
+		for (i = nr; i > 0; i -= 2) {
+			CHACHA_QUARTERROUND( y0, y4, y8,y12);
+			CHACHA_QUARTERROUND( y1, y5, y9,y13);
+			CHACHA_QUARTERROUND( y2, y6,y10,y14);
+			CHACHA_QUARTERROUND( y3, y7,y11,y15);
+			CHACHA_QUARTERROUND( y0, y5,y10,y15);
+			CHACHA_QUARTERROUND( y1, y6,y11,y12);
+			CHACHA_QUARTERROUND( y2, y7, y8,y13);
+			CHACHA_QUARTERROUND( y3, y4, y9,y14);
+		}
+		le32enc(buf + 0, x0 + y0);
+		le32enc(buf + 4, x1 + y1);
+		le32enc(buf + 8, x2 + y2);
+		le32enc(buf + 12, x3 + y3);
+		le32enc(buf + 16, x4 + y4);
+		le32enc(buf + 20, x5 + y5);
+		le32enc(buf + 24, x6 + y6);
+		le32enc(buf + 28, x7 + y7);
+		le32enc(buf + 32, x8 + y8);
+		le32enc(buf + 36, x9 + y9);
+		le32enc(buf + 40, x10 + y10);
+		le32enc(buf + 44, x11 + y11);
+		le32enc(buf + 48, x12 + y12);
+		le32enc(buf + 52, x13 + y13);
+		le32enc(buf + 56, x14 + y14);
+		le32enc(buf + 60, x15 + y15);
+		memcpy(s, buf, nbytes);
+	}
+}
+
+static void
+chacha_stream_xor_ref(uint8_t *s, const uint8_t *p, size_t nbytes,
+    uint32_t blkno,
+    const uint8_t nonce[static 12],
+    const uint8_t k[static 32],
+    unsigned nr)
+{
+	const uint8_t *c = chacha_const32;
+	uint32_t x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15;
+	uint32_t y0,y1,y2,y3,y4,y5,y6,y7,y8,y9,y10,y11,y12,y13,y14,y15;
+	unsigned i;
+
+	x0 = le32dec(c + 0);
+	x1 = le32dec(c + 4);
+	x2 = le32dec(c + 8);
+	x3 = le32dec(c + 12);
+	x4 = le32dec(k + 0);
+	x5 = le32dec(k + 4);
+	x6 = le32dec(k + 8);
+	x7 = le32dec(k + 12);
+	x8 = le32dec(k + 16);
+	x9 = le32dec(k + 20);
+	x10 = le32dec(k + 24);
+	x11 = le32dec(k + 28);
+	/* x12 = blkno */
+	x13 = le32dec(nonce + 0);
+	x14 = le32dec(nonce + 4);
+	x15 = le32dec(nonce + 8);
+
+	for (; nbytes >= 64; nbytes -= 64, s += 64, p += 64, blkno++) {
+		y0 = x0;
+		y1 = x1;
+		y2 = x2;
+		y3 = x3;
+		y4 = x4;
+		y5 = x5;
+		y6 = x6;
+		y7 = x7;
+		y8 = x8;
+		y9 = x9;
+		y10 = x10;
+		y11 = x11;
+		y12 = x12 = blkno;
+		y13 = x13;
+		y14 = x14;
+		y15 = x15;
+		for (i = nr; i > 0; i -= 2) {
+			CHACHA_QUARTERROUND( y0, y4, y8,y12);
+			CHACHA_QUARTERROUND( y1, y5, y9,y13);
+			CHACHA_QUARTERROUND( y2, y6,y10,y14);
+			CHACHA_QUARTERROUND( y3, y7,y11,y15);
+			CHACHA_QUARTERROUND( y0, y5,y10,y15);
+			CHACHA_QUARTERROUND( y1, y6,y11,y12);
+			CHACHA_QUARTERROUND( y2, y7, y8,y13);
+			CHACHA_QUARTERROUND( y3, y4, y9,y14);
+		}
+		le32enc(s + 0, (x0 + y0) ^ le32dec(p + 0));
+		le32enc(s + 4, (x1 + y1) ^ le32dec(p + 4));
+		le32enc(s + 8, (x2 + y2) ^ le32dec(p + 8));
+		le32enc(s + 12, (x3 + y3) ^ le32dec(p + 12));
+		le32enc(s + 16, (x4 + y4) ^ le32dec(p + 16));
+		le32enc(s + 20, (x5 + y5) ^ le32dec(p + 20));
+		le32enc(s + 24, (x6 + y6) ^ le32dec(p + 24));
+		le32enc(s + 28, (x7 + y7) ^ le32dec(p + 28));
+		le32enc(s + 32, (x8 + y8) ^ le32dec(p + 32));
+		le32enc(s + 36, (x9 + y9) ^ le32dec(p + 36));
+		le32enc(s + 40, (x10 + y10) ^ le32dec(p + 40));
+		le32enc(s + 44, (x11 + y11) ^ le32dec(p + 44));
+		le32enc(s + 48, (x12 + y12) ^ le32dec(p + 48));
+		le32enc(s + 52, (x13 + y13) ^ le32dec(p + 52));
+		le32enc(s + 56, (x14 + y14) ^ le32dec(p + 56));
+		le32enc(s + 60, (x15 + y15) ^ le32dec(p + 60));
+	}
+
+	if (nbytes) {
+		uint8_t buf[64];
+
+		y0 = x0;
+		y1 = x1;
+		y2 = x2;
+		y3 = x3;
+		y4 = x4;
+		y5 = x5;
+		y6 = x6;
+		y7 = x7;
+		y8 = x8;
+		y9 = x9;
+		y10 = x10;
+		y11 = x11;
+		y12 = x12 = blkno;
+		y13 = x13;
+		y14 = x14;
+		y15 = x15;
+		for (i = nr; i > 0; i -= 2) {
+			CHACHA_QUARTERROUND( y0, y4, y8,y12);
+			CHACHA_QUARTERROUND( y1, y5, y9,y13);
+			CHACHA_QUARTERROUND( y2, y6,y10,y14);
+			CHACHA_QUARTERROUND( y3, y7,y11,y15);
+			CHACHA_QUARTERROUND( y0, y5,y10,y15);
+			CHACHA_QUARTERROUND( y1, y6,y11,y12);
+			CHACHA_QUARTERROUND( y2, y7, y8,y13);
+			CHACHA_QUARTERROUND( y3, y4, y9,y14);
+		}
+		le32enc(buf + 0, x0 + y0);
+		le32enc(buf + 4, x1 + y1);
+		le32enc(buf + 8, x2 + y2);
+		le32enc(buf + 12, x3 + y3);
+		le32enc(buf + 16, x4 + y4);
+		le32enc(buf + 20, x5 + y5);
+		le32enc(buf + 24, x6 + y6);
+		le32enc(buf + 28, x7 + y7);
+		le32enc(buf + 32, x8 + y8);
+		le32enc(buf + 36, x9 + y9);
+		le32enc(buf + 40, x10 + y10);
+		le32enc(buf + 44, x11 + y11);
+		le32enc(buf + 48, x12 + y12);
+		le32enc(buf + 52, x13 + y13);
+		le32enc(buf + 56, x14 + y14);
+		le32enc(buf + 60, x15 + y15);
+		for (i = 0; i < nbytes - nbytes%4; i += 4)
+			le32enc(s + i, le32dec(p + i) ^ le32dec(buf + i));
+		for (; i < nbytes; i++)
+			s[i] = p[i] ^ buf[i];
+	}
+}
+
+/* HChaCha */
+
+static void
+hchacha_ref(uint8_t out[restrict static 32], const uint8_t in[static 16],
+    const uint8_t k[static 32], const uint8_t c[static 16], unsigned nr)
+{
+	uint32_t y0,y1,y2,y3,y4,y5,y6,y7,y8,y9,y10,y11,y12,y13,y14,y15;
+
+	y0 = le32dec(c + 0);
+	y1 = le32dec(c + 4);
+	y2 = le32dec(c + 8);
+	y3 = le32dec(c + 12);
+	y4 = le32dec(k + 0);
+	y5 = le32dec(k + 4);
+	y6 = le32dec(k + 8);
+	y7 = le32dec(k + 12);
+	y8 = le32dec(k + 16);
+	y9 = le32dec(k + 20);
+	y10 = le32dec(k + 24);
+	y11 = le32dec(k + 28);
+	y12 = le32dec(in + 0);
+	y13 = le32dec(in + 4);
+	y14 = le32dec(in + 8);
+	y15 = le32dec(in + 12);
+
+	for (; nr > 0; nr -= 2) {
+		CHACHA_QUARTERROUND( y0, y4, y8,y12);
+		CHACHA_QUARTERROUND( y1, y5, y9,y13);
+		CHACHA_QUARTERROUND( y2, y6,y10,y14);
+		CHACHA_QUARTERROUND( y3, y7,y11,y15);
+		CHACHA_QUARTERROUND( y0, y5,y10,y15);
+		CHACHA_QUARTERROUND( y1, y6,y11,y12);
+		CHACHA_QUARTERROUND( y2, y7, y8,y13);
+		CHACHA_QUARTERROUND( y3, y4, y9,y14);
+	}
+
+	le32enc(out + 0, y0);
+	le32enc(out + 4, y1);
+	le32enc(out + 8, y2);
+	le32enc(out + 12, y3);
+	le32enc(out + 16, y12);
+	le32enc(out + 20, y13);
+	le32enc(out + 24, y14);
+	le32enc(out + 28, y15);
+}
+
+/* XChaCha stream cipher */
+
+/* https://tools.ietf.org/html/draft-irtf-cfrg-xchacha-03 */
+
+static void
+xchacha_stream_ref(uint8_t *restrict s, size_t nbytes, uint32_t blkno,
+    const uint8_t nonce[static 24], const uint8_t k[static 32], unsigned nr)
+{
+	uint8_t subkey[32];
+	uint8_t subnonce[12];
+
+	hchacha_ref(subkey, nonce/*[0:16)*/, k, chacha_const32, nr);
+	memset(subnonce, 0, 4);
+	memcpy(subnonce + 4, nonce + 16, 8);
+	chacha_stream_ref(s, nbytes, blkno, subnonce, subkey, nr);
+}
+
+static void
+xchacha_stream_xor_ref(uint8_t *restrict c, const uint8_t *p, size_t nbytes,
+    uint32_t blkno,
+    const uint8_t nonce[static 24],
+    const uint8_t k[static 32],
+    unsigned nr)
+{
+	uint8_t subkey[32];
+	uint8_t subnonce[12];
+
+	hchacha_ref(subkey, nonce/*[0:16)*/, k, chacha_const32, nr);
+	memset(subnonce, 0, 4);
+	memcpy(subnonce + 4, nonce + 16, 8);
+	chacha_stream_xor_ref(c, p, nbytes, blkno, subnonce, subkey, nr);
+}
+
+static int
+chacha_probe_ref(void)
+{
+
+	/* The reference implementation is always available.  */
+	return 0;
+}
+
+const struct chacha_impl chacha_ref_impl = {
+	.ci_name = "Portable C ChaCha",
+	.ci_probe = chacha_probe_ref,
+	.ci_chacha_core = chacha_core_ref,
+	.ci_hchacha = hchacha_ref,
+	.ci_chacha_stream = chacha_stream_ref,
+	.ci_chacha_stream_xor = chacha_stream_xor_ref,
+	.ci_xchacha_stream = xchacha_stream_ref,
+	.ci_xchacha_stream_xor = xchacha_stream_xor_ref,
+};
Index: src/sys/crypto/chacha/chacha_ref.h
diff -u /dev/null src/sys/crypto/chacha/chacha_ref.h:1.1
--- /dev/null	Sat Jul 25 22:46:35 2020
+++ src/sys/crypto/chacha/chacha_ref.h	Sat Jul 25 22:46:34 2020
@@ -0,0 +1,36 @@
+/*	$NetBSD: chacha_ref.h,v 1.1 2020/07/25 22:46:34 riastradh Exp $	*/
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef	_SYS_CRYPTO_CHACHA_REF_H
+#define	_SYS_CRYPTO_CHACHA_REF_H
+
+#include "chacha_impl.h"
+
+extern const struct chacha_impl chacha_ref_impl;
+
+#endif	/* _SYS_CRYPTO_CHACHA_REF_H */
Index: src/sys/crypto/chacha/chacha_selftest.c
diff -u /dev/null src/sys/crypto/chacha/chacha_selftest.c:1.1
--- /dev/null	Sat Jul 25 22:46:35 2020
+++ src/sys/crypto/chacha/chacha_selftest.c	Sat Jul 25 22:46:34 2020
@@ -0,0 +1,464 @@
+/*	$NetBSD: chacha_selftest.c,v 1.1 2020/07/25 22:46:34 riastradh Exp $	*/
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "chacha_impl.h"
+
+#ifdef _KERNEL
+
+#include <lib/libkern/libkern.h>
+
+#else
+
+#include <stdio.h>
+#include <string.h>
+
+static void
+hexdump(int (*prf)(const char *, ...) __printflike(1,2), const char *prefix,
+    const void *buf, size_t len)
+{
+	const uint8_t *p = buf;
+	size_t i;
+
+	(*prf)("%s (%zu bytes @ %p)\n", prefix, len, buf);
+	for (i = 0; i < len; i++) {
+		if (i % 16 == 8)
+			(*prf)("  ");
+		else
+			(*prf)(" ");
+		(*prf)("%02hhx", p[i]);
+		if ((i + 1) % 16 == 0)
+			(*prf)("\n");
+	}
+	if (i % 16)
+		(*prf)("\n");
+}
+
+#endif
+
+/* https://tools.ietf.org/html/draft-strombergson-chacha-test-vectors-00 */
+static int
+chacha_core_selftest(const struct chacha_impl *ci)
+{
+	/* TC1, 32-byte key, rounds=12, keystream block 1 */
+	static const uint8_t zero[32];
+	static const uint8_t expected0[64] = {
+		0x9b,0xf4,0x9a,0x6a, 0x07,0x55,0xf9,0x53,
+		0x81,0x1f,0xce,0x12, 0x5f,0x26,0x83,0xd5,
+		0x04,0x29,0xc3,0xbb, 0x49,0xe0,0x74,0x14,
+		0x7e,0x00,0x89,0xa5, 0x2e,0xae,0x15,0x5f,
+		0x05,0x64,0xf8,0x79, 0xd2,0x7a,0xe3,0xc0,
+		0x2c,0xe8,0x28,0x34, 0xac,0xfa,0x8c,0x79,
+		0x3a,0x62,0x9f,0x2c, 0xa0,0xde,0x69,0x19,
+		0x61,0x0b,0xe8,0x2f, 0x41,0x13,0x26,0xbe,
+	};
+	/* TC7, 32-byte key, rounds=12, keystream block 2 */
+	static const uint8_t k1[32] = {
+		0x00,0x11,0x22,0x33, 0x44,0x55,0x66,0x77,
+		0x88,0x99,0xaa,0xbb, 0xcc,0xdd,0xee,0xff,
+		0xff,0xee,0xdd,0xcc, 0xbb,0xaa,0x99,0x88,
+		0x77,0x66,0x55,0x44, 0x33,0x22,0x11,0x00,
+	};
+	static const uint8_t in1[16] = {
+		0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
+		0x0f,0x1e,0x2d,0x3c, 0x4b,0x59,0x68,0x77,
+	};
+	static const uint8_t expected1[64] = {
+		0xcd,0x9a,0x2a,0xa9, 0xea,0x93,0xc2,0x67,
+		0x5e,0x82,0x88,0x14, 0x08,0xde,0x85,0x2c,
+		0x62,0xfa,0x74,0x6a, 0x30,0xe5,0x2b,0x45,
+		0xa2,0x69,0x62,0xcf, 0x43,0x51,0xe3,0x04,
+		0xd3,0x13,0x20,0xbb, 0xd6,0xaa,0x6c,0xc8,
+		0xf3,0x26,0x37,0xf9, 0x59,0x34,0xe4,0xc1,
+		0x45,0xef,0xd5,0x62, 0x31,0xef,0x31,0x61,
+		0x03,0x28,0x36,0xf4, 0x96,0x71,0x83,0x3e,
+	};
+	uint8_t out[64];
+	int result = 0;
+
+	(*ci->ci_chacha_core)(out, zero, zero, chacha_const32, 12);
+	if (memcmp(out, expected0, 64)) {
+		hexdump(printf, "chacha core 1", out, sizeof out);
+		result = -1;
+	}
+
+	(*ci->ci_chacha_core)(out, in1, k1, chacha_const32, 12);
+	if (memcmp(out, expected1, 64)) {
+		hexdump(printf, "chacha core 2", out, sizeof out);
+		result = -1;
+	}
+
+	return result;
+}
+
+static int
+hchacha_selftest(const struct chacha_impl *ci)
+{
+	/* https://tools.ietf.org/html/draft-irtf-cfrg-xchacha-03, ยง2.2.1 */
+	static const uint8_t k[32] = {
+		0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07,
+		0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f,
+		0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17,
+		0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f,
+	};
+	static const uint8_t in[16] = {
+		0x00,0x00,0x00,0x09, 0x00,0x00,0x00,0x4a,
+		0x00,0x00,0x00,0x00, 0x31,0x41,0x59,0x27,
+	};
+	static const uint8_t expected[32] = {
+		0x82,0x41,0x3b,0x42, 0x27,0xb2,0x7b,0xfe,
+		0xd3,0x0e,0x42,0x50, 0x8a,0x87,0x7d,0x73,
+		0xa0,0xf9,0xe4,0xd5, 0x8a,0x74,0xa8,0x53,
+		0xc1,0x2e,0xc4,0x13, 0x26,0xd3,0xec,0xdc,
+	};
+	uint8_t out[32];
+	int result = 0;
+
+	(*ci->ci_hchacha)(out, in, k, chacha_const32, 20);
+	if (memcmp(out, expected, 32)) {
+		hexdump(printf, "hchacha", out, sizeof out);
+		result = -1;
+	}
+
+	return result;
+}
+
+static int
+chacha_stream_selftest(const struct chacha_impl *ci)
+{
+
+	/* XXX */
+	return 0;
+}
+
+static int
+xchacha_stream_selftest(const struct chacha_impl *ci)
+{
+	/* https://tools.ietf.org/html/draft-irtf-cfrg-xchacha-03, A.2.1 */
+	static const uint8_t k[32] = {
+		0x80,0x81,0x82,0x83, 0x84,0x85,0x86,0x87,
+		0x88,0x89,0x8a,0x8b, 0x8c,0x8d,0x8e,0x8f,
+		0x90,0x91,0x92,0x93, 0x94,0x95,0x96,0x97,
+		0x98,0x99,0x9a,0x9b, 0x9c,0x9d,0x9e,0x9f,
+	};
+	static const uint8_t nonce[24] = {
+		0x40,0x41,0x42,0x43, 0x44,0x45,0x46,0x47,
+		0x48,0x49,0x4a,0x4b, 0x4c,0x4d,0x4e,0x4f,
+		0x50,0x51,0x52,0x53, 0x54,0x55,0x56,0x58,
+	};
+	static const uint8_t p[608] = {
+		0x54,0x68,0x65,0x20, 0x64,0x68,0x6f,0x6c,
+		0x65,0x20,0x28,0x70, 0x72,0x6f,0x6e,0x6f,
+		0x75,0x6e,0x63,0x65, 0x64,0x20,0x22,0x64,
+		0x6f,0x6c,0x65,0x22, 0x29,0x20,0x69,0x73,
+		0x20,0x61,0x6c,0x73, 0x6f,0x20,0x6b,0x6e,
+		0x6f,0x77,0x6e,0x20, 0x61,0x73,0x20,0x74,
+		0x68,0x65,0x20,0x41, 0x73,0x69,0x61,0x74,
+		0x69,0x63,0x20,0x77, 0x69,0x6c,0x64,0x20,
+		0x64,0x6f,0x67,0x2c, 0x20,0x72,0x65,0x64,
+		0x20,0x64,0x6f,0x67, 0x2c,0x20,0x61,0x6e,
+		0x64,0x20,0x77,0x68, 0x69,0x73,0x74,0x6c,
+		0x69,0x6e,0x67,0x20, 0x64,0x6f,0x67,0x2e,
+		0x20,0x49,0x74,0x20, 0x69,0x73,0x20,0x61,
+		0x62,0x6f,0x75,0x74, 0x20,0x74,0x68,0x65,
+		0x20,0x73,0x69,0x7a, 0x65,0x20,0x6f,0x66,
+		0x20,0x61,0x20,0x47, 0x65,0x72,0x6d,0x61,
+		0x6e,0x20,0x73,0x68, 0x65,0x70,0x68,0x65,
+		0x72,0x64,0x20,0x62, 0x75,0x74,0x20,0x6c,
+		0x6f,0x6f,0x6b,0x73, 0x20,0x6d,0x6f,0x72,
+		0x65,0x20,0x6c,0x69, 0x6b,0x65,0x20,0x61,
+		0x20,0x6c,0x6f,0x6e, 0x67,0x2d,0x6c,0x65,
+		0x67,0x67,0x65,0x64, 0x20,0x66,0x6f,0x78,
+		0x2e,0x20,0x54,0x68, 0x69,0x73,0x20,0x68,
+		0x69,0x67,0x68,0x6c, 0x79,0x20,0x65,0x6c,
+		0x75,0x73,0x69,0x76, 0x65,0x20,0x61,0x6e,
+		0x64,0x20,0x73,0x6b, 0x69,0x6c,0x6c,0x65,
+		0x64,0x20,0x6a,0x75, 0x6d,0x70,0x65,0x72,
+		0x20,0x69,0x73,0x20, 0x63,0x6c,0x61,0x73,
+		0x73,0x69,0x66,0x69, 0x65,0x64,0x20,0x77,
+		0x69,0x74,0x68,0x20, 0x77,0x6f,0x6c,0x76,
+		0x65,0x73,0x2c,0x20, 0x63,0x6f,0x79,0x6f,
+		0x74,0x65,0x73,0x2c, 0x20,0x6a,0x61,0x63,
+		0x6b,0x61,0x6c,0x73, 0x2c,0x20,0x61,0x6e,
+		0x64,0x20,0x66,0x6f, 0x78,0x65,0x73,0x20,
+		0x69,0x6e,0x20,0x74, 0x68,0x65,0x20,0x74,
+		0x61,0x78,0x6f,0x6e, 0x6f,0x6d,0x69,0x63,
+		0x20,0x66,0x61,0x6d, 0x69,0x6c,0x79,0x20,
+		0x43,0x61,0x6e,0x69, 0x64,0x61,0x65,0x2e,
+
+		0x54,0x68,0x65,0x20, 0x64,0x68,0x6f,0x6c,
+		0x65,0x20,0x28,0x70, 0x72,0x6f,0x6e,0x6f,
+		0x75,0x6e,0x63,0x65, 0x64,0x20,0x22,0x64,
+		0x6f,0x6c,0x65,0x22, 0x29,0x20,0x69,0x73,
+		0x20,0x61,0x6c,0x73, 0x6f,0x20,0x6b,0x6e,
+		0x6f,0x77,0x6e,0x20, 0x61,0x73,0x20,0x74,
+		0x68,0x65,0x20,0x41, 0x73,0x69,0x61,0x74,
+		0x69,0x63,0x20,0x77, 0x69,0x6c,0x64,0x20,
+		0x64,0x6f,0x67,0x2c, 0x20,0x72,0x65,0x64,
+		0x20,0x64,0x6f,0x67, 0x2c,0x20,0x61,0x6e,
+		0x64,0x20,0x77,0x68, 0x69,0x73,0x74,0x6c,
+		0x69,0x6e,0x67,0x20, 0x64,0x6f,0x67,0x2e,
+		0x20,0x49,0x74,0x20, 0x69,0x73,0x20,0x61,
+		0x62,0x6f,0x75,0x74, 0x20,0x74,0x68,0x65,
+		0x20,0x73,0x69,0x7a, 0x65,0x20,0x6f,0x66,
+		0x20,0x61,0x20,0x47, 0x65,0x72,0x6d,0x61,
+		0x6e,0x20,0x73,0x68, 0x65,0x70,0x68,0x65,
+		0x72,0x64,0x20,0x62, 0x75,0x74,0x20,0x6c,
+		0x6f,0x6f,0x6b,0x73, 0x20,0x6d,0x6f,0x72,
+		0x65,0x20,0x6c,0x69, 0x6b,0x65,0x20,0x61,
+		0x20,0x6c,0x6f,0x6e, 0x67,0x2d,0x6c,0x65,
+		0x67,0x67,0x65,0x64, 0x20,0x66,0x6f,0x78,
+		0x2e,0x20,0x54,0x68, 0x69,0x73,0x20,0x68,
+		0x69,0x67,0x68,0x6c, 0x79,0x20,0x65,0x6c,
+		0x75,0x73,0x69,0x76, 0x65,0x20,0x61,0x6e,
+		0x64,0x20,0x73,0x6b, 0x69,0x6c,0x6c,0x65,
+		0x64,0x20,0x6a,0x75, 0x6d,0x70,0x65,0x72,
+		0x20,0x69,0x73,0x20, 0x63,0x6c,0x61,0x73,
+		0x73,0x69,0x66,0x69, 0x65,0x64,0x20,0x77,
+		0x69,0x74,0x68,0x20, 0x77,0x6f,0x6c,0x76,
+		0x65,0x73,0x2c,0x20, 0x63,0x6f,0x79,0x6f,
+		0x74,0x65,0x73,0x2c, 0x20,0x6a,0x61,0x63,
+		0x6b,0x61,0x6c,0x73, 0x2c,0x20,0x61,0x6e,
+		0x64,0x20,0x66,0x6f, 0x78,0x65,0x73,0x20,
+		0x69,0x6e,0x20,0x74, 0x68,0x65,0x20,0x74,
+		0x61,0x78,0x6f,0x6e, 0x6f,0x6d,0x69,0x63,
+		0x20,0x66,0x61,0x6d, 0x69,0x6c,0x79,0x20,
+		0x43,0x61,0x6e,0x69, 0x64,0x61,0x65,0x2e,
+	};
+	static const uint8_t expected[608] = {
+		0x45,0x59,0xab,0xba, 0x4e,0x48,0xc1,0x61,
+		0x02,0xe8,0xbb,0x2c, 0x05,0xe6,0x94,0x7f,
+		0x50,0xa7,0x86,0xde, 0x16,0x2f,0x9b,0x0b,
+		0x7e,0x59,0x2a,0x9b, 0x53,0xd0,0xd4,0xe9,
+		0x8d,0x8d,0x64,0x10, 0xd5,0x40,0xa1,0xa6,
+		0x37,0x5b,0x26,0xd8, 0x0d,0xac,0xe4,0xfa,
+		0xb5,0x23,0x84,0xc7, 0x31,0xac,0xbf,0x16,
+		0xa5,0x92,0x3c,0x0c, 0x48,0xd3,0x57,0x5d,
+		0x4d,0x0d,0x2c,0x67, 0x3b,0x66,0x6f,0xaa,
+		0x73,0x10,0x61,0x27, 0x77,0x01,0x09,0x3a,
+		0x6b,0xf7,0xa1,0x58, 0xa8,0x86,0x42,0x92,
+		0xa4,0x1c,0x48,0xe3, 0xa9,0xb4,0xc0,0xda,
+		0xec,0xe0,0xf8,0xd9, 0x8d,0x0d,0x7e,0x05,
+		0xb3,0x7a,0x30,0x7b, 0xbb,0x66,0x33,0x31,
+		0x64,0xec,0x9e,0x1b, 0x24,0xea,0x0d,0x6c,
+		0x3f,0xfd,0xdc,0xec, 0x4f,0x68,0xe7,0x44,
+		0x30,0x56,0x19,0x3a, 0x03,0xc8,0x10,0xe1,
+		0x13,0x44,0xca,0x06, 0xd8,0xed,0x8a,0x2b,
+		0xfb,0x1e,0x8d,0x48, 0xcf,0xa6,0xbc,0x0e,
+		0xb4,0xe2,0x46,0x4b, 0x74,0x81,0x42,0x40,
+		0x7c,0x9f,0x43,0x1a, 0xee,0x76,0x99,0x60,
+		0xe1,0x5b,0xa8,0xb9, 0x68,0x90,0x46,0x6e,
+		0xf2,0x45,0x75,0x99, 0x85,0x23,0x85,0xc6,
+		0x61,0xf7,0x52,0xce, 0x20,0xf9,0xda,0x0c,
+		0x09,0xab,0x6b,0x19, 0xdf,0x74,0xe7,0x6a,
+		0x95,0x96,0x74,0x46, 0xf8,0xd0,0xfd,0x41,
+		0x5e,0x7b,0xee,0x2a, 0x12,0xa1,0x14,0xc2,
+		0x0e,0xb5,0x29,0x2a, 0xe7,0xa3,0x49,0xae,
+		0x57,0x78,0x20,0xd5, 0x52,0x0a,0x1f,0x3f,
+		0xb6,0x2a,0x17,0xce, 0x6a,0x7e,0x68,0xfa,
+		0x7c,0x79,0x11,0x1d, 0x88,0x60,0x92,0x0b,
+		0xc0,0x48,0xef,0x43, 0xfe,0x84,0x48,0x6c,
+		0xcb,0x87,0xc2,0x5f, 0x0a,0xe0,0x45,0xf0,
+		0xcc,0xe1,0xe7,0x98, 0x9a,0x9a,0xa2,0x20,
+		0xa2,0x8b,0xdd,0x48, 0x27,0xe7,0x51,0xa2,
+		0x4a,0x6d,0x5c,0x62, 0xd7,0x90,0xa6,0x63,
+		0x93,0xb9,0x31,0x11, 0xc1,0xa5,0x5d,0xd7,
+		0x42,0x1a,0x10,0x18, 0x49,0x74,0xc7,0xc5,
+
+		0x08,0x38,0x2d,0x64, 0x35,0x8d,0x21,0x77,
+		0x2e,0xb9,0x73,0xa8, 0x8f,0xb6,0x2b,0xf8,
+		0xce,0xfa,0xb4,0xca, 0x6f,0x0c,0x26,0xbb,
+		0x7f,0xd6,0x6d,0xb2, 0xa0,0xbe,0xb0,0x5a,
+		0x1a,0x6e,0x39,0xcb, 0xd5,0xda,0xf2,0xfc,
+		0x0b,0x74,0x31,0x3d, 0x2e,0xcd,0x5f,0x94,
+		0xc2,0x9f,0x30,0xdb, 0x11,0x5e,0x41,0x53,
+		0x8c,0x6d,0x30,0xba, 0x97,0xa0,0xc5,0x07,
+		0x70,0x78,0x02,0x5a, 0xc1,0x69,0x70,0x8f,
+		0x22,0x85,0xcb,0x98, 0xbc,0x6a,0x51,0xfb,
+		0xc6,0xa7,0xc3,0x3d, 0x76,0xe4,0x93,0x9a,
+		0x21,0xe2,0xc6,0x12, 0xe1,0x3a,0xcc,0xfb,
+		0x6f,0xa6,0x57,0xc0, 0x09,0x8c,0x6f,0xf3,
+		0x8d,0x83,0x21,0x1b, 0x71,0xa9,0xc1,0x93,
+		0x88,0x35,0xfc,0x18, 0x1f,0x94,0xa2,0x57,
+		0x3a,0x4e,0xd0,0xc0, 0xbc,0x92,0xa7,0x9c,
+		0x52,0x8a,0x82,0x9d, 0x44,0x75,0x7b,0xa0,
+		0xcf,0x3d,0x2d,0xbf, 0xf9,0x6f,0x71,0x56,
+		0x38,0xb0,0x63,0x5e, 0x55,0xcd,0x28,0x12,
+		0xc5,0xea,0x52,0xf4, 0xdc,0xf7,0xdc,0x3d,
+		0xd8,0x96,0x09,0xe8, 0x2a,0xcc,0x00,0x16,
+		0x88,0x77,0x82,0x10, 0xed,0x7d,0xd8,0x8b,
+		0xf5,0xd3,0xe1,0xfc, 0x49,0x66,0x36,0x8d,
+		0x55,0xd2,0x33,0xb8, 0x6d,0xff,0xe3,0xd3,
+		0x55,0x80,0x0e,0xd8, 0x95,0x32,0x32,0x55,
+		0x83,0xe7,0x58,0x6f, 0xec,0xc3,0x8c,0xf8,
+		0x52,0x16,0xdc,0x0d, 0x29,0x02,0xe5,0x27,
+		0x35,0xc2,0xbb,0xe2, 0xe2,0x3b,0xf5,0x19,
+		0xcd,0x44,0x83,0xe8, 0x21,0x55,0xd0,0x10,
+		0x15,0x68,0x8e,0x46, 0xa3,0x2f,0xa5,0x7c,
+		0xa8,0x2c,0xc6,0x8f, 0x14,0xcd,0xb3,0x79,
+		0x92,0x32,0x71,0xac, 0xd9,0xaf,0x9c,0x4d,
+		0x00,0x88,0xd1,0x42, 0xd5,0x23,0xfa,0xe6,
+		0x7f,0x38,0xa2,0x56, 0x99,0xbe,0x6f,0xcf,
+		0xe0,0xaa,0x44,0x11, 0x8a,0xc8,0x3a,0x99,
+		0x48,0x6d,0x33,0x0e, 0x94,0xf2,0xb9,0x87,
+		0xed,0x4f,0x6a,0x9c, 0x33,0x93,0x6d,0xe4,
+		0x92,0x76,0xab,0xfa, 0xce,0x5b,0x17,0x14,
+	};
+	uint8_t c[608];
+	unsigned i;
+	int result = 0;
+
+	/*
+	 * 608 = 96 (mod 256)
+	 * 607 = 95 (mod 256), = 7 (mod 8)
+	 * 543 = 31 (mod 256), = 7 (mod 8)
+	 * 511 = 255 (mod 256), = 7 (mod 8)
+	 *
+	 * This exercises several branches when there are special cases
+	 * for integral numbers of 4-byte words, integral numbers of
+	 * 64-byte blocks, and integral numbers of 256-byte chunks.
+	 */
+
+	(*ci->ci_xchacha_stream)(c, 608, 0, nonce, k, 20);
+	for (i = 0; i < 608; i++)
+		c[i] ^= p[i];
+	if (memcmp(c, expected, 608)) {
+		for (i = 0; i < 608; i++)
+			c[i] ^= p[i];
+		hexdump(printf, "xchacha_stream", c, 608);
+		for (i = 0; i < 608; i++)
+			c[i] = expected[i] ^ p[i];
+		hexdump(printf, "expected", c, 608);
+		result = -1;
+	}
+
+	(*ci->ci_xchacha_stream)(c, 607, 0, nonce, k, 20);
+	for (i = 0; i < 607; i++)
+		c[i] ^= p[i];
+	if (memcmp(c, expected, 607)) {
+		for (i = 0; i < 607; i++)
+			c[i] ^= p[i];
+		hexdump(printf, "xchacha_stream", c, 607);
+		for (i = 0; i < 607; i++)
+			c[i] = expected[i] ^ p[i];
+		hexdump(printf, "expected", c, 607);
+		result = -1;
+	}
+
+	(*ci->ci_xchacha_stream)(c, 543, 0, nonce, k, 20);
+	for (i = 0; i < 543; i++)
+		c[i] ^= p[i];
+	if (memcmp(c, expected, 543)) {
+		for (i = 0; i < 543; i++)
+			c[i] ^= p[i];
+		hexdump(printf, "xchacha_stream", c, 543);
+		for (i = 0; i < 543; i++)
+			c[i] = expected[i] ^ p[i];
+		hexdump(printf, "expected", c, 543);
+		result = -1;
+	}
+
+	(*ci->ci_xchacha_stream)(c, 511, 0, nonce, k, 20);
+	for (i = 0; i < 511; i++)
+		c[i] ^= p[i];
+	if (memcmp(c, expected, 511)) {
+		for (i = 0; i < 511; i++)
+			c[i] ^= p[i];
+		hexdump(printf, "xchacha_stream", c, 511);
+		for (i = 0; i < 511; i++)
+			c[i] = expected[i] ^ p[i];
+		hexdump(printf, "expected", c, 511);
+		result = -1;
+	}
+
+	(*ci->ci_xchacha_stream)(c, 63, 0, nonce, k, 20);
+	for (i = 0; i < 63; i++)
+		c[i] ^= p[i];
+	if (memcmp(c, expected, 63)) {
+		for (i = 0; i < 63; i++)
+			c[i] ^= p[i];
+		hexdump(printf, "xchacha_stream", c, 63);
+		for (i = 0; i < 63; i++)
+			c[i] = expected[i] ^ p[i];
+		hexdump(printf, "expected", c, 63);
+		result = -1;
+	}
+
+	(*ci->ci_xchacha_stream_xor)(c, p, 608, 0, nonce, k, 20);
+	if (memcmp(c, expected, 608)) {
+		hexdump(printf, "xchacha_stream_xor", c, 608);
+		hexdump(printf, "expected", expected, 608);
+		result = -1;
+	}
+
+	memset(c, 0, sizeof c);
+	(*ci->ci_xchacha_stream_xor)(c, p, 607, 0, nonce, k, 20);
+	if (memcmp(c, expected, 607)) {
+		hexdump(printf, "xchacha_stream_xor", c, 607);
+		hexdump(printf, "expected", expected, 607);
+		result = -1;
+	}
+
+	memset(c, 0, sizeof c);
+	(*ci->ci_xchacha_stream_xor)(c, p, 543, 0, nonce, k, 20);
+	if (memcmp(c, expected, 543)) {
+		hexdump(printf, "xchacha_stream_xor", c, 543);
+		hexdump(printf, "expected", expected, 543);
+		result = -1;
+	}
+
+	memset(c, 0, sizeof c);
+	(*ci->ci_xchacha_stream_xor)(c, p, 511, 0, nonce, k, 20);
+	if (memcmp(c, expected, 511)) {
+		hexdump(printf, "xchacha_stream_xor", c, 511);
+		hexdump(printf, "expected", expected, 511);
+		result = -1;
+	}
+
+	memset(c, 0, sizeof c);
+	(*ci->ci_xchacha_stream_xor)(c, p, 63, 0, nonce, k, 20);
+	if (memcmp(c, expected, 63)) {
+		hexdump(printf, "xchacha_stream_xor", c, 63);
+		hexdump(printf, "expected", expected, 63);
+		result = -1;
+	}
+
+	return result;
+}
+
+int
+chacha_selftest(const struct chacha_impl *ci)
+{
+	int result = 0;
+
+	result |= chacha_core_selftest(ci);
+	result |= chacha_stream_selftest(ci);
+	result |= hchacha_selftest(ci);
+	result |= xchacha_stream_selftest(ci);
+
+	return result;
+}
Index: src/sys/crypto/chacha/files.chacha
diff -u /dev/null src/sys/crypto/chacha/files.chacha:1.1
--- /dev/null	Sat Jul 25 22:46:35 2020
+++ src/sys/crypto/chacha/files.chacha	Sat Jul 25 22:46:35 2020
@@ -0,0 +1,7 @@
+#	$NetBSD: files.chacha,v 1.1 2020/07/25 22:46:35 riastradh Exp $
+
+define	chacha
+
+file	crypto/chacha/chacha_impl.c			chacha
+file	crypto/chacha/chacha_ref.c			chacha
+file	crypto/chacha/chacha_selftest.c			chacha

Reply via email to