Hi again tech@

This is my second attempt at a patch to add support for the octeon's
onboard rng. I've fixed all of the concerns (ISC license, wrong #define,
comment removal) and I've also come bearing statistics on the quality of
the entropy.

I dd'd 512M of /dev/random and ran the ent from
http://www.fourmilab.ch/random/

512M of /dev/random

With octrng:
# sysctl kern.random
kern.random=tot: 232802 used: 2560 read: 326918 stirs: 5 enqs: 12575
deqs: 791 drops: 0 ledrops: 704 ed: 198 188 280 385 487 666 786 790 901
698 496 207 163 76 35 29 20 13 3 4 5 1 2 0 0 0 0 0 0 0 2 6140 sc: 6140
27 0 49 0 6359 0 0 sb: 190340 0 0 779 0 42140 0 0
# uptime
10:12PM  36 secs, 1 user, load averages: 0.48, 0.12, 0.04

# ./ent
Entropy = 8.000000 bits per byte.

Optimum compression would reduce the size
of this 536870912 byte file by 0 percent.

Chi square distribution for 536870912 samples is 240.04, and randomly
would exceed this value 74.09 percent of the times.

Arithmetic mean value of data bytes is 127.5021 (127.5 = random).
Monte Carlo value for Pi is 3.141322610 (error 0.01 percent).
Serial correlation coefficient is -0.000013 (totally uncorrelated =
0.0).

Without octrng:
# sysctl kern.random                                                    
kern.random=tot: 43283 used: 2560 read: 328224 stirs: 5 enqs: 6439 deqs:
405 drops: 0 ledrops: 542 ed: 194 169 270 370 567 715 729 748 865 683
479 206 160 111 62 42 28 17 4 6 7 2 3 0 0 0 0 0 0 0 2 0 sc: 0 27 0 73 0
6339 0 0 sb: 0 0 0 1112 0 42375 0 0
# uptime
10:13PM  52 secs, 1 user, load averages: 0.61, 0.19, 0.07

# ./ent
Entropy = 8.000000 bits per byte.

Optimum compression would reduce the size
of this 536870912 byte file by 0 percent.

Chi square distribution for 536870912 samples is 270.87, and randomly
would exceed this value 23.64 percent of the times.

Arithmetic mean value of data bytes is 127.4949 (127.5 = random).
Monte Carlo value for Pi is 3.141474244 (error 0.00 percent).
Serial correlation coefficient is 0.000015 (totally uncorrelated = 0.0).

You'll notice that there's no significant difference between the output
of the two rngs. However, with octrng the dd completed in under a minute
(more entropy in pool). Without, it took several minutes. If you want
time output, I can add that as well.

So the addition of hardware entropy has no meaningful negative effect on
the quality of the entropy, and greatly increases the size of the
entropy pool.

Ok?


Index: conf/GENERIC
===================================================================
RCS file: /cvs/src/sys/arch/octeon/conf/GENERIC,v
retrieving revision 1.10
diff -u -b -w -p -r1.10 GENERIC
--- conf/GENERIC        19 Sep 2013 00:15:59 -0000      1.10
+++ conf/GENERIC        23 Oct 2013 01:22:06 -0000
@@ -51,3 +51,6 @@ pciide*               at pci? flags 0x0000
 
 # IDE hard drives
 wd*            at pciide? flags 0x0000
+
+# RNG
+octrng0                at iobus0
Index: conf/files.octeon
===================================================================
RCS file: /cvs/src/sys/arch/octeon/conf/files.octeon,v
retrieving revision 1.14
diff -u -b -w -p -r1.14 files.octeon
--- conf/files.octeon   15 Aug 2013 06:54:35 -0000      1.14
+++ conf/files.octeon   23 Oct 2013 01:22:06 -0000
@@ -90,3 +90,8 @@ file  arch/octeon/dev/octeon_pcibus.c                 p
 file   arch/octeon/dev/octeon_bus_space.c
 
 file   arch/octeon/octeon/pciide_machdep.c             pciide
+
+# Onboard rng
+device octrng
+attach octrng at iobus
+file   arch/octeon/dev/octrng.c                                octrng
Index: dev/cn30xxrnmreg.h
===================================================================
RCS file: dev/cn30xxrnmreg.h
diff -N dev/cn30xxrnmreg.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ dev/cn30xxrnmreg.h  23 Oct 2013 01:22:06 -0000
@@ -0,0 +1,40 @@
+/*     $OpenBSD$       */
+/*
+ * Copyright (c) 2013 William Orr <w...@worrbase.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _CN30XXRNMREG_H_
+#define _CN30XXRNMREG_H_
+
+#define RNM_REG_BASE   0x0001180040000000ULL
+#define RNM_REG_SIZE   0xFULL
+
+#define RNM_REG_CTL            0x0001180040000000ULL
+#define RNM_REG_BIST   0x0001180040000008ULL
+
+#define RNM_CTL_ENT_EN 0x0000000000000001ULL
+#define RNM_CTL_RNG_EN 0x0000000000000002ULL
+#define RNM_CTL_RNM_RST        0x0000000000000004ULL
+#define RNM_CTL_RNG_RST        0x0000000000000008ULL
+#define RNM_CTL_ENT_SEL        0x00000000000000F0ULL
+#define RNM_CTL_EER_VAL        0x0000000000000100ULL
+#define RNM_CTL_EER_LCK        0x0000000000000200ULL
+#define RNM_CTL_DIS_MAK        0x0000000000000400ULL
+
+#define RNM_BIST_MEM   0x0000000000000001ULL
+#define RNM_BIST_RRC   0x0000000000000002ULL
+
+#endif
+
Index: dev/octeon_iobus.c
===================================================================
RCS file: /cvs/src/sys/arch/octeon/dev/octeon_iobus.c,v
retrieving revision 1.4
diff -u -b -w -p -r1.4 octeon_iobus.c
--- dev/octeon_iobus.c  2 Jun 2013 20:29:36 -0000       1.4
+++ dev/octeon_iobus.c  23 Oct 2013 01:22:06 -0000
@@ -154,12 +154,14 @@ struct machine_bus_dma_tag iobus_bus_dma
 const struct iobus_unit iobus_units[] = {
        { OCTEON_CF_BASE, 0 },                  /* octcf */
        { 0, 0 },                               /* pcibus */
