Page MenuHomeFreeBSD

D7876.1783170451.diff
No OneTemporary

Size
13 KB
Referenced Files
None
Subscribers
None

D7876.1783170451.diff

Index: sys/arm/allwinner/a10_crypto.h
===================================================================
--- sys/arm/allwinner/a10_crypto.h
+++ sys/arm/allwinner/a10_crypto.h
@@ -0,0 +1,135 @@
+/*-
+ * Copyright (c) 2016 Ganbold Tsagaankhuu <ganbold@freebsd.org>
+ * 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 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 AUTHOR 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 A10_CRYPTO_H_
+#define A10_CRYPTO_H_
+
+#define A10_SS_CTL 0x00
+#define A10_SS_KEY0 0x04
+#define A10_SS_KEY1 0x08
+#define A10_SS_KEY2 0x0C
+#define A10_SS_KEY3 0x10
+#define A10_SS_KEY4 0x14
+#define A10_SS_KEY5 0x18
+#define A10_SS_KEY6 0x1C
+#define A10_SS_KEY7 0x20
+
+#define A10_SS_IV0 0x24
+#define A10_SS_IV1 0x28
+#define A10_SS_IV2 0x2C
+#define A10_SS_IV3 0x30
+
+#define A10_SS_FCSR 0x44
+
+#define A10_SS_MD0 0x4C
+#define A10_SS_MD1 0x50
+#define A10_SS_MD2 0x54
+#define A10_SS_MD3 0x58
+#define A10_SS_MD4 0x5C
+
+#define A10_SS_RXFIFO 0x200
+#define A10_SS_TXFIFO 0x204
+
+/* A10_SS_CTL values */
+
+/* PRNG generator mode - bit 15 */
+#define A10_SS_PRNG_ONESHOT (0 << 15)
+#define A10_SS_PRNG_CONTINUE (1 << 15)
+
+/* IV mode for hash */
+#define A10_SS_IV_ARBITRARY (1 << 14)
+
+/* SS operation mode - bits 12-13 */
+#define A10_SS_ECB (0 << 12)
+#define A10_SS_CBC (1 << 12)
+#define A10_SS_CTS (3 << 12)
+
+/* Counter width for CNT mode - bits 10-11 */
+#define A10_SS_CNT_16BITS (0 << 10)
+#define A10_SS_CNT_32BITS (1 << 10)
+#define A10_SS_CNT_64BITS (2 << 10)
+
+/* Key size for AES - bits 8-9 */
+#define A10_SS_AES_128BITS (0 << 8)
+#define A10_SS_AES_192BITS (1 << 8)
+#define A10_SS_AES_256BITS (2 << 8)
+
+/* Operation direction - bit 7 */
+#define A10_SS_ENCRYPTION (0 << 7)
+#define A10_SS_DECRYPTION (1 << 7)
+
+/* SS Method - bits 4-6 */
+#define A10_SS_OP_AES (0 << 4)
+#define A10_SS_OP_DES (1 << 4)
+#define A10_SS_OP_3DES (2 << 4)
+#define A10_SS_OP_SHA1 (3 << 4)
+#define A10_SS_OP_MD5 (4 << 4)
+#define A10_SS_OP_PRNG (5 << 4)
+
+/* Data end bit - bit 2 */
+#define A10_SS_DATA_END (1 << 2)
+
+/* PRNG start bit - bit 1 */
+#define A10_SS_PRNG_START (1 << 1)
+
+/* SS Enable bit - bit 0 */
+#define A10_SS_DISABLED (0 << 0)
+#define A10_SS_ENABLED (1 << 0)
+
+/* A10_SS_FCSR configuration values */
+/* RX FIFO status - bit 30 */
+#define A10_SS_RXFIFO_FREE (1 << 30)
+
+/* RX FIFO empty spaces - bits 24-29 */
+#define A10_SS_RXFIFO_SPACES(val) (((val) >> 24) & 0x3f)
+
+/* TX FIFO status - bit 22 */
+#define A10_SS_TXFIFO_AVAILABLE (1 << 22)
+
+/* TX FIFO available spaces - bits 16-21 */
+#define A10_SS_TXFIFO_SPACES(val) (((val) >> 16) & 0x3f)
+
+#define A10_SS_RX_MAX 32
+#define A10_SS_RX_DEFAULT A10_SS_RX_MAX
+#define A10_SS_TX_MAX 33
+
+#define A10_SS_RXFIFO_EMP_INT_PENDING (1 << 10)
+#define A10_SS_TXFIFO_AVA_INT_PENDING (1 << 8)
+#define A10_SS_RXFIFO_EMP_INT_ENABLE (1 << 2)
+#define A10_SS_TXFIFO_AVA_INT_ENABLE (1 << 0)
+
+#define A10_SS_SEED_LEN_BITS 192
+#define A10_SS_SEED_LEN (A10_SS_SEED_LEN_BITS / 8)
+
+#define A10_SS_DATA_LEN_BITS 160
+#define A10_SS_DATA_LEN (A10_SS_DATA_LEN_BITS / 8)
+
+#define A10_SS_FIFO_WORDS (A10_SS_SEED_LEN / sizeof(uint32_t))
+
+#define DIE_ID_START_BIT 16
+#define DIE_ID_MASK 0x07
+
+#endif
Index: sys/arm/allwinner/a10_crypto.c
===================================================================
--- sys/arm/allwinner/a10_crypto.c
+++ sys/arm/allwinner/a10_crypto.c
@@ -0,0 +1,268 @@
+/*-
+ * Copyright (c) 2016 Ganbold Tsagaankhuu <ganbold@freebsd.org>
+ * 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 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 AUTHOR 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.
+ */
+
+/*
+ * Allwinner A10/A20 Security System/Crypto accelerator
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/endian.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/sysctl.h>
+#include <machine/bus.h>
+#include <sys/random.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/extres/clk/clk.h>
+#include <dev/extres/hwreset/hwreset.h>
+
+#include <arm/allwinner/a10_crypto.h>
+
+static struct ofw_compat_data compat_data[] = {
+ { "allwinner,sun4i-a10-crypto", 1 },
+ { NULL, 0 }
+};
+
+struct a10_crypto_softc {
+ device_t dev;
+ struct resource *res;
+ struct callout co;
+ int ticks;
+ uint32_t sc_seed[A10_SS_FIFO_WORDS];
+ uint32_t sc_buf[A10_SS_FIFO_WORDS];
+};
+
+static struct resource_spec a10_crypto_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { -1, 0 }
+};
+
+#define RD4(sc, reg) bus_read_4((sc)->res, (reg))
+#define WR4(sc, reg, val) bus_write_4((sc)->res, (reg), (val))
+
+static void
+a10_rng_start(struct a10_crypto_softc *sc)
+{
+ uint32_t prng_mode;
+ int i;
+
+ prng_mode = A10_SS_OP_PRNG | A10_SS_PRNG_CONTINUE | A10_SS_ENABLED;
+
+ /* Write PRNG mode */
+ WR4(sc, A10_SS_CTL, prng_mode);
+
+ /* Write the seed */
+ for (i = 0; i < A10_SS_FIFO_WORDS; i++)
+ WR4(sc, A10_SS_KEY0 + i * 4, sc->sc_seed[i]);
+
+ /* Start PRNG */
+ WR4(sc, A10_SS_CTL, prng_mode | A10_SS_PRNG_START);
+}
+
+static void
+a10_rng_stop(struct a10_crypto_softc *sc)
+{
+ uint32_t ctrl;
+
+ /* Disable PRNG */
+ ctrl = RD4(sc, A10_SS_CTL);
+ ctrl &= ~A10_SS_PRNG_START;
+ WR4(sc, A10_SS_CTL, ctrl);
+
+ /* Disable and flush FIFO */
+ WR4(sc, A10_SS_CTL, A10_SS_DISABLED);
+}
+
+static void
+a10_rng_harvest(void *arg)
+{
+ struct a10_crypto_softc *sc = arg;
+ uint32_t val;
+ int i;
+
+ /* Start PRNG */
+ a10_rng_start(sc);
+
+ /* Read random data */
+ bus_read_multi_4(sc->res, A10_SS_TXFIFO, sc->sc_buf,
+ A10_SS_DATA_LEN / sizeof(uint32_t));
+
+ /* Update the seed */
+ for (i = 0; i < A10_SS_FIFO_WORDS; i++) {
+ val = RD4(sc, A10_SS_KEY0 + i * 4);
+ sc->sc_seed[i] = val;
+ }
+
+ /* Disable and flush FIFO */
+ WR4(sc, A10_SS_CTL, A10_SS_DISABLED);
+
+ random_harvest_queue(sc->sc_buf, sizeof(sc->sc_buf),
+ sizeof(sc->sc_buf) * NBBY / 2, RANDOM_PURE_ALLWINNER);
+
+ callout_reset(&sc->co, sc->ticks, a10_rng_harvest, sc);
+}
+
+static int
+a10_crypto_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "A10/A20 Security System/Crypto accelerator");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+a10_crypto_attach(device_t dev)
+{
+ struct a10_crypto_softc *sc;
+ hwreset_t rst_ahb;
+ clk_t clk_ss, clk_gate;
+ int err, i;
+ uint32_t val = 0;
+
+ sc = device_get_softc(dev);
+ clk_ss = clk_gate = NULL;
+ rst_ahb = NULL;
+
+ if (bus_alloc_resources(dev, a10_crypto_spec, &sc->res) != 0) {
+ device_printf(dev, "cannot allocate resources for device\n");
+ return (ENXIO);
+ }
+
+ /* De-assert reset */
+ if (hwreset_get_by_ofw_name(dev, 0, "ahb", &rst_ahb) == 0) {
+ err = hwreset_deassert(rst_ahb);
+ if (err != 0) {
+ device_printf(dev, "cannot de-assert reset\n");
+ goto error;
+ }
+ }
+
+ /* Get clocks and enable them */
+ err = clk_get_by_ofw_name(dev, 0, "ahb", &clk_gate);
+ if (err != 0) {
+ device_printf(dev, "Cannot get gate clock\n");
+ goto error;
+ }
+ err = clk_get_by_ofw_name(dev, 0, "mod", &clk_ss);
+ if (err != 0) {
+ device_printf(dev, "Cannot get SS clock\n");
+ goto error;
+ }
+ err = clk_enable(clk_gate);
+ if (err != 0) {
+ device_printf(dev, "Cannot enable clk gate\n");
+ goto error;
+ }
+ err = clk_enable(clk_ss);
+ if (err != 0) {
+ device_printf(dev, "Cannot enable SS clock\n");
+ goto error;
+ }
+
+ /*
+ * "Die Bonding ID"
+ */
+ WR4(sc, A10_SS_CTL, A10_SS_ENABLED);
+ val = RD4(sc, A10_SS_CTL);
+ val >>= DIE_ID_START_BIT;
+ val &= DIE_ID_MASK;
+ device_printf(dev, "Die ID %d\n", val);
+ WR4(sc, A10_SS_CTL, 0);
+
+ /* Install a periodic collector for the RNG */
+ if (hz > 100)
+ sc->ticks = hz / 100;
+ else
+ sc->ticks = 1;
+
+ /* Generate the seed fist */
+ for (i = 0; i < A10_SS_FIFO_WORDS; i++)
+ sc->sc_seed[i] = arc4random();
+
+ callout_init(&sc->co, 1);
+ callout_reset(&sc->co, sc->ticks, a10_rng_harvest, sc);
+
+ return (0);
+
+error:
+ if (clk_gate != NULL)
+ clk_release(clk_gate);
+ if (clk_ss != NULL)
+ clk_release(clk_ss);
+ if (rst_ahb != NULL)
+ hwreset_release(rst_ahb);
+ bus_release_resources(dev, a10_crypto_spec, &sc->res);
+ return (ENXIO);
+}
+
+static int
+a10_crypto_detach(device_t dev)
+{
+ struct a10_crypto_softc *sc = device_get_softc(dev);
+
+ a10_rng_stop(sc);
+ callout_drain(&sc->co);
+
+ bus_release_resources(dev, a10_crypto_spec, &sc->res);
+
+ return (0);
+}
+
+static device_method_t a10_crypto_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, a10_crypto_probe),
+ DEVMETHOD(device_attach, a10_crypto_attach),
+ DEVMETHOD(device_detach, a10_crypto_detach),
+
+ DEVMETHOD_END
+};
+
+static driver_t a10_crypto_driver = {
+ "a10_crypto",
+ a10_crypto_methods,
+ sizeof(struct a10_crypto_softc),
+};
+
+static devclass_t a10_crypto_devclass;
+
+DRIVER_MODULE(a10_crypto, simplebus, a10_crypto_driver, a10_crypto_devclass, 0, 0);
+MODULE_VERSION(a10_crypto, 1);
+MODULE_DEPEND(a10_crypto, crypto, 1, 1, 1);
+MODULE_DEPEND(a10_crypto, randomdev, 1, 1, 1);
Index: sys/arm/allwinner/files.allwinner
===================================================================
--- sys/arm/allwinner/files.allwinner
+++ sys/arm/allwinner/files.allwinner
@@ -29,6 +29,7 @@
arm/allwinner/aw_sid.c standard
arm/allwinner/aw_thermal.c standard
dev/iicbus/sy8106a.c optional sy8106a
+arm/allwinner/a10_crypto.c optional a10_crypto random
#arm/allwinner/console.c standard
arm/allwinner/a10_fb.c optional vt
Index: sys/arm/conf/ALLWINNER
===================================================================
--- sys/arm/conf/ALLWINNER
+++ sys/arm/conf/ALLWINNER
@@ -86,6 +86,10 @@
device axp81x # AXP813/818 Power Management Unit
device sy8106a # SY8106A Buck Regulator
+device a10_crypto
+device crypto
+device cryptodev
+
# GPIO
device gpio
device gpioled
Index: sys/arm/conf/ALLWINNER_UP
===================================================================
--- sys/arm/conf/ALLWINNER_UP
+++ sys/arm/conf/ALLWINNER_UP
@@ -70,6 +70,10 @@
device pcf8563 # RTC
+device a10_crypto
+device crypto
+device cryptodev
+
# GPIO
device gpio
device gpioled
Index: sys/dev/random/random_harvestq.c
===================================================================
--- sys/dev/random/random_harvestq.c
+++ sys/dev/random/random_harvestq.c
@@ -280,6 +280,7 @@
"PURE_RDRAND",
"PURE_NEHEMIAH",
"PURE_RNDTEST",
+ "PURE_ALLWINNER",
/* "ENTROPYSOURCE" */
};
Index: sys/sys/random.h
===================================================================
--- sys/sys/random.h
+++ sys/sys/random.h
@@ -90,6 +90,7 @@
RANDOM_PURE_NEHEMIAH,
RANDOM_PURE_RNDTEST,
RANDOM_PURE_VIRTIO,
+ RANDOM_PURE_ALLWINNER,
RANDOM_PURE_BROADCOM,
ENTROPYSOURCE
};

File Metadata

Mime Type
text/plain
Expires
Sat, Jul 4, 1:07 PM (1 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29012396
Default Alt Text
D7876.1783170451.diff (13 KB)

Event Timeline