Module Name: src
Committed By: martin
Date: Mon May 18 18:54:30 UTC 2020
Modified Files:
src/sys/arch/arm/dts [netbsd-9]: rk3399-pinebook-pro.dts
rk3399-rockpro64.dts
src/sys/arch/arm/rockchip [netbsd-9]: files.rockchip rk3399_cru.c
src/sys/arch/evbarm/conf [netbsd-9]: GENERIC64
Added Files:
src/sys/arch/arm/dts [netbsd-9]: rk3399-crypto.dtsi
src/sys/arch/arm/rockchip [netbsd-9]: rk_v1crypto.c rk_v1crypto.h
Log Message:
Pull up following revision(s) (requested by riastradh in ticket #913):
sys/arch/arm/dts/rk3399-crypto.dtsi: revision 1.1
sys/arch/arm/rockchip/rk_v1crypto.c: revision 1.1
sys/arch/arm/rockchip/rk_v1crypto.c: revision 1.2 (plus patch)
sys/arch/arm/rockchip/rk_v1crypto.h: revision 1.1
sys/arch/arm/dts/rk3399-pinebook-pro.dts: revision 1.3
sys/arch/arm/rockchip/rk3399_cru.c: revision 1.20
sys/arch/evbarm/conf/GENERIC64: revision 1.158
sys/arch/arm/dts/rk3399-rockpro64.dts: revision 1.11
sys/arch/arm/rockchip/files.rockchip: revision 1.24
Rockchip crypto engine RNG driver.
As found on the rk3288 and rk3399. This driver only supports the
TRNG, not the rest of the crypto engine, although it uses the AES unit
to do a self-test at attach time to verify that the engine works.
There seem to be two versions of the Rockchip crypto engine, v1 and
v2; this one is for v1. Can't name a driver `rkcryptov1' so we'll
clumsily call it `rkv1crypto' instead to leave room for `rkv2crypto'
later on.
The crypto binding derived from the Rockchip BSP Linux kernel, in the
location it appears on the rk3399, is in rk3399-crypto.dtsi, since
there doesn't seem to be a better place to put it at the moment among
this twisty maze of inclusions, all different.
Use rnd_add_data_sync from the callback.
(Doesn't make a difference in HEAD but this is the stated API
contract and it matters if we want to pull this up.)
Prime the pool on attach.
To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1.2.2 src/sys/arch/arm/dts/rk3399-crypto.dtsi
cvs rdiff -u -r1.2.4.2 -r1.2.4.3 src/sys/arch/arm/dts/rk3399-pinebook-pro.dts
cvs rdiff -u -r1.7.2.2 -r1.7.2.3 src/sys/arch/arm/dts/rk3399-rockpro64.dts
cvs rdiff -u -r1.19.2.3 -r1.19.2.4 src/sys/arch/arm/rockchip/files.rockchip
cvs rdiff -u -r1.8.4.3 -r1.8.4.4 src/sys/arch/arm/rockchip/rk3399_cru.c
cvs rdiff -u -r0 -r1.2.2.2 src/sys/arch/arm/rockchip/rk_v1crypto.c
cvs rdiff -u -r0 -r1.1.2.2 src/sys/arch/arm/rockchip/rk_v1crypto.h
cvs rdiff -u -r1.103.2.11 -r1.103.2.12 src/sys/arch/evbarm/conf/GENERIC64
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/arm/dts/rk3399-pinebook-pro.dts
diff -u src/sys/arch/arm/dts/rk3399-pinebook-pro.dts:1.2.4.2 src/sys/arch/arm/dts/rk3399-pinebook-pro.dts:1.2.4.3
--- src/sys/arch/arm/dts/rk3399-pinebook-pro.dts:1.2.4.2 Tue Jan 21 10:39:59 2020
+++ src/sys/arch/arm/dts/rk3399-pinebook-pro.dts Mon May 18 18:54:30 2020
@@ -12,6 +12,7 @@
#include <dt-bindings/pinctrl/rockchip.h>
#include "rk3399.dtsi"
#include "rk3399-opp.dtsi"
+#include "rk3399-crypto.dtsi"
/ {
model = "Pine64 Pinebook Pro";
Index: src/sys/arch/arm/dts/rk3399-rockpro64.dts
diff -u src/sys/arch/arm/dts/rk3399-rockpro64.dts:1.7.2.2 src/sys/arch/arm/dts/rk3399-rockpro64.dts:1.7.2.3
--- src/sys/arch/arm/dts/rk3399-rockpro64.dts:1.7.2.2 Tue Jan 21 10:39:59 2020
+++ src/sys/arch/arm/dts/rk3399-rockpro64.dts Mon May 18 18:54:30 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: rk3399-rockpro64.dts,v 1.7.2.2 2020/01/21 10:39:59 martin Exp $ */
+/* $NetBSD: rk3399-rockpro64.dts,v 1.7.2.3 2020/05/18 18:54:30 martin Exp $ */
/*-
* Copyright (c) 2019 Jared McNeill <[email protected]>
@@ -27,6 +27,7 @@
*/
#include "../../../external/gpl2/dts/dist/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts"
+#include "rk3399-crypto.dtsi"
/ {
pwm-fan {
@@ -147,7 +148,6 @@
status = "okay";
};
#endif
-
};
&pinctrl {
Index: src/sys/arch/arm/rockchip/files.rockchip
diff -u src/sys/arch/arm/rockchip/files.rockchip:1.19.2.3 src/sys/arch/arm/rockchip/files.rockchip:1.19.2.4
--- src/sys/arch/arm/rockchip/files.rockchip:1.19.2.3 Tue Jan 21 10:39:59 2020
+++ src/sys/arch/arm/rockchip/files.rockchip Mon May 18 18:54:30 2020
@@ -1,4 +1,4 @@
-# $NetBSD: files.rockchip,v 1.19.2.3 2020/01/21 10:39:59 martin Exp $
+# $NetBSD: files.rockchip,v 1.19.2.4 2020/05/18 18:54:30 martin Exp $
#
# Configuration info for Rockchip family SoCs
#
@@ -112,6 +112,11 @@ device rki2s
attach rki2s at fdt with rk_i2s
file arch/arm/rockchip/rk_i2s.c rk_i2s
+# Crypto engine v1
+device rkv1crypto
+attach rkv1crypto at fdt with rk_v1crypto
+file arch/arm/rockchip/rk_v1crypto.c rk_v1crypto
+
# SOC parameters
defflag opt_soc.h SOC_ROCKCHIP
defflag opt_soc.h SOC_RK3328: SOC_ROCKCHIP
Index: src/sys/arch/arm/rockchip/rk3399_cru.c
diff -u src/sys/arch/arm/rockchip/rk3399_cru.c:1.8.4.3 src/sys/arch/arm/rockchip/rk3399_cru.c:1.8.4.4
--- src/sys/arch/arm/rockchip/rk3399_cru.c:1.8.4.3 Tue Jan 21 10:39:59 2020
+++ src/sys/arch/arm/rockchip/rk3399_cru.c Mon May 18 18:54:30 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: rk3399_cru.c,v 1.8.4.3 2020/01/21 10:39:59 martin Exp $ */
+/* $NetBSD: rk3399_cru.c,v 1.8.4.4 2020/05/18 18:54:30 martin Exp $ */
/*-
* Copyright (c) 2018 Jared McNeill <[email protected]>
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: rk3399_cru.c,v 1.8.4.3 2020/01/21 10:39:59 martin Exp $");
+__KERNEL_RCSID(1, "$NetBSD: rk3399_cru.c,v 1.8.4.4 2020/05/18 18:54:30 martin Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -844,6 +844,27 @@ static struct rk_cru_clk rk3399_cru_clks
0),
RK_MUX(RK3399_SCLK_PCIE_CORE, "clk_pcie_core", mux_pciecore_cru_phy_parents, CLKSEL_CON(18), __BIT(7)),
+ /* Crypto */
+ RK_COMPOSITE(RK3399_SCLK_CRYPTO0, "clk_crypto0", mux_pll_src_cpll_gpll_ppll_parents,
+ CLKSEL_CON(24), /* muxdiv_reg */
+ __BITS(7,6), /* mux_mask */
+ __BITS(4,0), /* div_mask */
+ CLKGATE_CON(7), /* gate_reg */
+ __BIT(7), /* gate_mask */
+ RK_COMPOSITE_ROUND_DOWN /*???*/),
+ RK_COMPOSITE(RK3399_SCLK_CRYPTO1, "clk_crypto1", mux_pll_src_cpll_gpll_ppll_parents,
+ CLKSEL_CON(26), /* muxdiv_reg */
+ __BITS(7,6), /* mux_mask */
+ __BITS(4,0), /* div_mask */
+ CLKGATE_CON(8), /* gate_reg */
+ __BIT(7), /* gate_mask */
+ RK_COMPOSITE_ROUND_DOWN /*???*/),
+ RK_GATE(RK3399_HCLK_M_CRYPTO0, "hclk_m_crypto0", "pclk_perilp0", CLKGATE_CON(24), 5),
+ RK_GATE(RK3399_HCLK_S_CRYPTO0, "hclk_s_crypto0", "pclk_perilp0", CLKGATE_CON(24), 6),
+ RK_GATE(RK3399_HCLK_M_CRYPTO1, "hclk_m_crypto1", "pclk_perilp0", CLKGATE_CON(24), 14),
+ RK_GATE(RK3399_HCLK_S_CRYPTO1, "hclk_s_crypto1", "pclk_perilp0", CLKGATE_CON(24), 15),
+ RK_GATE(RK3399_ACLK_DMAC1_PERILP, "aclk_dmac1_perilp", "pclk_perilp", CLKGATE_CON(25), 6),
+
/* TSADC */
RK_COMPOSITE(RK3399_SCLK_TSADC, "clk_tsadc", mux_clk_tsadc_parents,
CLKSEL_CON(27), /* muxdiv_reg */
Index: src/sys/arch/evbarm/conf/GENERIC64
diff -u src/sys/arch/evbarm/conf/GENERIC64:1.103.2.11 src/sys/arch/evbarm/conf/GENERIC64:1.103.2.12
--- src/sys/arch/evbarm/conf/GENERIC64:1.103.2.11 Mon May 18 18:45:40 2020
+++ src/sys/arch/evbarm/conf/GENERIC64 Mon May 18 18:54:30 2020
@@ -1,5 +1,5 @@
#
-# $NetBSD: GENERIC64,v 1.103.2.11 2020/05/18 18:45:40 martin Exp $
+# $NetBSD: GENERIC64,v 1.103.2.12 2020/05/18 18:54:30 martin Exp $
#
# GENERIC ARM (aarch64) kernel
#
@@ -370,6 +370,7 @@ amdccp* at acpi?
bcmrng* at fdt? # Broadcom BCM283x RNG
mesonrng* at fdt? # Amlogic Meson RNG
sun8icrypto* at fdt? # Allwinner Crypto Engine
+rkv1crypto* at fdt? # Rockchip Crypto v1
# RTC
plrtc* at fdt? # ARM PrimeCell RTC
Added files:
Index: src/sys/arch/arm/dts/rk3399-crypto.dtsi
diff -u /dev/null src/sys/arch/arm/dts/rk3399-crypto.dtsi:1.1.2.2
--- /dev/null Mon May 18 18:54:30 2020
+++ src/sys/arch/arm/dts/rk3399-crypto.dtsi Mon May 18 18:54:30 2020
@@ -0,0 +1,41 @@
+/* $NetBSD: rk3399-crypto.dtsi,v 1.1.2.2 2020/05/18 18:54:30 martin 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 AUTHOR ``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 AUTHOR 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.
+ */
+
+/ {
+ crypto: crypto@ff8b8000 {
+ compatible = "rockchip,rk3288-crypto";
+ reg = <0x0 0xff8b8000 0x0 0x1000>;
+ clocks = <&cru HCLK_M_CRYPTO1>, <&cru HCLK_S_CRYPTO1>,
+ <&cru SCLK_CRYPTO1>, <&cru ACLK_DMAC1_PERILP>;
+ clock-names = "aclk", "hclk", "sclk", "apb_pclk";
+ assigned-clocks = <&cru SCLK_CRYPTO1>, <&cru HCLK_S_CRYPTO1>;
+ assigned-clock-rates = <150000000>, <100000000>;
+ resets = <&cru SRST_CRYPTO1>;
+ reset-names = "crypto-rst";
+ };
+};
Index: src/sys/arch/arm/rockchip/rk_v1crypto.c
diff -u /dev/null src/sys/arch/arm/rockchip/rk_v1crypto.c:1.2.2.2
--- /dev/null Mon May 18 18:54:30 2020
+++ src/sys/arch/arm/rockchip/rk_v1crypto.c Mon May 18 18:54:30 2020
@@ -0,0 +1,388 @@
+/* $NetBSD: rk_v1crypto.c,v 1.2.2.2 2020/05/18 18:54:30 martin Exp $ */
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Taylor R. Campbell.
+ *
+ * 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.
+ */
+
+/*
+ * rk_v1crypto -- Rockchip crypto v1 driver
+ *
+ * This is just the RNG for now.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(1, "$NetBSD: rk_v1crypto.c,v 1.2.2.2 2020/05/18 18:54:30 martin Exp $");
+
+#include <sys/types.h>
+
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/errno.h>
+#include <sys/mutex.h>
+#include <sys/rndpool.h>
+#include <sys/rndsource.h>
+#include <sys/sysctl.h>
+
+#include <dev/fdt/fdtvar.h>
+
+#include <arm/rockchip/rk_v1crypto.h>
+
+struct rk_v1crypto_softc {
+ device_t sc_dev;
+ bus_space_tag_t sc_bst;
+ bus_space_handle_t sc_bsh;
+ kmutex_t sc_lock;
+ struct krndsource sc_rndsource;
+ struct rk_v1crypto_sysctl {
+ struct sysctllog *cy_log;
+ const struct sysctlnode *cy_root_node;
+ } sc_sysctl;
+};
+
+static int rk_v1crypto_match(device_t, cfdata_t, void *);
+static void rk_v1crypto_attach(device_t, device_t, void *);
+static int rk_v1crypto_selftest(struct rk_v1crypto_softc *);
+static void rk_v1crypto_rndsource_attach(struct rk_v1crypto_softc *);
+static void rk_v1crypto_rng_get(size_t, void *);
+static void rk_v1crypto_sysctl_attach(struct rk_v1crypto_softc *);
+static int rk_v1crypto_sysctl_rng(SYSCTLFN_ARGS);
+static int rk_v1crypto_rng(struct rk_v1crypto_softc *,
+ uint32_t[static RK_V1CRYPTO_TRNG_NOUT]);
+
+static uint32_t
+RKC_READ(struct rk_v1crypto_softc *sc, bus_addr_t reg)
+{
+ return bus_space_read_4(sc->sc_bst, sc->sc_bsh, reg);
+}
+
+static void
+RKC_WRITE(struct rk_v1crypto_softc *sc, bus_addr_t reg, uint32_t v)
+{
+ return bus_space_write_4(sc->sc_bst, sc->sc_bsh, reg, v);
+}
+
+static inline void
+RKC_CTRL(struct rk_v1crypto_softc *sc, uint16_t m, uint16_t v)
+{
+ uint32_t c = 0;
+
+ c |= __SHIFTIN(m, RK_V1CRYPTO_CTRL_MASK);
+ c |= __SHIFTIN(v, m);
+ RKC_WRITE(sc, RK_V1CRYPTO_CTRL, c);
+}
+
+CFATTACH_DECL_NEW(rk_v1crypto, sizeof(struct rk_v1crypto_softc),
+ rk_v1crypto_match, rk_v1crypto_attach, NULL, NULL);
+
+static const struct of_compat_data compat_data[] = {
+ {"rockchip,rk3288-crypto", 0},
+ {NULL}
+};
+
+static int
+rk_v1crypto_match(device_t parent, cfdata_t cf, void *aux)
+{
+ const struct fdt_attach_args *const faa = aux;
+
+ return of_match_compat_data(faa->faa_phandle, compat_data);
+}
+
+static void
+rk_v1crypto_attach(device_t parent, device_t self, void *aux)
+{
+ static const char *const clks[] = {"aclk", "hclk", "sclk", "apb_pclk"};
+ struct rk_v1crypto_softc *const sc = device_private(self);
+ const struct fdt_attach_args *const faa = aux;
+ bus_addr_t addr;
+ bus_size_t size;
+ const int phandle = faa->faa_phandle;
+ struct fdtbus_reset *rst;
+ unsigned i;
+ uint32_t ctrl;
+
+ fdtbus_clock_assign(phandle);
+
+ sc->sc_dev = self;
+ sc->sc_bst = faa->faa_bst;
+ mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
+
+ /* Get and map device registers. */
+ if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
+ aprint_error(": couldn't get registers\n");
+ return;
+ }
+ if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
+ aprint_error(": couldn't map registers\n");
+ return;
+ }
+
+ /* Enable the clocks. */
+ for (i = 0; i < __arraycount(clks); i++) {
+ if (fdtbus_clock_enable(phandle, clks[i], true) != 0) {
+ aprint_error(": couldn't enable %s clock\n", clks[i]);
+ return;
+ }
+ }
+
+ /* Get a reset handle if we need and try to deassert it. */
+ if ((rst = fdtbus_reset_get_index(phandle, 0)) != NULL) {
+ if (fdtbus_reset_deassert(rst) != 0) {
+ aprint_error(": couldn't de-assert reset\n");
+ return;
+ }
+ }
+
+ aprint_naive("\n");
+ aprint_normal(": Crypto v1\n");
+
+ /*
+ * Enable ring oscillator to start gathering entropy, and set
+ * up the crypto clock to sample it once every 100 cycles.
+ *
+ * The ring oscillator can run even when the clock is gated or
+ * flush is asserted, and the longer we run it, the less it
+ * will be synchronized with the main clock owing to jitter
+ * ideally from unpredictable thermal noise.
+ */
+ ctrl = RK_V1CRYPTO_TRNG_CTRL_OSC_ENABLE;
+ ctrl |= __SHIFTIN(100, RK_V1CRYPTO_TRNG_CTRL_CYCLES);
+ RKC_WRITE(sc, RK_V1CRYPTO_TRNG_CTRL, ctrl);
+
+ if (rk_v1crypto_selftest(sc))
+ return;
+ rk_v1crypto_rndsource_attach(sc);
+ rk_v1crypto_sysctl_attach(sc);
+}
+
+static int
+rk_v1crypto_selftest(struct rk_v1crypto_softc *sc)
+{
+ static const uint32_t key[4] = {0};
+ static const uint32_t input[4] = {0};
+ static const uint32_t expected[4] = {
+ 0x66e94bd4, 0xef8a2c3b, 0x884cfa59, 0xca342b2e,
+ };
+ uint32_t output[4];
+ uint32_t ctrl;
+ unsigned i, timo;
+
+ /* Program the key and input block. */
+ for (i = 0; i < 4; i++)
+ RKC_WRITE(sc, RK_V1CRYPTO_AES_DIN(i), key[i]);
+ for (i = 0; i < 4; i++)
+ RKC_WRITE(sc, RK_V1CRYPTO_AES_DIN(i), input[i]);
+
+ /*
+ * Set up the AES unit to do AES-128 `ECB' (i.e., just the raw
+ * AES permutation) in the encryption direction.
+ */
+ ctrl = 0;
+ ctrl |= RK_V1CRYPTO_AES_CTRL_KEYCHANGE;
+ ctrl |= __SHIFTIN(RK_V1CRYPTO_AES_CTRL_MODE_ECB,
+ RK_V1CRYPTO_AES_CTRL_MODE);
+ ctrl |= __SHIFTIN(RK_V1CRYPTO_AES_CTRL_KEYSIZE_128,
+ RK_V1CRYPTO_AES_CTRL_KEYSIZE);
+ ctrl |= __SHIFTIN(RK_V1CRYPTO_AES_CTRL_DIR_ENC,
+ RK_V1CRYPTO_AES_CTRL_DIR);
+ RKC_WRITE(sc, RK_V1CRYPTO_AES_CTRL, ctrl);
+
+ /* Kick it off. */
+ RKC_CTRL(sc, RK_V1CRYPTO_CTRL_AES_START, 1);
+
+ /* Wait up to 1ms for it to complete. */
+ timo = 1000;
+ while (RKC_READ(sc, RK_V1CRYPTO_CTRL) & RK_V1CRYPTO_CTRL_AES_START) {
+ if (--timo == 0) {
+ device_printf(sc->sc_dev, "AES self-test timed out\n");
+ return -1;
+ }
+ DELAY(1);
+ }
+
+ /* Read the output. */
+ for (i = 0; i < 4; i++)
+ output[i] = RKC_READ(sc, RK_V1CRYPTO_AES_DOUT(i));
+
+ /* Verify the output. */
+ for (i = 0; i < 4; i++) {
+ if (output[i] != expected[i]) {
+ device_printf(sc->sc_dev, "AES self-test failed\n");
+ return -1;
+ }
+ }
+
+ /* Success! */
+ return 0;
+}
+
+static void
+rk_v1crypto_rndsource_attach(struct rk_v1crypto_softc *sc)
+{
+ device_t self = sc->sc_dev;
+
+ rndsource_setcb(&sc->sc_rndsource, rk_v1crypto_rng_get, sc);
+ rnd_attach_source(&sc->sc_rndsource, device_xname(self),
+ RND_TYPE_RNG, RND_FLAG_DEFAULT|RND_FLAG_HASCB);
+ rk_v1crypto_rng_get(RND_POOLBITS/NBBY, sc);
+}
+
+static void
+rk_v1crypto_rng_get(size_t nbytes, void *cookie)
+{
+ struct rk_v1crypto_softc *sc = cookie;
+ device_t self = sc->sc_dev;
+ uint32_t buf[RK_V1CRYPTO_TRNG_NOUT];
+ uint32_t entropybits = NBBY*sizeof(buf)/2; /* be conservative */
+ unsigned n = RK_V1CRYPTO_TRNG_NOUT;
+ int error;
+ size_t nbits = NBBY*nbytes;
+
+ while (nbits) {
+ CTASSERT((RK_V1CRYPTO_TRNG_NOUT % 2) == 0);
+
+ error = rk_v1crypto_rng(sc, buf);
+ if (error) {
+ device_printf(self, "timed out\n");
+ break;
+ }
+ if (consttime_memequal(buf, buf + n/2, n/2)) {
+ device_printf(self, "failed repeated output test\n");
+ break;
+ }
+ rnd_add_data_sync(&sc->sc_rndsource, buf, sizeof buf,
+ entropybits);
+ nbits -= MIN(nbits, MAX(1, entropybits));
+ }
+ explicit_memset(buf, 0, sizeof buf);
+}
+
+static void
+rk_v1crypto_sysctl_attach(struct rk_v1crypto_softc *sc)
+{
+ device_t self = sc->sc_dev;
+ struct rk_v1crypto_sysctl *cy = &sc->sc_sysctl;
+ int error;
+
+ /* hw.rkv1cryptoN (node) */
+ error = sysctl_createv(&cy->cy_log, 0, NULL, &cy->cy_root_node,
+ CTLFLAG_PERMANENT, CTLTYPE_NODE, device_xname(self),
+ SYSCTL_DESCR("rk crypto v1 engine knobs"),
+ NULL, 0, NULL, 0,
+ CTL_HW, CTL_CREATE, CTL_EOL);
+ if (error) {
+ aprint_error_dev(self,
+ "failed to set up sysctl hw.%s: %d\n",
+ device_xname(self), error);
+ return;
+ }
+
+ /* hw.rkv1cryptoN.rng (`struct', 32-byte array) */
+ sysctl_createv(&cy->cy_log, 0, &cy->cy_root_node, NULL,
+ CTLFLAG_PERMANENT|CTLFLAG_READONLY|CTLFLAG_PRIVATE, CTLTYPE_STRUCT,
+ "rng", SYSCTL_DESCR("Read up to 32 bytes out of the TRNG"),
+ &rk_v1crypto_sysctl_rng, 0, sc, 0, CTL_CREATE, CTL_EOL);
+ if (error) {
+ aprint_error_dev(self,
+ "failed to set up sysctl hw.%s.rng: %d\n",
+ device_xname(self), error);
+ return;
+ }
+}
+
+static int
+rk_v1crypto_sysctl_rng(SYSCTLFN_ARGS)
+{
+ uint32_t buf[RK_V1CRYPTO_TRNG_NOUT];
+ struct sysctlnode node = *rnode;
+ struct rk_v1crypto_softc *sc = node.sysctl_data;
+ size_t size;
+ int error;
+
+ /* If oldp == NULL, the caller wants to learn the size. */
+ if (oldp == NULL) {
+ *oldlenp = sizeof buf;
+ return 0;
+ }
+
+ /* Verify the output buffer size is reasonable. */
+ size = *oldlenp;
+ if (size > sizeof buf) /* size_t, so never negative */
+ return E2BIG;
+ if (size == 0)
+ return 0; /* nothing to do */
+
+ /* Generate data. */
+ error = rk_v1crypto_rng(sc, buf);
+ if (error)
+ return error;
+
+ /* Copy out the data. */
+ node.sysctl_data = buf;
+ node.sysctl_size = size;
+ error = sysctl_lookup(SYSCTLFN_CALL(&node));
+
+ /* Clear the buffer. */
+ explicit_memset(buf, 0, sizeof buf);
+
+ /* Return the sysctl_lookup error, if any. */
+ return error;
+}
+
+static int
+rk_v1crypto_rng(struct rk_v1crypto_softc *sc,
+ uint32_t buf[static RK_V1CRYPTO_TRNG_NOUT])
+{
+ unsigned i, timo;
+ int error;
+
+ /* Acquire lock to serialize access to TRNG. */
+ mutex_enter(&sc->sc_lock);
+
+ /*
+ * Query TRNG and wait up to 1ms for it to post. Empirically,
+ * this takes around 120us.
+ */
+ RKC_CTRL(sc, RK_V1CRYPTO_CTRL_TRNG_START, 1);
+ timo = 1000;
+ while (RKC_READ(sc, RK_V1CRYPTO_CTRL) & RK_V1CRYPTO_CTRL_TRNG_START) {
+ if (--timo == 0) {
+ error = ETIMEDOUT;
+ goto out;
+ }
+ DELAY(1);
+ }
+
+ /* Read out the data. */
+ for (i = 0; i < RK_V1CRYPTO_TRNG_NOUT; i++)
+ buf[i] = RKC_READ(sc, RK_V1CRYPTO_TRNG_DOUT(i));
+
+ /* Success! */
+ error = 0;
+out: mutex_exit(&sc->sc_lock);
+ return error;
+}
Index: src/sys/arch/arm/rockchip/rk_v1crypto.h
diff -u /dev/null src/sys/arch/arm/rockchip/rk_v1crypto.h:1.1.2.2
--- /dev/null Mon May 18 18:54:30 2020
+++ src/sys/arch/arm/rockchip/rk_v1crypto.h Mon May 18 18:54:30 2020
@@ -0,0 +1,178 @@
+/* $NetBSD: rk_v1crypto.h,v 1.1.2.2 2020/05/18 18:54:30 martin Exp $ */
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Taylor R. Campbell.
+ *
+ * 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 _ARM_ROCKCHIP_RK_V1CRYPTO_H
+#define _ARM_ROCKCHIP_RK_V1CRYPTO_H
+
+#define RK_V1CRYPTO_INTSTS 0x0000 /* Interrupt Status */
+#define RK_V1CRYPTO_INTSTS_PKA_DONE __BIT(5)
+#define RK_V1CRYPTO_INTSTS_HASH_DONE __BIT(4)
+#define RK_V1CRYPTO_INTSTS_HRDMA_ERR __BIT(3)
+#define RK_V1CRYPTO_INTSTS_HRDMA_DONE __BIT(2)
+#define RK_V1CRYPTO_INTSTS_BCDMA_ERR __BIT(1)
+#define RK_V1CRYPTO_INTSTS_BCDMA_DONE __BIT(0)
+
+#define RK_V1CRYPTO_INTENA 0x0004 /* Interrupt Enable */
+#define RK_V1CRYPTO_INTENA_PKA_DONE __BIT(5)
+#define RK_V1CRYPTO_INTENA_HASH_DONE __BIT(4)
+#define RK_V1CRYPTO_INTENA_HRDMA_ERR __BIT(3)
+#define RK_V1CRYPTO_INTENA_HRDMA_DONE __BIT(2)
+#define RK_V1CRYPTO_INTENA_BCDMA_ERR __BIT(1)
+#define RK_V1CRYPTO_INTENA_BCDMA_DONE __BIT(0)
+
+#define RK_V1CRYPTO_CTRL 0x0008 /* Control */
+#define RK_V1CRYPTO_CTRL_MASK __BITS(31,16)
+#define RK_V1CRYPTO_CTRL_TRNG_FLUSH __BIT(9)
+#define RK_V1CRYPTO_CTRL_TRNG_START __BIT(8)
+#define RK_V1CRYPTO_CTRL_PKA_FLUSH __BIT(7)
+#define RK_V1CRYPTO_CTRL_HASH_FLUSH __BIT(6)
+#define RK_V1CRYPTO_CTRL_BLOCK_FLUSH __BIT(5)
+#define RK_V1CRYPTO_CTRL_PKA_START __BIT(4)
+#define RK_V1CRYPTO_CTRL_HASH_START __BIT(3)
+#define RK_V1CRYPTO_CTRL_BLOCK_START __BIT(2)
+#define RK_V1CRYPTO_CTRL_TDES_START __BIT(1)
+#define RK_V1CRYPTO_CTRL_AES_START __BIT(0)
+
+#define RK_V1CRYPTO_CONF 0x000c /* ? */
+#define RK_V1CRYPTO_CONF_HR_ADDR_MODE __BIT(8)
+#define RK_V1CRYPTO_CONF_BT_ADDR_MODE __BIT(7)
+#define RK_V1CRYPTO_CONF_BR_ADDR_MODE __BIT(6)
+#define RK_V1CRYPTO_CONF_MODE_FIX 1
+#define RK_V1CRYPTO_CONF_MODE_INCR 0
+#define RK_V1CRYPTO_CONF_BYTESWAP_HRFIFO __BIT(5)
+#define RK_V1CRYPTO_CONF_BYTESWAP_BTFIFO __BIT(4)
+#define RK_V1CRYPTO_CONF_BYTESWAP_BRFIFO __BIT(3)
+#define RK_V1CRYPTO_CONF_DESSEL __BIT(2)
+#define RK_V1CRYPTO_CONF_DESSEL_AES 0
+#define RK_V1CRYPTO_CONF_DESSEL_DES 1 /* 3DES? */
+#define RK_V1CRYPTO_CONF_HASHINSEL __BITS(1,0)
+#define RK_V1CRYPTO_CONF_HASHINSEL_INDEP 0
+#define RK_V1CRYPTO_CONF_HASHINSEL_BLKIN 1
+#define RK_V1CRYPTO_CONF_HASHINSEL_BLKOUT 2
+
+#define RK_V1CRYPTO_BRDMAS 0x0010 /* Block Rx DMA Start */
+#define RK_V1CRYPTO_BTDMAS 0x0014 /* Block Tx DMA Start */
+#define RK_V1CRYPTO_BRDMAL 0x0018 /* Block Rx DMA Length */
+#define RK_V1CRYPTO_BTDMAL 0x0020 /* Block Tx DMA Length */
+#define RK_V1CRYPTO_HRDMAS 0x001c /* Hash Rx DMA Start */
+#define RK_V1CRYPTO_HRDMAL 0x0020 /* Hash Rx DMA Length */
+
+#define RK_V1CRYPTO_AES_CTRL 0x0080 /* AES Control */
+#define RK_V1CRYPTO_AES_CTRL_BYTESWAP_CNT __BIT(11)
+#define RK_V1CRYPTO_AES_CTRL_BYTESWAP_KEY __BIT(10)
+#define RK_V1CRYPTO_AES_CTRL_BYTESWAP_IV __BIT(9)
+#define RK_V1CRYPTO_AES_CTRL_BYTESWAP_DO __BIT(8)
+#define RK_V1CRYPTO_AES_CTRL_BYTESWAP_DI __BIT(7)
+#define RK_V1CRYPTO_AES_CTRL_KEYCHANGE __BIT(6)
+#define RK_V1CRYPTO_AES_CTRL_MODE __BITS(5,4)
+#define RK_V1CRYPTO_AES_CTRL_MODE_ECB 0
+#define RK_V1CRYPTO_AES_CTRL_MODE_CBC 1
+#define RK_V1CRYPTO_AES_CTRL_MODE_CTR 2
+#define RK_V1CRYPTO_AES_CTRL_KEYSIZE __BITS(3,2)
+#define RK_V1CRYPTO_AES_CTRL_KEYSIZE_128 0
+#define RK_V1CRYPTO_AES_CTRL_KEYSIZE_192 1
+#define RK_V1CRYPTO_AES_CTRL_KEYSIZE_256 2
+#define RK_V1CRYPTO_AES_CTRL_FIFOMODE __BIT(1)
+#define RK_V1CRYPTO_AES_CTRL_DIR __BIT(0)
+#define RK_V1CRYPTO_AES_CTRL_DIR_ENC 0
+#define RK_V1CRYPTO_AES_CTRL_DIR_DEC 1
+
+#define RK_V1CRYPTO_AES_STS 0x0084 /* AES Status */
+#define RK_V1CRYPTO_AES_STS_DONE __BIT(0)
+
+#define RK_V1CRYPTO_AES_DIN(n) (0x0088 + 4*(n)) /* AES Input */
+#define RK_V1CRYPTO_AES_DOUT(n) (0x0098 + 4*(n)) /* AES Output */
+#define RK_V1CRYPTO_AES_IV(n) (0x00a8 + 4*(n)) /* AES IV */
+#define RK_V1CRYPTO_AES_KEY(n) (0x00b8 + 4*(n)) /* AES Key */
+#define RK_V1CRYPTO_AES_CNT(n) (0x00d8 + 4*(n)) /* AES Input Counter */
+
+#define RK_V1CRYPTO_TDES_CTRL 0x0100 /* 3DES Control */
+#define RK_V1CRYPTO_TDES_CTRL_BYTESWAP_KEY __BIT(8)
+#define RK_V1CRYPTO_TDES_CTRL_BYTESWAP_IV __BIT(7)
+#define RK_V1CRYPTO_TDES_CTRL_BYTESWAP_DO __BIT(6)
+#define RK_V1CRYPTO_TDES_CTRL_BYTESWAP_DI __BIT(5)
+#define RK_V1CRYPTO_TDES_CTRL_MODE __BIT(4)
+#define RK_V1CRYPTO_TDES_CTRL_MODE_ECB 0
+#define RK_V1CRYPTO_TDES_CTRL_MODE_CBC 1
+#define RK_V1CRYPTO_TDES_CTRL_KEYMODE __BIT(3)
+#define RK_V1CRYPTO_TDES_CTRL_KEYMODE_EDE 0
+#define RK_V1CRYPTO_TDES_CTRL_KEYMODE_EEE 1
+#define RK_V1CRYPTO_TDES_CTRL_SELECT __BIT(2)
+#define RK_V1CRYPTO_TDES_CTRL_SELECT_DES 0
+#define RK_V1CRYPTO_TDES_CTRL_SELECT_TDES 1
+#define RK_V1CRYPTO_TDES_CTRL_FIFOMODE __BIT(1)
+#define RK_V1CRYPTO_TDES_CTRL_DIR __BIT(0)
+#define RK_V1CRYPTO_TDES_CTRL_DIR_ENC 0
+#define RK_V1CRYPTO_TDES_CTRL_DIR_DEC 1
+
+#define RK_V1CRYPTO_TDES_STS 0x0104 /* 3DES Status */
+#define RK_V1CRYPTO_TDES_STS_DONE __BIT(0)
+
+#define RK_V1CRYPTO_TDES_DIN(n) (0x0108 + 4*(n)) /* 3DES Input */
+#define RK_V1CRYPTO_TDES_DOUT(n)(0x0110 + 4*(n)) /* 3DES Output */
+#define RK_V1CRYPTO_TDES_IV(n) (0x0118 + 4*(n)) /* 3DES IV */
+#define RK_V1CRYPTO_TDES_KEY(n) (0x0120 + 4*(n)) /* 3DES Key(1,2,3) */
+
+#define RK_V1CRYPTO_HASH_CTRL 0x0180 /* Hash Control */
+#define RK_V1CRYPTO_HASH_SWAP_DO __BIT(3)
+#define RK_V1CRYPTO_HASH_SWAP_DI __BIT(2)
+#define RK_V1CRYPTO_HASH_SELECT __BITS(1,0)
+#define RK_V1CRYPTO_HASH_SELECT_SHA1 0
+#define RK_V1CRYPTO_HASH_SELECT_MD5 1
+#define RK_V1CRYPTO_HASH_SELECT_SHA256 2
+#define RK_V1CRYPTO_HASH_SELECT_PRNG 3 /* ??? */
+
+#define RK_V1CRYPTO_HASH_STS 0x0184 /* Hash Status */
+#define RK_V1CRYPTO_HASH_STS_DONE __BIT(0)
+
+#define RK_V1CRYPTO_HASH_MSG_LEN 0x0188 /* Hash Message Len */
+#define RK_V1CRYPTO_HASH_DOUT(n)(0x018c + 4*(n)) /* Hash Result */
+#define RK_V1CRYPTO_HASH_SEED(n)(0x01ac + 4*(n)) /* HMAC/PRNG key */
+
+#define RK_V1CRYPTO_TRNG_CTRL 0x0200 /* TRNG Control */
+#define RK_V1CRYPTO_TRNG_CTRL_OSC_ENABLE __BIT(16)
+#define RK_V1CRYPTO_TRNG_CTRL_CYCLES __BITS(15,0)
+
+#define RK_V1CRYPTO_TRNG_DOUT(n)(0x0204 + 4*(n)) /* TRNG Output */
+#define RK_V1CRYPTO_TRNG_NOUT 8 /* up to 8 32-bit */
+
+#define RK_V1CRYPTO_PKA_CTRL 0x0280 /* PKA Control (RSA?) */
+#define RK_V1CRYPTO_PKA_CTRL_SIZE __BITS(1,0)
+#define RK_V1CRYPTO_PKA_CTRL_SIZE_512 0
+#define RK_V1CRYPTO_PKA_CTRL_SIZE_1024 1
+#define RK_V1CRYPTO_PKA_CTRL_SIZE_2048 2
+
+#define RK_V1CRYPTO_M 0x0400 /* RSA `message' */
+#define RK_V1CRYPTO_C 0x0500 /* 2^(2 ceil(lg n) + 2) mod n */
+#define RK_V1CRYPTO_N 0x0600 /* RSA modulus? */
+#define RK_V1CRYPTO_E 0x0700 /* RSA exponent? */
+
+#endif /* _ARM_ROCKCHIP_RK_V1CRYPTO_H */