Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-9]: src/sys/arch Pull up following revision(s) (requested by rias...



details:   https://anonhg.NetBSD.org/src/rev/b51304b80af1
branches:  netbsd-9
changeset: 963892:b51304b80af1
user:      martin <martin%NetBSD.org@localhost>
date:      Mon May 18 18:45:40 2020 +0000

description:
Pull up following revision(s) (requested by riastradh in ticket #912):

        sys/arch/arm/dts/sun50i-a64.dtsi: revision 1.14
        sys/arch/evbarm/conf/GENERIC64: revision 1.116
        sys/arch/evbarm/conf/GENERIC64: revision 1.131
        sys/arch/arm/sunxi/sun50i_a64_ccu.c: revision 1.21
        sys/arch/arm/sunxi/sun50i_a64_ccu.c: revision 1.22
        sys/arch/arm/sunxi/sun8i_crypto.c: revision 1.10
        sys/arch/arm/sunxi/sun8i_crypto.c: revision 1.11
        sys/arch/arm/sunxi/sun8i_crypto.c: revision 1.12
        sys/arch/arm/sunxi/sun8i_crypto.c: revision 1.1
        sys/arch/arm/sunxi/sun8i_crypto.c: revision 1.2
        sys/arch/arm/sunxi/sun8i_crypto.c: revision 1.3
        sys/arch/arm/sunxi/sun8i_crypto.h: revision 1.1
        sys/arch/arm/sunxi/sun8i_crypto.c: revision 1.4
        sys/arch/arm/sunxi/sun8i_crypto.c: revision 1.5
        sys/arch/arm/sunxi/sun8i_crypto.c: revision 1.6
        sys/arch/arm/sunxi/sun8i_crypto.c: revision 1.7
        sys/arch/arm/sunxi/sun8i_crypto.c: revision 1.8
        sys/arch/arm/sunxi/sun8i_crypto.c: revision 1.9
        sys/arch/arm/sunxi/files.sunxi: revision 1.67

Add crypto engine clock

Add SUNXI_CCU_NM_ROUND_DOWN to CE clock, fix pll parents to use 2X outputs

Add crypto engine block.

Draft driver for Allwinner Crypto Engine.
Found on, e.g., the Pinebook.

Only used for TRNG at the moment, but hooking it up to opencrypto(9)
shouldn't be too hard if anyone still cares about that these days.

The distribution of the alleged TRNG is very nonuniform distributed
seems to alternate between toward runs with exceptionally high
fractions of 0 bits and runs with exceptionally high fractions of 1
bits -- initially all my samples were mostly 0's, and then all my
samples were mostly 1's, and now I'm seeing more oscillation between
these runs.

So I've wired it up as RND_TYPE_UNKNOWN, not RND_TYPE_RNG (it will
immediately flunk our rngtest and be disabled), and I estimated it to
provide at most one bit of entropy per byte of data -- which may
still be optimistic.  I also added a sysctl node hw.sun8icryptoN.rng
to read out 1024-byte samples for analysis, and I left the driver
commented out in GENERIC64 for now.
(If anyone has contacts at Allwinner who can tell us about how the
alleged TRNG is supposed to work, please let me know!)

Reduce some duplicated bus_dma clutter.

Factor out some of the self-test logic used for debugging.

Add missing bus_dmamap_sync(POSTWRITE) while here.

Make sure ERESTART doesn't come flying out to userland.
I picked ERESTART to mean `all channels are occupied' because that's
what opencrypto(9) uses to decide whether to queue a request, but
it's not appropriate for sysctl(2) to return that.

Avoid a race between interruption and reacquisition of lock.
Otherwise, we would have leaked the memory in this case.

Tidy up comments.

Oops -- forgot to kmem_free.

Fix typo -- acknowledge interrupts _and_ errors.

Reduce entropy estimate for sun8icrypto TRNG.

NIST's SP800-90B entropy estimation tools put it at no more than .08
bits of entropy per byte of data(!), so estimate 100 bits of data per
bit of entropy.  This is probably not conservative enough -- the NIST
tools were written without knowledge of how this alleged TRNG works!
Knowledge of the physics of how the TRNG is supposed to work could
probably enable a better job at predicting the outputs.
While here, bump the size of data we can sample directly with sysctl
to 4096 bytes.

Enable sun8icrypto in GENERIC64.

But set its entropy estimate to zero until we have a better idea of
how it works.  Can't really hurt this way unless sun8icrypto is
maliciously dependent on all other inputs to the entropy pool, which
seems unlikely.

Fix (presently harmless) psato.

Don't overwrite cy_root_node; use cy_trng_node as intended.

Fix previous brainfart.

Don't use the uninitialized trng node as the root node -- derp.
Instead, use the root node as the root node, and initialize the trng
node here.

diffstat:

 sys/arch/arm/dts/sun50i-a64.dtsi    |    11 +-
 sys/arch/arm/sunxi/files.sunxi      |     7 +-
 sys/arch/arm/sunxi/sun50i_a64_ccu.c |    14 +-
 sys/arch/arm/sunxi/sun8i_crypto.c   |  1338 +++++++++++++++++++++++++++++++++++
 sys/arch/arm/sunxi/sun8i_crypto.h   |   152 +++
 sys/arch/evbarm/conf/GENERIC64      |     3 +-
 6 files changed, 1520 insertions(+), 5 deletions(-)

diffs (truncated from 1611 to 300 lines):

diff -r 2841a0a419be -r b51304b80af1 sys/arch/arm/dts/sun50i-a64.dtsi
--- a/sys/arch/arm/dts/sun50i-a64.dtsi  Mon May 18 18:12:24 2020 +0000
+++ b/sys/arch/arm/dts/sun50i-a64.dtsi  Mon May 18 18:45:40 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sun50i-a64.dtsi,v 1.11.2.2 2019/11/18 19:31:00 martin Exp $ */
+/* $NetBSD: sun50i-a64.dtsi,v 1.11.2.3 2020/05/18 18:45:40 martin Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -50,6 +50,15 @@
                        resets = <&ccu RST_BUS_THS>;
                        #thermal-sensor-cells = <0>;
                };
+
+               crypto: crypto@1c15000 {
+                       compatible = "allwinner,sun50i-a64-crypto";
+                       reg = <0x01c15000 0x1000>;
+                       interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_CE>, <&ccu CLK_CE>;
+                       clock-names = "bus", "mod";
+                       resets = <&ccu RST_BUS_CE>;
+               };
        };
 
        /* PMU interrupt numbers are wrong in mainline dts */
diff -r 2841a0a419be -r b51304b80af1 sys/arch/arm/sunxi/files.sunxi
--- a/sys/arch/arm/sunxi/files.sunxi    Mon May 18 18:12:24 2020 +0000
+++ b/sys/arch/arm/sunxi/files.sunxi    Mon May 18 18:45:40 2020 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.sunxi,v 1.65 2019/06/14 21:26:36 tnn Exp $
+#      $NetBSD: files.sunxi,v 1.65.2.1 2020/05/18 18:45:40 martin Exp $
 #
 # Configuration info for Allwinner sunxi family SoCs
 #
@@ -361,6 +361,11 @@
 attach sunxihdmiphy at fdt with sunxi_hdmiphy
 file   arch/arm/sunxi/sunxi_hdmiphy.c          sunxi_hdmiphy | sunxi_dwhdmi
 
+# Allwinner Crypto Engine
+device sun8icrypto
+attach sun8icrypto at fdt with sun8i_crypto
+file   arch/arm/sunxi/sun8i_crypto.c           sun8i_crypto
+
 # SOC parameters
 defflag        opt_soc.h                       SOC_SUNXI
 defflag        opt_soc.h                       SOC_SUNXI_MC
diff -r 2841a0a419be -r b51304b80af1 sys/arch/arm/sunxi/sun50i_a64_ccu.c
--- a/sys/arch/arm/sunxi/sun50i_a64_ccu.c       Mon May 18 18:12:24 2020 +0000
+++ b/sys/arch/arm/sunxi/sun50i_a64_ccu.c       Mon May 18 18:45:40 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sun50i_a64_ccu.c,v 1.13.2.3 2019/11/25 16:18:40 martin Exp $ */
+/* $NetBSD: sun50i_a64_ccu.c,v 1.13.2.4 2020/05/18 18:45:40 martin Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: sun50i_a64_ccu.c,v 1.13.2.3 2019/11/25 16:18:40 martin Exp $");
+__KERNEL_RCSID(1, "$NetBSD: sun50i_a64_ccu.c,v 1.13.2.4 2020/05/18 18:45:40 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -60,6 +60,7 @@
 #define        SDMMC0_CLK_REG          0x088
 #define        SDMMC1_CLK_REG          0x08c
 #define        SDMMC2_CLK_REG          0x090
+#define        CE_CLK_REG              0x09c
 #define        SPI0_CLK_REG            0x0a0
 #define        SPI1_CLK_REG            0x0a4
 #define        I2SPCM0_CLK_REG         0x0b0
@@ -156,6 +157,7 @@
 static const char *ahb2_parents[] = { "ahb1", "pll_periph0" };
 static const char *apb1_parents[] = { "ahb1" };
 static const char *apb2_parents[] = { "losc", "hosc", "pll_periph0" };
+static const char *ce_parents[] = { "hosc", "pll_periph0_2x", "pll_periph1_2x" };
 static const char *mmc_parents[] = { "hosc", "pll_periph0_2x", "pll_periph1_2x" };
 static const char *ths_parents[] = { "hosc", NULL, NULL, NULL };
 static const char *de_parents[] = { "pll_periph0_2x", "pll_de" };
@@ -397,6 +399,14 @@
            __BIT(31),          /* enable */
            SUNXI_CCU_NM_POWER_OF_TWO|SUNXI_CCU_NM_ROUND_DOWN|SUNXI_CCU_NM_DIVIDE_BY_TWO),
 
+       SUNXI_CCU_NM(A64_CLK_CE, "ce", ce_parents,
+           CE_CLK_REG,         /* reg */
+           __BITS(17,16),      /* n */
+           __BITS(3,0),        /* m */
+           __BITS(25,24),      /* sel */
+           __BIT(31),          /* enable */
+           SUNXI_CCU_NM_POWER_OF_TWO|SUNXI_CCU_NM_ROUND_DOWN),
+
        SUNXI_CCU_DIV_GATE(A64_CLK_THS, "ths", ths_parents,
            THS_CLK_REG,        /* reg */
            __BITS(1,0),        /* div */
diff -r 2841a0a419be -r b51304b80af1 sys/arch/arm/sunxi/sun8i_crypto.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/sunxi/sun8i_crypto.c Mon May 18 18:45:40 2020 +0000
@@ -0,0 +1,1338 @@
+/*     $NetBSD: sun8i_crypto.c,v 1.14.2.2 2020/05/18 18:45:40 martin Exp $     */
+
+/*-
+ * Copyright (c) 2019 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.
+ */
+
+/*
+ * sun8i_crypto -- Allwinner Crypto Engine driver
+ *
+ * The Crypto Engine is documented in Sec. 3.15 of the Allwinner A64
+ * User Manual v1.1, on pp. 230--241.  We only use it for the TRNG at
+ * the moment, but in principle it could be wired up with opencrypto(9)
+ * to compute AES, DES, 3DES, MD5, SHA-1, SHA-224, SHA-256, HMAC-SHA1,
+ * HMAC-HA256, RSA, and an undocumented PRNG.  It also seems to support
+ * AES keys in SRAM (for some kind of HDMI HDCP stuff?).
+ *
+ * https://linux-sunxi.org/images/b/b4/Allwinner_A64_User_Manual_V1.1.pdf
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(1, "$NetBSD: sun8i_crypto.c,v 1.14.2.2 2020/05/18 18:45:40 martin Exp $");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/atomic.h>
+#include <sys/bus.h>
+#include <sys/callout.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/kmem.h>
+#include <sys/mutex.h>
+#include <sys/rndpool.h>
+#include <sys/rndsource.h>
+#include <sys/sysctl.h>
+#include <sys/workqueue.h>
+
+#include <dev/fdt/fdtvar.h>
+
+#include <arm/sunxi/sun8i_crypto.h>
+
+#define        SUN8I_CRYPTO_TIMEOUT    hz
+#define        SUN8I_CRYPTO_RNGENTROPY 100 /* estimated bits per bit of entropy */
+#define        SUN8I_CRYPTO_RNGBYTES   PAGE_SIZE
+
+struct sun8i_crypto_task;
+
+struct sun8i_crypto_buf {
+       bus_dma_segment_t       cb_seg[1];
+       int                     cb_nsegs;
+       bus_dmamap_t            cb_map;
+       void                    *cb_kva;
+};
+
+struct sun8i_crypto_softc {
+       device_t                        sc_dev;
+       bus_space_tag_t                 sc_bst;
+       bus_space_handle_t              sc_bsh;
+       bus_dma_tag_t                   sc_dmat;
+       kmutex_t                        sc_lock;
+       struct sun8i_crypto_chan {
+               struct sun8i_crypto_task        *cc_task;
+               unsigned                        cc_starttime;
+       }                               sc_chan[SUN8I_CRYPTO_NCHAN];
+       struct callout                  sc_timeout;
+       struct workqueue                *sc_wq;
+       struct work                     sc_work;
+       void                            *sc_ih;
+       uint32_t                        sc_done;
+       uint32_t                        sc_esr;
+       bool                            sc_work_pending;
+       struct sun8i_crypto_rng {
+               struct sun8i_crypto_buf         cr_buf;
+               struct sun8i_crypto_task        *cr_task;
+               struct krndsource               cr_rndsource;
+               bool                            cr_pending;
+       }                               sc_rng;
+       struct sun8i_crypto_selftest {
+               struct sun8i_crypto_buf         cs_in;
+               struct sun8i_crypto_buf         cs_key;
+               struct sun8i_crypto_buf         cs_out;
+               struct sun8i_crypto_task        *cs_task;
+       }                               sc_selftest;
+       struct sun8i_crypto_sysctl {
+               struct sysctllog                *cy_log;
+               const struct sysctlnode         *cy_root_node;
+               const struct sysctlnode         *cy_trng_node;
+       }                               sc_sysctl;
+};
+
+struct sun8i_crypto_task {
+       struct sun8i_crypto_buf ct_buf;
+       struct sun8i_crypto_taskdesc *ct_desc;
+       void                    (*ct_callback)(struct sun8i_crypto_softc *,
+                                   struct sun8i_crypto_task *, void *, int);
+       void                    *ct_cookie;
+};
+
+/*
+ * Forward declarations
+ */
+
+static int     sun8i_crypto_match(device_t, cfdata_t, void *);
+static void    sun8i_crypto_attach(device_t, device_t, void *);
+
+static struct sun8i_crypto_task *
+               sun8i_crypto_task_get(struct sun8i_crypto_softc *,
+                   void (*)(struct sun8i_crypto_softc *,
+                       struct sun8i_crypto_task *, void *, int),
+                   void *);
+static void    sun8i_crypto_task_put(struct sun8i_crypto_softc *,
+                   struct sun8i_crypto_task *);
+static void    sun8i_crypto_task_reset(struct sun8i_crypto_task *);
+
+static void    sun8i_crypto_task_set_key(struct sun8i_crypto_task *,
+                   bus_dmamap_t);
+static void    sun8i_crypto_task_set_iv(struct sun8i_crypto_task *,
+                   bus_dmamap_t);
+static void    sun8i_crypto_task_set_ctr(struct sun8i_crypto_task *,
+                   bus_dmamap_t);
+static void    sun8i_crypto_task_set_input(struct sun8i_crypto_task *,
+                   bus_dmamap_t);
+static void    sun8i_crypto_task_set_output(struct sun8i_crypto_task *,
+                   bus_dmamap_t);
+
+static void    sun8i_crypto_task_scatter(struct sun8i_crypto_adrlen *,
+                   bus_dmamap_t);
+
+static int     sun8i_crypto_submit_trng(struct sun8i_crypto_softc *,
+                   struct sun8i_crypto_task *, uint32_t);
+static int     sun8i_crypto_submit_aesecb(struct sun8i_crypto_softc *,
+                   struct sun8i_crypto_task *, uint32_t, uint32_t, uint32_t);
+static int     sun8i_crypto_submit(struct sun8i_crypto_softc *,
+                   struct sun8i_crypto_task *);
+
+static void    sun8i_crypto_timeout(void *);
+static int     sun8i_crypto_intr(void *);
+static void    sun8i_crypto_schedule_worker(struct sun8i_crypto_softc *);
+static void    sun8i_crypto_worker(struct work *, void *);
+static void    sun8i_crypto_chan_done(struct sun8i_crypto_softc *, unsigned,
+                   int);
+
+static int     sun8i_crypto_allocbuf(struct sun8i_crypto_softc *, size_t,
+                   struct sun8i_crypto_buf *);
+static void    sun8i_crypto_freebuf(struct sun8i_crypto_softc *, size_t,
+                   struct sun8i_crypto_buf *);
+
+static void    sun8i_crypto_rng_attach(struct sun8i_crypto_softc *);
+static void    sun8i_crypto_rng_get(size_t, void *);
+static void    sun8i_crypto_rng_done(struct sun8i_crypto_softc *,
+                   struct sun8i_crypto_task *, void *, int);
+
+static void    sun8i_crypto_selftest(device_t);
+static void    sun8i_crypto_selftest_done(struct sun8i_crypto_softc *,
+                   struct sun8i_crypto_task *, void *, int);
+
+static void    sun8i_crypto_sysctl_attach(struct sun8i_crypto_softc *);
+static int     sun8i_crypto_sysctl_rng(SYSCTLFN_ARGS);
+static void    sun8i_crypto_sysctl_rng_done(struct sun8i_crypto_softc *,
+                   struct sun8i_crypto_task *, void *, int);
+
+/*
+ * Register access
+ */
+
+static uint32_t
+sun8i_crypto_read(struct sun8i_crypto_softc *sc, bus_addr_t reg)
+{
+       return bus_space_read_4(sc->sc_bst, sc->sc_bsh, reg);
+}
+
+static void
+sun8i_crypto_write(struct sun8i_crypto_softc *sc, bus_addr_t reg, uint32_t v)
+{
+       bus_space_write_4(sc->sc_bst, sc->sc_bsh, reg, v);
+}



Home | Main Index | Thread Index | Old Index