-       { GMX0_BASE_PORT0, CIU_INT_GMX_DRP0 }   /* cn30xxgmx */
+       { GMX0_BASE_PORT0, CIU_INT_GMX_DRP0 },  /* cn30xxgmx */
+       { OCTEON_RNG_BASE, 0 }                  /* octrng */
 };
 struct iobus_attach_args iobus_children[] = {
        IOBUSDEV("octcf", 0, &iobus_units[0]),
        IOBUSDEV("pcibus", 0, &iobus_units[1]),
-       IOBUSDEV("cn30xxgmx", 0, &iobus_units[2])
+       IOBUSDEV("cn30xxgmx", 0, &iobus_units[2]),
+       IOBUSDEV("octrng", 0, &iobus_units[3])
 };
 #undef IOBUSDEV
 
Index: dev/octrng.c
===================================================================
RCS file: dev/octrng.c
diff -N dev/octrng.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ dev/octrng.c        23 Oct 2013 01:22:06 -0000
@@ -0,0 +1,108 @@
+/* $OpenBSD$ */
+/*
+ * Copyright (c) 2013 William Orr <w...@worrbase.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+#include <sys/timeout.h>
+
+#include <machine/bus.h>
+#include <machine/octeonreg.h>
+#include <machine/octeonvar.h>
+
+#include <dev/rndvar.h>
+
+#include <octeon/dev/cn30xxrnmreg.h>
+#include <octeon/dev/iobusvar.h>
+
+#define OCTEON_RNG_SIZE                0x8
+#define OCTEON_RNG_TIMEOUT     5
+
+int octrngprobe(struct device *, void *, void *);
+void octrngattach(struct device *, struct device *, void *);
+void octrngdettach(struct device *, int);
+void octrngrnd(void *);
+
+struct octrng_softc {
+       struct device sc_dev;
+       struct timeout sc_to;
+       bus_space_tag_t       sc_iot;
+       bus_space_handle_t    sc_ioh;
+};
+
+struct cfattach octrng_ca = {
+       sizeof(struct octrng_softc), octrngprobe, octrngattach
+};
+
+struct cfdriver octrng_cd = {
+       NULL, "octrng", DV_DULL
+};
+
+int
+octrngprobe(struct device *parent, void *match, void *aux)
+{
+       struct iobus_attach_args *aa = (struct iobus_attach_args *)aux;
+       struct cfdata *cf = (struct cfdata *)match;
+
+       if (strcmp(aa->aa_name, cf->cf_driver->cd_name) == 0)
+               return 1;
+
+       return 0;
+}
+
+void
+octrngattach(struct device *parent, struct device *self, void *aux)
+{
+       struct octrng_softc *sc = (void *)self;
+       struct iobus_attach_args *aa = (struct iobus_attach_args *)aux;
+       uint64_t rnm;
+
+       sc->sc_iot = aa->aa_bust;
+
+       if (bus_space_map(sc->sc_iot, OCTEON_RNG_BASE,
+           OCTEON_RNG_SIZE, 0, &sc->sc_ioh)) {
+               printf(": couldn't map registers\n");
+               return;
+       }
+
+       printf("\n");
+
+       /* We need to initialize the rng by writing some values
+        * to rnm csr
+        */
+       rnm = octeon_xkphys_read_8(RNM_REG_CTL);
+       rnm |= RNM_CTL_ENT_EN | RNM_CTL_RNG_EN;
+       octeon_xkphys_write_8(RNM_REG_CTL, rnm);
+
+       timeout_set(&sc->sc_to, octrngrnd, sc);
+       timeout_add(&sc->sc_to, OCTEON_RNG_TIMEOUT);
+}
+
+void
+octrngrnd(void *v)
+{
+       struct octrng_softc *sc = v;
+       uint64_t r;
+
+       r = bus_space_read_8(sc->sc_iot, sc->sc_ioh, 0);
+
+       add_true_randomness(r);
+       add_true_randomness(r >> 32);
+
+       timeout_add(&sc->sc_to, OCTEON_RNG_TIMEOUT);
+}
+
Index: include/octeonreg.h
===================================================================
RCS file: /cvs/src/sys/arch/octeon/include/octeonreg.h,v
retrieving revision 1.2
diff -u -b -w -p -r1.2 octeonreg.h
--- include/octeonreg.h 9 Jun 2013 20:20:11 -0000       1.2
+++ include/octeonreg.h 23 Oct 2013 01:22:06 -0000
@@ -35,6 +35,7 @@
 #define OCTEON_MIO_BOOT_BASE   0x1180000000000ULL
 #define OCTEON_UART0_BASE      0x1180000000800ULL
 #define OCTEON_UART1_BASE      0x1180000000C00ULL
+#define OCTEON_RNG_BASE                0x1400000000000ULL
 
 #define MIO_BOOT_REG_CFG0      0x0
 #define MIO_BOOT_REG_CFG(x)    (MIO_BOOT_REG_CFG0+((x)*8))

Reply via email to