[Cryptech-Commits] [core/platform/novena] 01/01: Add trng_extractor app to eim and i2c, refactor i2c apps to use common memory map.

git at cryptech.is git at cryptech.is
Thu Apr 2 19:08:26 UTC 2015


This is an automated email from the git hooks/post-receive script.

paul at psgd.org pushed a commit to branch master
in repository core/platform/novena.

commit b1ebb2a975de7f29e63c3a4046de15c26b44dceb
Author: Paul Selkirk <paul at psgd.org>
Date:   Thu Apr 2 15:07:22 2015 -0400

    Add trng_extractor app to eim and i2c, refactor i2c apps to use common memory map.
---
 eim/sw/Makefile                       |   9 +-
 eim/sw/cryptech_memory_map.h          |  34 +++----
 eim/sw/hash_tester_eim.c              |   2 +-
 eim/sw/trng_extractor_eim.c           | 155 +++++++++++++++++++++++++++++++
 eim/sw/trng_tester_eim.c              |  78 +++++++---------
 i2c/sw/Makefile                       |   9 +-
 {eim => i2c}/sw/cryptech_memory_map.h | 103 ++++++++++-----------
 i2c/sw/hash_i2c.c                     |  92 ++-----------------
 i2c/sw/hash_tester_i2c.c              |  97 +++-----------------
 i2c/sw/trng_extractor_i2c.c           | 167 ++++++++++++++++++++++++++++++++++
 i2c/sw/trng_tester_i2c.c              | 152 +++++++------------------------
 11 files changed, 491 insertions(+), 407 deletions(-)

diff --git a/eim/sw/Makefile b/eim/sw/Makefile
index 263a327..8b5f974 100755
--- a/eim/sw/Makefile
+++ b/eim/sw/Makefile
@@ -1,4 +1,4 @@
-all: hash_tester_eim trng_tester_eim hash_eim
+all: hash_tester_eim trng_tester_eim hash_eim trng_extractor_eim
 
 .c.o:
 	gcc -c -Wall -o $@ $<
@@ -18,9 +18,14 @@ hash_eim: hash_eim.o novena-eim.o tc_eim.o
 
 hash_eim.o: hash_eim.c tc_eim.h
 
+trng_extractor_eim: trng_extractor_eim.o novena-eim.o tc_eim.o
+	gcc -o $@ $^
+
+trng_extractor_eim.o: trng_extractor_eim.c tc_eim.h cryptech_memory_map.h
+
 novena-eim.o: novena-eim.c novena-eim.h
 
 tc_eim.o: tc_eim.c tc_eim.h novena-eim.h
 
 clean:
-	rm -f *.o hash_tester_eim trng_tester_eim hash_eim
+	rm -f *.o hash_tester_eim trng_tester_eim hash_eim trng_extractor_eim
diff --git a/eim/sw/cryptech_memory_map.h b/eim/sw/cryptech_memory_map.h
index c392584..c70e69c 100644
--- a/eim/sw/cryptech_memory_map.h
+++ b/eim/sw/cryptech_memory_map.h
@@ -49,26 +49,34 @@
 
 
 // addresses and codes common to all cores
-#define ADDR_NAME0              (0x0 << 2)
-#define ADDR_NAME1              (0x1 << 2)
-#define ADDR_VERSION            (0x2 << 2)
+#define ADDR_NAME0              (0x00 << 2)
+#define ADDR_NAME1              (0x01 << 2)
+#define ADDR_VERSION            (0x02 << 2)
 
 
 //------------------------------------------------------------------
 // Board segment.
 // Board-level registers and communication channel registers
 //------------------------------------------------------------------
-#define BOARD_ADDR_BASE         SEGMENT_OFFSET_GLOBALS + 0x0000
+#define BOARD_CORE_SIZE         (0x100 << 2)
+
+#define BOARD_ADDR_BASE         SEGMENT_OFFSET_GLOBALS + (0 * BOARD_CORE_SIZE)
 #define BOARD_ADDR_NAME0        BOARD_ADDR_BASE + ADDR_NAME0
 #define BOARD_ADDR_NAME1        BOARD_ADDR_BASE + ADDR_NAME1
 #define BOARD_ADDR_VERSION      BOARD_ADDR_BASE + ADDR_VERSION
 #define BOARD_ADDR_DUMMY        BOARD_ADDR_BASE + (0xFF << 2)
 
-#define COMM_ADDR_BASE          SEGMENT_OFFSET_GLOBALS + 0x0400
+#define COMM_ADDR_BASE          SEGMENT_OFFSET_GLOBALS + (1 * BOARD_CORE_SIZE)
 #define COMM_ADDR_NAME0         COMM_ADDR_BASE + ADDR_NAME0
 #define COMM_ADDR_NAME1         COMM_ADDR_BASE + ADDR_NAME1
 #define COMM_ADDR_VERSION       COMM_ADDR_BASE + ADDR_VERSION
 
+
+//------------------------------------------------------------------
+// Hashes segment.
+//------------------------------------------------------------------
+#define HASH_CORE_SIZE          (0x100 << 2)
+
 // addresses and codes common to all hash cores */
 #define ADDR_CTRL               (0x8 << 2)
 #define CTRL_INIT_CMD           1
@@ -77,16 +85,10 @@
 #define STATUS_READY_BIT        1
 #define STATUS_VALID_BIT        2
 #define ADDR_BLOCK              (0x10 << 2)
-#define ADDR_DIGEST             (0x20 << 2)
-
-
-//------------------------------------------------------------------
-// Hashes segment.
-//------------------------------------------------------------------
-#define HASH_CORE_SIZE          (0x100 << 2)
+#define ADDR_DIGEST             (0x20 << 2)    // except SHA512
 
 // addresses and codes for the specific hash cores.
-#define SHA1_ADDR_BASE          SEGMENT_OFFSET_HASHES + (0*HASH_CORE_SIZE)
+#define SHA1_ADDR_BASE          SEGMENT_OFFSET_HASHES + (0 * HASH_CORE_SIZE)
 #define SHA1_ADDR_NAME0         SHA1_ADDR_BASE + ADDR_NAME0
 #define SHA1_ADDR_NAME1         SHA1_ADDR_BASE + ADDR_NAME1
 #define SHA1_ADDR_VERSION       SHA1_ADDR_BASE + ADDR_VERSION
@@ -97,7 +99,7 @@
 #define SHA1_BLOCK_LEN          512 / 8
 #define SHA1_DIGEST_LEN         160 / 8
 
-#define SHA256_ADDR_BASE        SEGMENT_OFFSET_HASHES + (1*HASH_CORE_SIZE)
+#define SHA256_ADDR_BASE        SEGMENT_OFFSET_HASHES + (1 * HASH_CORE_SIZE)
 #define SHA256_ADDR_NAME0       SHA256_ADDR_BASE + ADDR_NAME0
 #define SHA256_ADDR_NAME1       SHA256_ADDR_BASE + ADDR_NAME1
 #define SHA256_ADDR_VERSION     SHA256_ADDR_BASE + ADDR_VERSION
@@ -108,14 +110,14 @@
 #define SHA256_BLOCK_LEN        512 / 8
 #define SHA256_DIGEST_LEN       256 / 8
 
-#define SHA512_ADDR_BASE        SEGMENT_OFFSET_HASHES + (2*HASH_CORE_SIZE)
+#define SHA512_ADDR_BASE        SEGMENT_OFFSET_HASHES + (2 * HASH_CORE_SIZE)
 #define SHA512_ADDR_NAME0       SHA512_ADDR_BASE + ADDR_NAME0
 #define SHA512_ADDR_NAME1       SHA512_ADDR_BASE + ADDR_NAME1
 #define SHA512_ADDR_VERSION     SHA512_ADDR_BASE + ADDR_VERSION
 #define SHA512_ADDR_CTRL        SHA512_ADDR_BASE + ADDR_CTRL
 #define SHA512_ADDR_STATUS      SHA512_ADDR_BASE + ADDR_STATUS
 #define SHA512_ADDR_BLOCK       SHA512_ADDR_BASE + ADDR_BLOCK
-#define SHA512_ADDR_DIGEST      SHA512_ADDR_BASE + 0x100
+#define SHA512_ADDR_DIGEST      SHA512_ADDR_BASE + (0x40 << 2)
 #define SHA512_BLOCK_LEN        1024 / 8
 #define SHA512_224_DIGEST_LEN   224 / 8
 #define SHA512_256_DIGEST_LEN   256 / 8
diff --git a/eim/sw/hash_tester_eim.c b/eim/sw/hash_tester_eim.c
index 1a37c11..75b0f1d 100644
--- a/eim/sw/hash_tester_eim.c
+++ b/eim/sw/hash_tester_eim.c
@@ -275,7 +275,7 @@ int TC0()
      */
     (void)time((time_t *)t);
     if (tc_write(BOARD_ADDR_DUMMY, (void *)&t, 4) != 0)
-	return 1;
+        return 1;
 
     if (tc_expected(BOARD_ADDR_NAME0,   board_name0,   4) ||
         tc_expected(BOARD_ADDR_NAME1,   board_name1,   4) ||
diff --git a/eim/sw/trng_extractor_eim.c b/eim/sw/trng_extractor_eim.c
new file mode 100644
index 0000000..e023c79
--- /dev/null
+++ b/eim/sw/trng_extractor_eim.c
@@ -0,0 +1,155 @@
+/*
+ * trng_extractor.c
+ * ----------------
+ * This program extracts raw data from the avalanche_entropy, rosc_entropy,
+ * and csprng cores.
+ *
+ * Author: Paul Selkirk
+ * Copyright (c) 2015, NORDUnet A/S All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ *
+ * - 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.
+ *
+ * - Neither the name of the NORDUnet nor the names of its contributors may
+ *   be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+ * HOLDER 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#include "tc_eim.h"
+#include "cryptech_memory_map.h"
+
+char *usage = 
+"%s [-a|r|c] [-n #] [-o file]\n\
+\n\
+-a      avalanche entropy\n\
+-r      rosc entropy\n\
+-c      csprng\n\
+-n      number of 4-byte samples (defaults to 10)\n\
+-o      output file (defaults to stdout)\n\
+";
+
+int debug = 0;          /* for dump() */
+
+/* extract one data sample */
+static int extract(off_t status_addr, off_t data_addr, uint32_t *data)
+{
+    if (tc_wait(status_addr, ENTROPY1_STATUS_VALID, NULL) != 0) {
+        fprintf(stderr, "tc_wait failed\n");
+        return 1;
+    }
+
+    if (tc_read(data_addr, (uint8_t *)data, 4) != 0) {
+        fprintf(stderr, "tc_read failed\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+/* main */
+int main(int argc, char *argv[])
+{
+    int i, opt, num_words = 10;
+    uint32_t data;
+    off_t status_addr = 0, data_addr = 0;
+    FILE *output = stdout;
+
+    /* parse command line */
+    while ((opt = getopt(argc, argv, "h?arcn:o:")) != -1) {
+        switch (opt) {
+        case 'h':
+        case '?':
+            printf(usage, argv[0]);
+            return EXIT_SUCCESS;
+        case 'a':
+            status_addr = ENTROPY1_ADDR_STATUS;
+            data_addr = ENTROPY1_ADDR_ENTROPY;
+            break;
+        case 'r':
+            status_addr = ENTROPY2_ADDR_STATUS;
+            data_addr = ENTROPY2_ADDR_ENTROPY;
+            break;
+        case 'c':
+            status_addr = CSPRNG_ADDR_STATUS;
+            data_addr = CSPRNG_ADDR_RANDOM;
+            break;
+        case 'n':
+            num_words = atoi(optarg);
+            if (num_words <= 0) {
+                fprintf(stderr, "-n requires a positive integer argument\n");
+                return EXIT_FAILURE;
+            }
+            break;
+        case 'o':
+            output = fopen(optarg, "wb+");
+            if (output == NULL) {
+                fprintf(stderr, "error opening output file %s: ", optarg);
+                perror("");
+                return EXIT_FAILURE;
+            }
+            break;
+        default:
+        errout:
+            fprintf(stderr, usage, argv[0]);
+            return EXIT_FAILURE;
+        }
+    }
+    if (optind < argc) {
+        fprintf(stderr, "%s: invalid argument%s --",
+                argv[0], argc - optind > 1 ? "s" : "");
+        do {
+            fprintf(stderr, " %s", argv[optind]);
+            ++optind;
+        } while (optind < argc);
+        fprintf(stderr, "\n");
+        goto errout;
+    }
+    if (status_addr == 0) {
+        fprintf(stderr, "%s: a data source must be specified\n", argv[0]);
+        goto errout;
+    }
+
+    /* set up EIM */
+    if (eim_setup() != 0) {
+        fprintf(stderr, "EIM setup failed\n");
+        return EXIT_FAILURE;
+    }
+
+    /* get the data */
+    for (i = 0; i < num_words; ++i) {
+        if (extract(status_addr, data_addr, &data) != 0)
+            return EXIT_FAILURE;
+        if (fwrite(&data, sizeof(data), 1, output) != 1) {
+            perror("fwrite");
+            fclose(output);
+            return EXIT_FAILURE;
+        }
+    }
+
+    fclose(output);
+    return EXIT_SUCCESS;
+}
diff --git a/eim/sw/trng_tester_eim.c b/eim/sw/trng_tester_eim.c
index 0cb9312..d25b784 100644
--- a/eim/sw/trng_tester_eim.c
+++ b/eim/sw/trng_tester_eim.c
@@ -50,13 +50,13 @@
 #include "tc_eim.h"
 #include "cryptech_memory_map.h"
 
-#define WAIT_STATS      /* report number of status reads before core says "ready" */
+char *usage = "Usage: %s [-h] [-d] [-q] [-r] [-w] [-n #] tc...\n";
 
 int debug = 0;
 int quiet = 0;
 int repeat = 0;
-int dump_data = 1;
 int num_words = 10;
+int wait_stats = 0;
 
 /* ---------------- sanity test case ---------------- */
 
@@ -80,7 +80,7 @@ int TC0()
      */
     (void)time((time_t *)t);
     if (tc_write(BOARD_ADDR_DUMMY, (void *)&t, 4) != 0)
-	return 1;
+        return 1;
 
     if (tc_expected(BOARD_ADDR_NAME0,   board_name0,   4) ||
         tc_expected(BOARD_ADDR_NAME1,   board_name1,   4) ||
@@ -142,26 +142,26 @@ int TC2(void)
 int TC3(void)
 {
     int i, n;
-    unsigned long entropy;
+    uint32_t entropy;
 
     if (!quiet)
         printf("TC3: Read random data from avalanche_entropy.\n");
 
     for (i = 0; i < num_words; ++i) {
         /* check status */
-	n = 0;
+        n = 0;
         if (tc_wait(ENTROPY1_ADDR_STATUS, ENTROPY1_STATUS_VALID, &n) != 0)
             return 1;
         /* read entropy data */
         if (tc_read(ENTROPY1_ADDR_ENTROPY, (uint8_t *)&entropy, 4) != 0)
             return 1;
         /* display entropy data */
-        if (!debug)
-#ifdef WAIT_STATS
-            printf("%08lx %d\n", entropy, n);
-#else
-            printf("%08lx\n", entropy);
-#endif
+        if (!debug) {
+            if (wait_stats)
+                printf("%08x %d\n", entropy, n);
+            else
+                printf("%08x\n", entropy);
+        }
     }
 
     return 0;
@@ -191,26 +191,26 @@ int TC4(void)
 int TC5(void)
 {
     int i, n;
-    unsigned long entropy;
+    uint32_t entropy;
 
     if (!quiet)
         printf("TC5: Read random data from rosc_entropy.\n");
 
     for (i = 0; i < num_words; ++i) {
         /* check status */
-	n = 0;
+        n = 0;
         if (tc_wait(ENTROPY2_ADDR_STATUS, ENTROPY2_STATUS_VALID, &n) != 0)
             return 1;
         /* read entropy data */
         if (tc_read(ENTROPY2_ADDR_ENTROPY, (uint8_t *)&entropy, 4) != 0)
             return 1;
         /* display entropy data */
-        if (!debug)
-#ifdef WAIT_STATS
-            printf("%08lx %d\n", entropy, n);
-#else
-            printf("%08lx\n", entropy);
-#endif
+        if (!debug) {
+            if (wait_stats)
+                printf("%08x %d\n", entropy, n);
+            else
+                printf("%08x\n", entropy);
+        }
     }
 
     return 0;
@@ -231,10 +231,7 @@ int TC6(void)
 /* TC7: Read random data from trng_csprng. */
 int TC7(void)
 {
-    int i;
-#ifdef WAIT_STATS
-    int n;
-#endif
+    int i, n;
     uint32_t random;
 
     if (!quiet)
@@ -242,33 +239,19 @@ int TC7(void)
 
     for (i = 0; i < num_words; ++i) {
         /* check status */
-#ifdef WAIT_STATS
-        if ((n = tc_wait(CSPRNG_ADDR_STATUS, CSPRNG_STATUS_VALID)) < 0)
-#else
-        if (tc_wait(CSPRNG_ADDR_STATUS, CSPRNG_STATUS_VALID) != 0)
-#endif
+        n = 0;
+        if (tc_wait(CSPRNG_ADDR_STATUS, CSPRNG_STATUS_VALID, &n) != 0)
             return 1;
         /* read random data */
         if (tc_read(CSPRNG_ADDR_RANDOM, (uint8_t *)&random, 4) != 0)
             return 1;
         /* display random data */
         if (!debug) {
-	  if (dump_data) {
-	    // Raw data output to std out.
-	    printf("%c%c%c%c", (int8_t)(random >> 24 & 0xff),
-				(int8_t)(random >> 16 & 0xff),
-				(int8_t)(random >> 8 & 0xff),
-		   (int8_t)(random & 0xff));
-	  }
-	  else
-	    {
-#ifdef WAIT_STATS
-            printf("0x%08x %d\n", random, n);
-#else
-            printf("0x%08x\n", random);
-#endif
-	    }
-	}
+            if (wait_stats)
+                printf("%08x %d\n", random, n);
+            else
+                printf("%08x\n", random);
+        }
     }
 
     return 0;
@@ -296,11 +279,9 @@ int main(int argc, char *argv[])
 {
     typedef int (*tcfp)(void);
     tcfp all_tests[] = { TC0, TC1, TC2, TC3, TC4, TC5, TC6, TC7 };
-
-    char *usage = "Usage: %s [-h] [-d] [-q] [-r] [-n #] tc...\n";
     int i, j, opt;
 
-    while ((opt = getopt(argc, argv, "h?dqrn:")) != -1) {
+    while ((opt = getopt(argc, argv, "h?dqrn:w")) != -1) {
         switch (opt) {
         case 'h':
         case '?':
@@ -322,6 +303,9 @@ int main(int argc, char *argv[])
                 return EXIT_FAILURE;
             }
             break;
+        case 'w':
+            wait_stats = 1;
+            break;
         default:
             fprintf(stderr, usage, argv[0]);
             return EXIT_FAILURE;
diff --git a/i2c/sw/Makefile b/i2c/sw/Makefile
index 02e7e7d..9869e04 100755
--- a/i2c/sw/Makefile
+++ b/i2c/sw/Makefile
@@ -1,4 +1,4 @@
-all: hash_tester_i2c trng_tester_i2c hash_i2c
+all: hash_tester_i2c trng_tester_i2c hash_i2c trng_extractor_i2c
 
 .c.o:
 	gcc -c -Wall -o $@ $<
@@ -18,7 +18,12 @@ hash_i2c: hash_i2c.o tc_i2c.o
 
 hash_i2c.o: hash_i2c.c tc_i2c.h
 
+trng_extractor_i2c: trng_extractor_i2c.o tc_i2c.o
+	gcc -o $@ $^
+
+trng_extractor_i2c.o: trng_extractor_i2c.c tc_i2c.h
+
 tc_i2c.o: tc_i2c.c tc_i2c.h
 
 clean:
-	rm -f *.o hash_tester_i2c trng_tester_i2c hash_i2c
+	rm -f *.o hash_tester_i2c trng_tester_i2c hash_i2c trng_extractor_i2c
diff --git a/eim/sw/cryptech_memory_map.h b/i2c/sw/cryptech_memory_map.h
similarity index 71%
copy from eim/sw/cryptech_memory_map.h
copy to i2c/sw/cryptech_memory_map.h
index c392584..cf5cb89 100644
--- a/eim/sw/cryptech_memory_map.h
+++ b/i2c/sw/cryptech_memory_map.h
@@ -36,57 +36,54 @@
 //
 //======================================================================
 
-// Include platform header and define base address based on platform.
-#include "novena-eim.h"
-#define CT_BASE_ADDR EIM_BASE_ADDR
-
-
 // Segments.
-#define SEGMENT_OFFSET_GLOBALS  EIM_BASE_ADDR + 0x000000
-#define SEGMENT_OFFSET_HASHES   EIM_BASE_ADDR + 0x010000
-#define SEGMENT_OFFSET_RNGS     EIM_BASE_ADDR + 0x020000
-#define SEGMENT_OFFSET_CIPHERS  EIM_BASE_ADDR + 0x030000
+#define SEGMENT_OFFSET_GLOBALS  0x0000
+#define SEGMENT_OFFSET_HASHES   0x2000
+#define SEGMENT_OFFSET_RNGS     0x4000
+#define SEGMENT_OFFSET_CIPHERS  0x6000
 
 
 // addresses and codes common to all cores
-#define ADDR_NAME0              (0x0 << 2)
-#define ADDR_NAME1              (0x1 << 2)
-#define ADDR_VERSION            (0x2 << 2)
+#define ADDR_NAME0              0x00
+#define ADDR_NAME1              0x01
+#define ADDR_VERSION            0x02
 
 
 //------------------------------------------------------------------
 // Board segment.
 // Board-level registers and communication channel registers
 //------------------------------------------------------------------
-#define BOARD_ADDR_BASE         SEGMENT_OFFSET_GLOBALS + 0x0000
+#define BOARD_CORE_SIZE         0x100
+
+#define BOARD_ADDR_BASE         SEGMENT_OFFSET_GLOBALS + (0 * BOARD_CORE_SIZE)
 #define BOARD_ADDR_NAME0        BOARD_ADDR_BASE + ADDR_NAME0
 #define BOARD_ADDR_NAME1        BOARD_ADDR_BASE + ADDR_NAME1
 #define BOARD_ADDR_VERSION      BOARD_ADDR_BASE + ADDR_VERSION
-#define BOARD_ADDR_DUMMY        BOARD_ADDR_BASE + (0xFF << 2)
+#define BOARD_ADDR_DUMMY        BOARD_ADDR_BASE + 0xFF
 
-#define COMM_ADDR_BASE          SEGMENT_OFFSET_GLOBALS + 0x0400
+#define COMM_ADDR_BASE          SEGMENT_OFFSET_GLOBALS + (1 * BOARD_CORE_SIZE)
 #define COMM_ADDR_NAME0         COMM_ADDR_BASE + ADDR_NAME0
 #define COMM_ADDR_NAME1         COMM_ADDR_BASE + ADDR_NAME1
 #define COMM_ADDR_VERSION       COMM_ADDR_BASE + ADDR_VERSION
 
+
+//------------------------------------------------------------------
+// Hashes segment.
+//------------------------------------------------------------------
+#define HASH_CORE_SIZE          0x100
+
 // addresses and codes common to all hash cores */
-#define ADDR_CTRL               (0x8 << 2)
+#define ADDR_CTRL               0x8
 #define CTRL_INIT_CMD           1
 #define CTRL_NEXT_CMD           2
-#define ADDR_STATUS             (9 << 2)
+#define ADDR_STATUS             9
 #define STATUS_READY_BIT        1
 #define STATUS_VALID_BIT        2
-#define ADDR_BLOCK              (0x10 << 2)
-#define ADDR_DIGEST             (0x20 << 2)
-
-
-//------------------------------------------------------------------
-// Hashes segment.
-//------------------------------------------------------------------
-#define HASH_CORE_SIZE          (0x100 << 2)
+#define ADDR_BLOCK              0x10
+#define ADDR_DIGEST             0x20    // except SHA512
 
 // addresses and codes for the specific hash cores.
-#define SHA1_ADDR_BASE          SEGMENT_OFFSET_HASHES + (0*HASH_CORE_SIZE)
+#define SHA1_ADDR_BASE          SEGMENT_OFFSET_HASHES + (0 * HASH_CORE_SIZE)
 #define SHA1_ADDR_NAME0         SHA1_ADDR_BASE + ADDR_NAME0
 #define SHA1_ADDR_NAME1         SHA1_ADDR_BASE + ADDR_NAME1
 #define SHA1_ADDR_VERSION       SHA1_ADDR_BASE + ADDR_VERSION
@@ -97,7 +94,7 @@
 #define SHA1_BLOCK_LEN          512 / 8
 #define SHA1_DIGEST_LEN         160 / 8
 
-#define SHA256_ADDR_BASE        SEGMENT_OFFSET_HASHES + (1*HASH_CORE_SIZE)
+#define SHA256_ADDR_BASE        SEGMENT_OFFSET_HASHES + (1 * HASH_CORE_SIZE)
 #define SHA256_ADDR_NAME0       SHA256_ADDR_BASE + ADDR_NAME0
 #define SHA256_ADDR_NAME1       SHA256_ADDR_BASE + ADDR_NAME1
 #define SHA256_ADDR_VERSION     SHA256_ADDR_BASE + ADDR_VERSION
@@ -108,14 +105,14 @@
 #define SHA256_BLOCK_LEN        512 / 8
 #define SHA256_DIGEST_LEN       256 / 8
 
-#define SHA512_ADDR_BASE        SEGMENT_OFFSET_HASHES + (2*HASH_CORE_SIZE)
+#define SHA512_ADDR_BASE        SEGMENT_OFFSET_HASHES + (2 * HASH_CORE_SIZE)
 #define SHA512_ADDR_NAME0       SHA512_ADDR_BASE + ADDR_NAME0
 #define SHA512_ADDR_NAME1       SHA512_ADDR_BASE + ADDR_NAME1
 #define SHA512_ADDR_VERSION     SHA512_ADDR_BASE + ADDR_VERSION
 #define SHA512_ADDR_CTRL        SHA512_ADDR_BASE + ADDR_CTRL
 #define SHA512_ADDR_STATUS      SHA512_ADDR_BASE + ADDR_STATUS
 #define SHA512_ADDR_BLOCK       SHA512_ADDR_BASE + ADDR_BLOCK
-#define SHA512_ADDR_DIGEST      SHA512_ADDR_BASE + 0x100
+#define SHA512_ADDR_DIGEST      SHA512_ADDR_BASE + 0x40
 #define SHA512_BLOCK_LEN        1024 / 8
 #define SHA512_224_DIGEST_LEN   224 / 8
 #define SHA512_256_DIGEST_LEN   256 / 8
@@ -130,69 +127,69 @@
 // -----------------------------------------------------------------
 // TRNG segment.
 // -----------------------------------------------------------------
-#define TRNG_CORE_SIZE               (0x100 << 2)
+#define TRNG_CORE_SIZE               0x100
 
 // addresses and codes for the TRNG cores */
 #define TRNG_ADDR_BASE          SEGMENT_OFFSET_RNGS + (0 * TRNG_CORE_SIZE)
 #define TRNG_ADDR_NAME0         TRNG_ADDR_BASE + ADDR_NAME0
 #define TRNG_ADDR_NAME1         TRNG_ADDR_BASE + ADDR_NAME1
 #define TRNG_ADDR_VERSION       TRNG_ADDR_BASE + ADDR_VERSION
-#define TRNG_ADDR_CTRL          TRNG_ADDR_BASE + (0x10 << 2)
+#define TRNG_ADDR_CTRL          TRNG_ADDR_BASE + 0x10
 #define TRNG_CTRL_DISCARD       1
 #define TRNG_CTRL_TEST_MODE     2
-#define TRNG_ADDR_STATUS        TRNG_ADDR_BASE + (0x11 << 2)
+#define TRNG_ADDR_STATUS        TRNG_ADDR_BASE + 0x11
 // no status bits defined (yet)
-#define TRNG_ADDR_DELAY         TRNG_ADDR_BASE + (0x13 << 2)
+#define TRNG_ADDR_DELAY         TRNG_ADDR_BASE + 0x13
 
 #define ENTROPY1_ADDR_BASE      SEGMENT_OFFSET_RNGS + (5 * TRNG_CORE_SIZE)
 #define ENTROPY1_ADDR_NAME0     ENTROPY1_ADDR_BASE + ADDR_NAME0
 #define ENTROPY1_ADDR_NAME1     ENTROPY1_ADDR_BASE + ADDR_NAME1
 #define ENTROPY1_ADDR_VERSION   ENTROPY1_ADDR_BASE + ADDR_VERSION
-#define ENTROPY1_ADDR_CTRL      ENTROPY1_ADDR_BASE + (0x10 << 2)
+#define ENTROPY1_ADDR_CTRL      ENTROPY1_ADDR_BASE + 0x10
 #define ENTROPY1_CTRL_ENABLE    1
-#define ENTROPY1_ADDR_STATUS    ENTROPY1_ADDR_BASE + (0x11 << 2)
+#define ENTROPY1_ADDR_STATUS    ENTROPY1_ADDR_BASE + 0x11
 #define ENTROPY1_STATUS_VALID   1
-#define ENTROPY1_ADDR_ENTROPY   ENTROPY1_ADDR_BASE + (0x20 << 2)
-#define ENTROPY1_ADDR_DELTA     ENTROPY1_ADDR_BASE + (0x30 << 2)
+#define ENTROPY1_ADDR_ENTROPY   ENTROPY1_ADDR_BASE + 0x20
+#define ENTROPY1_ADDR_DELTA     ENTROPY1_ADDR_BASE + 0x30
 
 #define ENTROPY2_ADDR_BASE      SEGMENT_OFFSET_RNGS + (6 * TRNG_CORE_SIZE)
 #define ENTROPY2_ADDR_NAME0     ENTROPY2_ADDR_BASE + ADDR_NAME0
 #define ENTROPY2_ADDR_NAME1     ENTROPY2_ADDR_BASE + ADDR_NAME1
 #define ENTROPY2_ADDR_VERSION   ENTROPY2_ADDR_BASE + ADDR_VERSION
-#define ENTROPY2_ADDR_CTRL      ENTROPY2_ADDR_BASE + (0x10 << 2)
+#define ENTROPY2_ADDR_CTRL      ENTROPY2_ADDR_BASE + 0x10
 #define ENTROPY2_CTRL_ENABLE    1
-#define ENTROPY2_ADDR_STATUS    ENTROPY2_ADDR_BASE + (0x11 << 2)
+#define ENTROPY2_ADDR_STATUS    ENTROPY2_ADDR_BASE + 0x11
 #define ENTROPY2_STATUS_VALID   1
-#define ENTROPY2_ADDR_OPA       ENTROPY2_ADDR_BASE + (0x18 << 2)
-#define ENTROPY2_ADDR_OPB       ENTROPY2_ADDR_BASE + (0x19 << 2)
-#define ENTROPY2_ADDR_ENTROPY   ENTROPY2_ADDR_BASE + (0x20 << 2)
-#define ENTROPY2_ADDR_RAW       ENTROPY2_ADDR_BASE + (0x21 << 2)
-#define ENTROPY2_ADDR_ROSC      ENTROPY2_ADDR_BASE + (0x22 << 2)
+#define ENTROPY2_ADDR_OPA       ENTROPY2_ADDR_BASE + 0x18
+#define ENTROPY2_ADDR_OPB       ENTROPY2_ADDR_BASE + 0x19
+#define ENTROPY2_ADDR_ENTROPY   ENTROPY2_ADDR_BASE + 0x20
+#define ENTROPY2_ADDR_RAW       ENTROPY2_ADDR_BASE + 0x21
+#define ENTROPY2_ADDR_ROSC      ENTROPY2_ADDR_BASE + 0x22
 
 #define MIXER_ADDR_BASE         SEGMENT_OFFSET_RNGS + (0x0a * TRNG_CORE_SIZE)
 #define MIXER_ADDR_NAME0        MIXER_ADDR_BASE + ADDR_NAME0
 #define MIXER_ADDR_NAME1        MIXER_ADDR_BASE + ADDR_NAME1
 #define MIXER_ADDR_VERSION      MIXER_ADDR_BASE + ADDR_VERSION
-#define MIXER_ADDR_CTRL         MIXER_ADDR_BASE + (0x10 << 2)
+#define MIXER_ADDR_CTRL         MIXER_ADDR_BASE + 0x10
 #define MIXER_CTRL_ENABLE       1
 #define MIXER_CTRL_RESTART      2
-#define MIXER_ADDR_STATUS       MIXER_ADDR_BASE + (0x11 << 2)
+#define MIXER_ADDR_STATUS       MIXER_ADDR_BASE + 0x11
 // no status bits defined (yet)
-#define MIXER_ADDR_TIMEOUT      MIXER_ADDR_BASE + (0x20 << 2)
+#define MIXER_ADDR_TIMEOUT      MIXER_ADDR_BASE + 0x20
 
 #define CSPRNG_ADDR_BASE        SEGMENT_OFFSET_RNGS + (0x0b * TRNG_CORE_SIZE)
 #define CSPRNG_ADDR_NAME0       CSPRNG_ADDR_BASE + ADDR_NAME0
 #define CSPRNG_ADDR_NAME1       CSPRNG_ADDR_BASE + ADDR_NAME1
 #define CSPRNG_ADDR_VERSION     CSPRNG_ADDR_BASE + ADDR_VERSION
-#define CSPRNG_ADDR_CTRL        CSPRNG_ADDR_BASE + (0x10 << 2)
+#define CSPRNG_ADDR_CTRL        CSPRNG_ADDR_BASE + 0x10
 #define CSPRNG_CTRL_ENABLE      1
 #define CSPRNG_CTRL_SEED        2
-#define CSPRNG_ADDR_STATUS      CSPRNG_ADDR_BASE + (0x11 << 2)
+#define CSPRNG_ADDR_STATUS      CSPRNG_ADDR_BASE + 0x11
 #define CSPRNG_STATUS_VALID     1
-#define CSPRNG_ADDR_RANDOM      CSPRNG_ADDR_BASE + (0x20 << 2)
-#define CSPRNG_ADDR_NROUNDS     CSPRNG_ADDR_BASE + (0x40 << 2)
-#define CSPRNG_ADDR_NBLOCKS_LO  CSPRNG_ADDR_BASE + (0x41 << 2)
-#define CSPRNG_ADDR_NBLOCKS_HI  CSPRNG_ADDR_BASE + (0x42 << 2)
+#define CSPRNG_ADDR_RANDOM      CSPRNG_ADDR_BASE + 0x20
+#define CSPRNG_ADDR_NROUNDS     CSPRNG_ADDR_BASE + 0x40
+#define CSPRNG_ADDR_NBLOCKS_LO  CSPRNG_ADDR_BASE + 0x41
+#define CSPRNG_ADDR_NBLOCKS_HI  CSPRNG_ADDR_BASE + 0x42
 
 //======================================================================
 // EOF cryptech_memory_map.h
diff --git a/i2c/sw/hash_i2c.c b/i2c/sw/hash_i2c.c
index c3ca013..04006d3 100644
--- a/i2c/sw/hash_i2c.c
+++ b/i2c/sw/hash_i2c.c
@@ -1,13 +1,13 @@
-/* 
+/*
  * hash.c
  * ------
  * This program uses the coretest_hashes subsystem to produce a
  * cryptographic hash of a file or input stream. It is a generalization
  * of the hash_tester.c test program.
- * 
+ *
  * Authors: Joachim Strömbergson, Paul Selkirk
  * Copyright (c) 2014-2015, NORDUnet A/S All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
  * met:
@@ -46,8 +46,9 @@
 #include <assert.h>
 
 #include "tc_i2c.h"
+#include "cryptech_memory_map.h"
 
-char *usage = 
+char *usage =
 "Usage: %s [-d] [-v] [-q] [-i I2C_device] [-a I2C_addr] [algorithm [file]]\n"
 "algorithms: sha-1, sha-256, sha-512/224, sha-512/256, sha-384, sha-512\n";
 
@@ -55,81 +56,6 @@ int debug = 0;
 int quiet = 0;
 int verbose = 0;
 
-/* memory segments for core families */
-#define SEGMENT_OFFSET_GLOBALS  0x0000
-#define SEGMENT_OFFSET_HASHES   0x2000
-#define SEGMENT_OFFSET_RNGS     0x4000
-#define SEGMENT_OFFSET_CIPHERS  0x6000
-
-#define CORE_SIZE               0x100
-
-/* addresses and codes common to all cores */
-#define ADDR_NAME0              0x00
-#define ADDR_NAME1              0x01
-#define ADDR_VERSION            0x02
-
-/* At segment 0, we have board-level register and communication channel registers */
-#define BOARD_ADDR_BASE         SEGMENT_OFFSET_GLOBALS + (0x00 * CORE_SIZE)
-#define BOARD_ADDR_NAME0        BOARD_ADDR_BASE + ADDR_NAME0
-#define BOARD_ADDR_NAME1        BOARD_ADDR_BASE + ADDR_NAME1
-#define BOARD_ADDR_VERSION      BOARD_ADDR_BASE + ADDR_VERSION
-#define BOARD_ADDR_DUMMY        BOARD_ADDR_BASE + 0xFF
-
-#define COMM_ADDR_BASE          SEGMENT_OFFSET_GLOBALS + (0x01 * CORE_SIZE)
-#define COMM_ADDR_NAME0         COMM_ADDR_BASE + ADDR_NAME0
-#define COMM_ADDR_NAME1         COMM_ADDR_BASE + ADDR_NAME1
-#define COMM_ADDR_VERSION       COMM_ADDR_BASE + ADDR_VERSION
-
-/* addresses and codes common to all hash cores */
-#define ADDR_CTRL               0x08
-#define CTRL_INIT_CMD           1
-#define CTRL_NEXT_CMD           2
-#define ADDR_STATUS             0x09
-#define STATUS_READY_BIT        1
-#define STATUS_VALID_BIT        2
-#define ADDR_BLOCK              0x10
-#define ADDR_DIGEST             0x20
-
-/* addresses and codes for the specific hash cores */
-#define SHA1_ADDR_BASE          SEGMENT_OFFSET_HASHES + (0*CORE_SIZE)
-#define SHA1_ADDR_NAME0         SHA1_ADDR_BASE + ADDR_NAME0
-#define SHA1_ADDR_NAME1         SHA1_ADDR_BASE + ADDR_NAME1
-#define SHA1_ADDR_VERSION       SHA1_ADDR_BASE + ADDR_VERSION
-#define SHA1_ADDR_CTRL          SHA1_ADDR_BASE + ADDR_CTRL
-#define SHA1_ADDR_STATUS        SHA1_ADDR_BASE + ADDR_STATUS
-#define SHA1_ADDR_BLOCK         SHA1_ADDR_BASE + ADDR_BLOCK
-#define SHA1_ADDR_DIGEST        SHA1_ADDR_BASE + ADDR_DIGEST
-#define SHA1_BLOCK_LEN          512 / 8
-#define SHA1_DIGEST_LEN         160 / 8
-
-#define SHA256_ADDR_BASE        SEGMENT_OFFSET_HASHES + (1*CORE_SIZE)
-#define SHA256_ADDR_NAME0       SHA256_ADDR_BASE + ADDR_NAME0
-#define SHA256_ADDR_NAME1       SHA256_ADDR_BASE + ADDR_NAME1
-#define SHA256_ADDR_VERSION     SHA256_ADDR_BASE + ADDR_VERSION
-#define SHA256_ADDR_CTRL        SHA256_ADDR_BASE + ADDR_CTRL
-#define SHA256_ADDR_STATUS      SHA256_ADDR_BASE + ADDR_STATUS
-#define SHA256_ADDR_BLOCK       SHA256_ADDR_BASE + ADDR_BLOCK
-#define SHA256_ADDR_DIGEST      SHA256_ADDR_BASE + ADDR_DIGEST
-#define SHA256_BLOCK_LEN        512 / 8
-#define SHA256_DIGEST_LEN       256 / 8
-
-#define SHA512_ADDR_BASE        SEGMENT_OFFSET_HASHES + (2*CORE_SIZE)
-#define SHA512_ADDR_NAME0       SHA512_ADDR_BASE + ADDR_NAME0
-#define SHA512_ADDR_NAME1       SHA512_ADDR_BASE + ADDR_NAME1
-#define SHA512_ADDR_VERSION     SHA512_ADDR_BASE + ADDR_VERSION
-#define SHA512_ADDR_CTRL        SHA512_ADDR_BASE + ADDR_CTRL
-#define SHA512_ADDR_STATUS      SHA512_ADDR_BASE + ADDR_STATUS
-#define SHA512_ADDR_BLOCK       SHA512_ADDR_BASE + ADDR_BLOCK
-#define SHA512_ADDR_DIGEST      SHA512_ADDR_BASE + 0x40
-#define SHA512_BLOCK_LEN        1024 / 8
-#define SHA512_224_DIGEST_LEN   224 / 8
-#define SHA512_256_DIGEST_LEN   256 / 8
-#define SHA384_DIGEST_LEN       384 / 8
-#define SHA512_DIGEST_LEN       512 / 8
-#define MODE_SHA_512_224        0 << 2
-#define MODE_SHA_512_256        1 << 2
-#define MODE_SHA_384            2 << 2
-#define MODE_SHA_512            3 << 2
 
 /* ---------------- algorithm lookup code ---------------- */
 
@@ -205,15 +131,15 @@ int transmit(off_t offset, uint8_t *block, int blen, int mode, int first)
     off_t base = offset & ~(0xff);
 
     if (tc_write(offset, block, blen) != 0)
-        return EXIT_FAILURE;
+        return 1;
 
     if (first) {
         if (tc_init(base + ADDR_CTRL, mode) != 0)
-            return EXIT_FAILURE;
+            return 1;
     }
     else {
         if (tc_next(base + ADDR_CTRL, mode) != 0)
-            return EXIT_FAILURE;
+            return 1;
     }
 
     return tc_wait_ready(base + ADDR_STATUS);
@@ -229,7 +155,7 @@ int pad_transmit(off_t offset, uint8_t *block, uint8_t flen, uint8_t blen,
 
     if (blen - flen < ((blen == 64) ? 8 : 16)) {
         if (transmit(offset, block, blen, mode, first) != 0)
-            return EXIT_FAILURE;
+            return 1;
         first = 0;
         memset(block, 0, blen);
     }
diff --git a/i2c/sw/hash_tester_i2c.c b/i2c/sw/hash_tester_i2c.c
index dc02691..c9b8f5f 100644
--- a/i2c/sw/hash_tester_i2c.c
+++ b/i2c/sw/hash_tester_i2c.c
@@ -1,4 +1,4 @@
-/* 
+/*
  * hash_tester.c
  * --------------
  * This program sends several commands to the coretest_hashes subsystem
@@ -11,10 +11,10 @@
  * NIST KAT document:
  * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf
  *
- * 
+ *
  * Authors: Joachim Strömbergson, Paul Selkirk
  * Copyright (c) 2014-2015, NORDUnet A/S All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
  * met:
@@ -51,85 +51,11 @@
 #include <ctype.h>
 
 #include "tc_i2c.h"
+#include "cryptech_memory_map.h"
 
 int debug = 0;
 int quiet = 0;
 
-/* memory segments for core families */
-#define SEGMENT_OFFSET_GLOBALS  0x0000
-#define SEGMENT_OFFSET_HASHES   0x2000
-#define SEGMENT_OFFSET_RNGS     0x4000
-#define SEGMENT_OFFSET_CIPHERS  0x6000
-
-#define CORE_SIZE               0x100
-
-/* addresses and codes common to all cores */
-#define ADDR_NAME0              0x00
-#define ADDR_NAME1              0x01
-#define ADDR_VERSION            0x02
-
-/* At segment 0, we have board-level register and communication channel registers */
-#define BOARD_ADDR_BASE         SEGMENT_OFFSET_GLOBALS + (0x00 * CORE_SIZE)
-#define BOARD_ADDR_NAME0        BOARD_ADDR_BASE + ADDR_NAME0
-#define BOARD_ADDR_NAME1        BOARD_ADDR_BASE + ADDR_NAME1
-#define BOARD_ADDR_VERSION      BOARD_ADDR_BASE + ADDR_VERSION
-#define BOARD_ADDR_DUMMY        BOARD_ADDR_BASE + 0xFF
-
-#define COMM_ADDR_BASE          SEGMENT_OFFSET_GLOBALS + (0x01 * CORE_SIZE)
-#define COMM_ADDR_NAME0         COMM_ADDR_BASE + ADDR_NAME0
-#define COMM_ADDR_NAME1         COMM_ADDR_BASE + ADDR_NAME1
-#define COMM_ADDR_VERSION       COMM_ADDR_BASE + ADDR_VERSION
-
-/* addresses and codes common to all hash cores */
-#define ADDR_CTRL               0x08
-#define CTRL_INIT_CMD           1
-#define CTRL_NEXT_CMD           2
-#define ADDR_STATUS             0x09
-#define STATUS_READY_BIT        1
-#define STATUS_VALID_BIT        2
-#define ADDR_BLOCK              0x10
-#define ADDR_DIGEST             0x20
-
-/* addresses and codes for the specific hash cores */
-#define SHA1_ADDR_BASE          SEGMENT_OFFSET_HASHES + (0*CORE_SIZE)
-#define SHA1_ADDR_NAME0         SHA1_ADDR_BASE + ADDR_NAME0
-#define SHA1_ADDR_NAME1         SHA1_ADDR_BASE + ADDR_NAME1
-#define SHA1_ADDR_VERSION       SHA1_ADDR_BASE + ADDR_VERSION
-#define SHA1_ADDR_CTRL          SHA1_ADDR_BASE + ADDR_CTRL
-#define SHA1_ADDR_STATUS        SHA1_ADDR_BASE + ADDR_STATUS
-#define SHA1_ADDR_BLOCK         SHA1_ADDR_BASE + ADDR_BLOCK
-#define SHA1_ADDR_DIGEST        SHA1_ADDR_BASE + ADDR_DIGEST
-#define SHA1_BLOCK_LEN          512 / 8
-#define SHA1_DIGEST_LEN         160 / 8
-
-#define SHA256_ADDR_BASE        SEGMENT_OFFSET_HASHES + (1*CORE_SIZE)
-#define SHA256_ADDR_NAME0       SHA256_ADDR_BASE + ADDR_NAME0
-#define SHA256_ADDR_NAME1       SHA256_ADDR_BASE + ADDR_NAME1
-#define SHA256_ADDR_VERSION     SHA256_ADDR_BASE + ADDR_VERSION
-#define SHA256_ADDR_CTRL        SHA256_ADDR_BASE + ADDR_CTRL
-#define SHA256_ADDR_STATUS      SHA256_ADDR_BASE + ADDR_STATUS
-#define SHA256_ADDR_BLOCK       SHA256_ADDR_BASE + ADDR_BLOCK
-#define SHA256_ADDR_DIGEST      SHA256_ADDR_BASE + ADDR_DIGEST
-#define SHA256_BLOCK_LEN        512 / 8
-#define SHA256_DIGEST_LEN       256 / 8
-
-#define SHA512_ADDR_BASE        SEGMENT_OFFSET_HASHES + (2*CORE_SIZE)
-#define SHA512_ADDR_NAME0       SHA512_ADDR_BASE + ADDR_NAME0
-#define SHA512_ADDR_NAME1       SHA512_ADDR_BASE + ADDR_NAME1
-#define SHA512_ADDR_VERSION     SHA512_ADDR_BASE + ADDR_VERSION
-#define SHA512_ADDR_CTRL        SHA512_ADDR_BASE + ADDR_CTRL
-#define SHA512_ADDR_STATUS      SHA512_ADDR_BASE + ADDR_STATUS
-#define SHA512_ADDR_BLOCK       SHA512_ADDR_BASE + ADDR_BLOCK
-#define SHA512_ADDR_DIGEST      SHA512_ADDR_BASE + 0x0
-#define SHA512_BLOCK_LEN        1024 / 8
-#define SHA512_224_DIGEST_LEN   224 / 8
-#define SHA512_256_DIGEST_LEN   256 / 8
-#define SHA384_DIGEST_LEN       384 / 8
-#define SHA512_DIGEST_LEN       512 / 8
-#define MODE_SHA_512_224        0 << 2
-#define MODE_SHA_512_256        1 << 2
-#define MODE_SHA_384            2 << 2
-#define MODE_SHA_512            3 << 2
 
 /* SHA-1/SHA-256 One Block Message Sample
    Input Message: "abc" */
@@ -271,7 +197,7 @@ const uint8_t NIST_1024_DOUBLE1[] =
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80 };
 
-const uint8_t SHA512_224_DOUBLE_DIGEST[] = 
+const uint8_t SHA512_224_DOUBLE_DIGEST[] =
 { 0x23, 0xfe, 0xc5, 0xbb, 0x94, 0xd6, 0x0b, 0x23,
   0x30, 0x81, 0x92, 0x64, 0x0b, 0x0c, 0x45, 0x33,
   0x35, 0xd6, 0x64, 0x73, 0x4f, 0xe4, 0x0e, 0x72,
@@ -348,7 +274,7 @@ int TC0()
      */
     (void)time((time_t *)t);
     if (tc_write(BOARD_ADDR_DUMMY, t, 4) != 0)
-	return 1;
+        return 1;
 
     if (tc_expected(BOARD_ADDR_NAME0,   board_name0, 4) ||
         tc_expected(BOARD_ADDR_NAME1,   board_name1, 4) ||
@@ -475,7 +401,7 @@ int TC5()
 int TC6()
 {
     const uint8_t *block[2] = { NIST_512_DOUBLE0, NIST_512_DOUBLE1 };
-    static const uint8_t block0_expected[] = 
+    static const uint8_t block0_expected[] =
         { 0x85, 0xE6, 0x55, 0xD6, 0x41, 0x7A, 0x17, 0x95,
           0x33, 0x63, 0x37, 0x6A, 0x62, 0x4C, 0xDE, 0x5C,
           0x76, 0xE0, 0x95, 0x89, 0xCA, 0xC5, 0xF8, 0x11,
@@ -516,7 +442,7 @@ int TC7()
           0x55, 0xaa, 0x55, 0xaa, 0xf0, 0x0f, 0xf0, 0x0f };
 
     /* final digest after 1000 iterations */
-    static const uint8_t expected[] = 
+    static const uint8_t expected[] =
         { 0x76, 0x38, 0xf3, 0xbc, 0x50, 0x0d, 0xd1, 0xa6,
           0x58, 0x6d, 0xd4, 0xd0, 0x1a, 0x15, 0x51, 0xaf,
           0xd8, 0x21, 0xd2, 0x35, 0x2f, 0x91, 0x9e, 0x28,
@@ -679,7 +605,7 @@ int main(int argc, char *argv[])
         case 'h':
         case '?':
             printf(usage, argv[0]);
-            return 0;
+            return EXIT_SUCCESS;
         case 'd':
             debug = 1;
             break;
@@ -693,7 +619,7 @@ int main(int argc, char *argv[])
             addr = (int)strtol(optarg, NULL, 0);
             if ((addr < 0x03) || (addr > 0x77)) {
                 fprintf(stderr, "addr must be between 0x03 and 0x77\n");
-                return 1;
+                return EXIT_FAILURE;
             }
             break;
         default:
@@ -702,8 +628,9 @@ int main(int argc, char *argv[])
         }
     }
 
+    /* set up I2C */
     if (i2c_open(dev, addr) != 0)
-        return 1;
+        return EXIT_FAILURE;
 
     /* no args == run all tests */
     if (optind >= argc) {
diff --git a/i2c/sw/trng_extractor_i2c.c b/i2c/sw/trng_extractor_i2c.c
new file mode 100644
index 0000000..29f054c
--- /dev/null
+++ b/i2c/sw/trng_extractor_i2c.c
@@ -0,0 +1,167 @@
+/*
+ * trng_extractor.c
+ * ----------------
+ * This program extracts raw data from the avalanche_entropy, rosc_entropy,
+ * and csprng cores.
+ *
+ * Author: Paul Selkirk
+ * Copyright (c) 2015, NORDUnet A/S All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ *
+ * - 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.
+ *
+ * - Neither the name of the NORDUnet nor the names of its contributors may
+ *   be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+ * HOLDER 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#include "tc_i2c.h"
+#include "cryptech_memory_map.h"
+
+char *usage = 
+"%s [-a|r|c] [-n #] [-o file] [-I I2C_device] [-A I2C_addr]\n\
+\n\
+-a      avalanche entropy\n\
+-r      rosc entropy\n\
+-c      csprng\n\
+-n      number of 4-byte samples (defaults to 10)\n\
+-o      output file (defaults to stdout)\n\
+";
+
+int debug = 0;          /* for dump() */
+
+/* extract one data sample */
+static int extract(off_t status_addr, off_t data_addr, uint32_t *data)
+{
+    if (tc_wait(status_addr, ENTROPY1_STATUS_VALID, NULL) != 0) {
+        fprintf(stderr, "tc_wait failed\n");
+        return 1;
+    }
+
+    if (tc_read(data_addr, (uint8_t *)data, 4) != 0) {
+        fprintf(stderr, "tc_read failed\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+/* main */
+int main(int argc, char *argv[])
+{
+    int i, opt, num_words = 10;
+    uint32_t data;
+    off_t status_addr = 0, data_addr = 0;
+    FILE *output = stdout;
+    char *dev = I2C_dev;
+    int addr = I2C_addr;
+
+    /* parse command line */
+    while ((opt = getopt(argc, argv, "h?arcn:o:I:A:")) != -1) {
+        switch (opt) {
+        case 'h':
+        case '?':
+            printf(usage, argv[0]);
+            return EXIT_SUCCESS;
+        case 'a':
+            status_addr = ENTROPY1_ADDR_STATUS;
+            data_addr = ENTROPY1_ADDR_ENTROPY;
+            break;
+        case 'r':
+            status_addr = ENTROPY2_ADDR_STATUS;
+            data_addr = ENTROPY2_ADDR_ENTROPY;
+            break;
+        case 'c':
+            status_addr = CSPRNG_ADDR_STATUS;
+            data_addr = CSPRNG_ADDR_RANDOM;
+            break;
+        case 'n':
+            num_words = atoi(optarg);
+            if (num_words <= 0) {
+                fprintf(stderr, "-n requires a positive integer argument\n");
+                return EXIT_FAILURE;
+            }
+            break;
+        case 'o':
+            output = fopen(optarg, "wb+");
+            if (output == NULL) {
+                fprintf(stderr, "error opening output file %s: ", optarg);
+                perror("");
+                return EXIT_FAILURE;
+            }
+            break;
+        case 'I':
+            dev = optarg;
+            break;
+        case 'A':
+            addr = (int)strtol(optarg, NULL, 0);
+            if ((addr < 0x03) || (addr > 0x77)) {
+                fprintf(stderr, "addr must be between 0x03 and 0x77\n");
+                return 1;
+            }
+            break;
+        default:
+        errout:
+            fprintf(stderr, usage, argv[0]);
+            return EXIT_FAILURE;
+        }
+    }
+    if (optind < argc) {
+        fprintf(stderr, "%s: invalid argument%s --",
+                argv[0], argc - optind > 1 ? "s" : "");
+        do {
+            fprintf(stderr, " %s", argv[optind]);
+            ++optind;
+        } while (optind < argc);
+        fprintf(stderr, "\n");
+        goto errout;
+    }
+    if (status_addr == 0) {
+        fprintf(stderr, "%s: a data source must be specified\n", argv[0]);
+        goto errout;
+    }
+
+    /* set up I2C */
+    if (i2c_open(dev, addr) != 0) {
+        fprintf(stderr, "I2C setup failed\n");
+        return EXIT_FAILURE;
+    }
+
+    /* get the data */
+    for (i = 0; i < num_words; ++i) {
+        if (extract(status_addr, data_addr, &data) != 0)
+            return EXIT_FAILURE;
+        if (fwrite(&data, sizeof(data), 1, output) != 1) {
+            perror("fwrite");
+            fclose(output);
+            return EXIT_FAILURE;
+        }
+    }
+
+    fclose(output);
+    return EXIT_SUCCESS;
+}
diff --git a/i2c/sw/trng_tester_i2c.c b/i2c/sw/trng_tester_i2c.c
index a38f7fa..a5dfb81 100644
--- a/i2c/sw/trng_tester_i2c.c
+++ b/i2c/sw/trng_tester_i2c.c
@@ -1,4 +1,4 @@
-/* 
+/*
  * trng_tester.c
  * --------------
  * This program sends several commands to the TRNG subsystem
@@ -9,7 +9,7 @@
  * 
  * Author: Paul Selkirk
  * Copyright (c) 2014-2015, NORDUnet A/S All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
  * met:
@@ -46,99 +46,14 @@
 #include <ctype.h>
 
 #include "tc_i2c.h"
+#include "cryptech_memory_map.h"
 
-#define WAIT_STATS      /* report number of status reads before core says "ready" */
+char *usage = "Usage: %s [-h] [-d] [-q] [-w] [-n #] [-i I2C_device] [-a I2C_addr] tc...\n";
 
 int debug = 0;
 int quiet = 0;
 int num_words = 10;
-
-/* memory segments for core families */
-#define SEGMENT_OFFSET_GLOBALS  0x0000
-#define SEGMENT_OFFSET_HASHES   0x2000
-#define SEGMENT_OFFSET_RNGS     0x4000
-#define SEGMENT_OFFSET_CIPHERS  0x6000
-
-/* addresses and codes common to all cores */
-#define ADDR_NAME0              0x00
-#define ADDR_NAME1              0x01
-#define ADDR_VERSION            0x02
-
-/* At segment 0, we have board-level register and communication channel registers */
-#define BOARD_ADDR_BASE         SEGMENT_OFFSET_GLOBALS + 0x0000
-#define BOARD_ADDR_NAME0        BOARD_ADDR_BASE + ADDR_NAME0
-#define BOARD_ADDR_NAME1        BOARD_ADDR_BASE + ADDR_NAME1
-#define BOARD_ADDR_VERSION      BOARD_ADDR_BASE + ADDR_VERSION
-#define BOARD_ADDR_DUMMY        BOARD_ADDR_BASE + 0xFF
-
-#define COMM_ADDR_BASE          SEGMENT_OFFSET_GLOBALS + 0x0100
-#define COMM_ADDR_NAME0         COMM_ADDR_BASE + ADDR_NAME0
-#define COMM_ADDR_NAME1         COMM_ADDR_BASE + ADDR_NAME1
-#define COMM_ADDR_VERSION       COMM_ADDR_BASE + ADDR_VERSION
-
-#define CORE_SIZE                0x100
-
-/* addresses and codes for the TRNG cores */
-#define TRNG_ADDR_BASE          SEGMENT_OFFSET_RNGS + (0x00 * CORE_SIZE)
-#define TRNG_ADDR_NAME0         TRNG_ADDR_BASE + ADDR_NAME0
-#define TRNG_ADDR_NAME1         TRNG_ADDR_BASE + ADDR_NAME1
-#define TRNG_ADDR_VERSION       TRNG_ADDR_BASE + ADDR_VERSION
-#define TRNG_ADDR_CTRL          TRNG_ADDR_BASE + 0x10
-#define TRNG_CTRL_DISCARD       1
-#define TRNG_CTRL_TEST_MODE     2
-#define TRNG_ADDR_STATUS        TRNG_ADDR_BASE + 0x11
-/* no status bits defined */
-#define TRNG_ADDR_DELAY         TRNG_ADDR_BASE + 0x13
-
-#define ENTROPY1_ADDR_BASE      SEGMENT_OFFSET_RNGS + (0x05 * CORE_SIZE)
-#define ENTROPY1_ADDR_NAME0     ENTROPY1_ADDR_BASE + ADDR_NAME0
-#define ENTROPY1_ADDR_NAME1     ENTROPY1_ADDR_BASE + ADDR_NAME1
-#define ENTROPY1_ADDR_VERSION   ENTROPY1_ADDR_BASE + ADDR_VERSION
-#define ENTROPY1_ADDR_CTRL      ENTROPY1_ADDR_BASE + 0x10
-#define ENTROPY1_CTRL_ENABLE    1
-#define ENTROPY1_ADDR_STATUS    ENTROPY1_ADDR_BASE + 0x11
-#define ENTROPY1_STATUS_VALID   1
-#define ENTROPY1_ADDR_ENTROPY   ENTROPY1_ADDR_BASE + 0x20
-#define ENTROPY1_ADDR_DELTA     ENTROPY1_ADDR_BASE + 0x30
-
-#define ENTROPY2_ADDR_BASE      SEGMENT_OFFSET_RNGS + (0x06 * CORE_SIZE)
-#define ENTROPY2_ADDR_NAME0     ENTROPY2_ADDR_BASE + ADDR_NAME0
-#define ENTROPY2_ADDR_NAME1     ENTROPY2_ADDR_BASE + ADDR_NAME1
-#define ENTROPY2_ADDR_VERSION   ENTROPY2_ADDR_BASE + ADDR_VERSION
-#define ENTROPY2_ADDR_CTRL      ENTROPY2_ADDR_BASE + 0x10
-#define ENTROPY2_CTRL_ENABLE    1
-#define ENTROPY2_ADDR_STATUS    ENTROPY2_ADDR_BASE + 0x11
-#define ENTROPY2_STATUS_VALID   1
-#define ENTROPY2_ADDR_OPA       ENTROPY2_ADDR_BASE + 0x18
-#define ENTROPY2_ADDR_OPB       ENTROPY2_ADDR_BASE + 0x19
-#define ENTROPY2_ADDR_ENTROPY   ENTROPY2_ADDR_BASE + 0x20
-#define ENTROPY2_ADDR_RAW       ENTROPY2_ADDR_BASE + 0x21
-#define ENTROPY2_ADDR_ROSC      ENTROPY2_ADDR_BASE + 0x22
-
-#define MIXER_ADDR_BASE         SEGMENT_OFFSET_RNGS + (0x0a * CORE_SIZE)
-#define MIXER_ADDR_NAME0        MIXER_ADDR_BASE + ADDR_NAME0
-#define MIXER_ADDR_NAME1        MIXER_ADDR_BASE + ADDR_NAME1
-#define MIXER_ADDR_VERSION      MIXER_ADDR_BASE + ADDR_VERSION
-#define MIXER_ADDR_CTRL         MIXER_ADDR_BASE + 0x10
-#define MIXER_CTRL_ENABLE       1
-#define MIXER_CTRL_RESTART      2
-#define MIXER_ADDR_STATUS       MIXER_ADDR_BASE + 0x11
-/* no status bits defined */
-#define MIXER_ADDR_TIMEOUT      MIXER_ADDR_BASE + 0x20
-
-#define CSPRNG_ADDR_BASE        SEGMENT_OFFSET_RNGS + (0x0b * CORE_SIZE)
-#define CSPRNG_ADDR_NAME0       CSPRNG_ADDR_BASE + ADDR_NAME0
-#define CSPRNG_ADDR_NAME1       CSPRNG_ADDR_BASE + ADDR_NAME1
-#define CSPRNG_ADDR_VERSION     CSPRNG_ADDR_BASE + ADDR_VERSION
-#define CSPRNG_ADDR_CTRL        CSPRNG_ADDR_BASE + 0x10
-#define CSPRNG_CTRL_ENABLE      1
-#define CSPRNG_CTRL_SEED        2
-#define CSPRNG_ADDR_STATUS      CSPRNG_ADDR_BASE + 0x11
-#define CSPRNG_STATUS_VALID     1
-#define CSPRNG_ADDR_RANDOM      CSPRNG_ADDR_BASE + 0x20
-#define CSPRNG_ADDR_NROUNDS     CSPRNG_ADDR_BASE + 0x40
-#define CSPRNG_ADDR_NBLOCKS_LO  CSPRNG_ADDR_BASE + 0x41
-#define CSPRNG_ADDR_NBLOCKS_HI  CSPRNG_ADDR_BASE + 0x42
+int wait_stats = 0;
 
 /* ---------------- sanity test case ---------------- */
 
@@ -162,7 +77,7 @@ int TC0()
      */
     (void)time((time_t *)t);
     if (tc_write(BOARD_ADDR_DUMMY, t, 4) != 0)
-	return 1;
+        return 1;
 
     if (tc_expected(BOARD_ADDR_NAME0,   board_name0,   4) ||
         tc_expected(BOARD_ADDR_NAME1,   board_name1,   4) ||
@@ -224,26 +139,26 @@ int TC2(void)
 int TC3(void)
 {
     int i, n;
-    unsigned long entropy;
+    uint32_t entropy;
 
     if (!quiet)
         printf("TC3: Read random data from avalanche_entropy.\n");
 
     for (i = 0; i < num_words; ++i) {
         /* check status */
-	n = 10;
+        n = 10;
         if (tc_wait(ENTROPY1_ADDR_STATUS, ENTROPY1_STATUS_VALID, &n) != 0)
             return 1;
         /* read entropy data */
         if (tc_read(ENTROPY1_ADDR_ENTROPY, (uint8_t *)&entropy, 4) != 0)
             return 1;
         /* display entropy data */
-        if (!debug)
-#ifdef WAIT_STATS
-            printf("%08lx %d\n", entropy, n);
-#else
-            printf("%08lx\n", entropy);
-#endif
+        if (!debug) {
+            if (wait_stats)
+                printf("%08x %d\n", entropy, n);
+            else
+                printf("%08x\n", entropy);
+        }
     }
 
     return 0;
@@ -273,26 +188,26 @@ int TC4(void)
 int TC5(void)
 {
     int i, n;
-    unsigned long entropy;
+    uint32_t entropy;
 
     if (!quiet)
         printf("TC5: Read random data from rosc_entropy.\n");
 
     for (i = 0; i < num_words; ++i) {
         /* check status */
-	n = 10;
+        n = 10;
         if (tc_wait(ENTROPY2_ADDR_STATUS, ENTROPY2_STATUS_VALID, &n) != 0)
             return 1;
         /* read entropy data */
         if (tc_read(ENTROPY2_ADDR_ENTROPY, (uint8_t *)&entropy, 4) != 0)
             return 1;
         /* display entropy data */
-        if (!debug)
-#ifdef WAIT_STATS
-            printf("%08lx %d\n", entropy, n);
-#else
-            printf("%08lx\n", entropy);
-#endif
+        if (!debug) {
+            if (wait_stats)
+                printf("%08x %d\n", entropy, n);
+            else
+                printf("%08x\n", entropy);
+        }
     }
 
     return 0;
@@ -314,26 +229,26 @@ int TC6(void)
 int TC7(void)
 {
     int i, n;
-    unsigned long random;
+    uint32_t random;
 
     if (!quiet)
         printf("TC7: Read random data from trng_csprng.\n");
 
     for (i = 0; i < num_words; ++i) {
         /* check status */
-	n = 10;
+        n = 10;
         if (tc_wait(CSPRNG_ADDR_STATUS, CSPRNG_STATUS_VALID, &n) != 0)
             return 1;
         /* read random data */
         if (tc_read(CSPRNG_ADDR_RANDOM, (uint8_t *)&random, 4) != 0)
             return 1;
         /* display random data */
-        if (!debug)
-#ifdef WAIT_STATS
-            printf("%08lx %d\n", random, n);
-#else
-            printf("%08lx\n", random);
-#endif
+        if (!debug) {
+            if (wait_stats)
+                printf("%08x %d\n", random, n);
+            else
+                printf("%08x\n", random);
+        }
     }
 
     return 0;
@@ -345,13 +260,11 @@ int main(int argc, char *argv[])
 {
     typedef int (*tcfp)(void);
     tcfp all_tests[] = { TC0, TC1, TC2, TC3, TC4, TC5, TC6, TC7 };
-
-    char *usage = "Usage: %s [-h] [-d] [-q] [-n #] [-i I2C_device] [-a I2C_addr] tc...\n";
     char *dev = I2C_dev;
     int addr = I2C_addr;
     int i, j, opt;
 
-    while ((opt = getopt(argc, argv, "h?dqn:i:a:")) != -1) {
+    while ((opt = getopt(argc, argv, "h?dqn:wi:a:")) != -1) {
         switch (opt) {
         case 'h':
         case '?':
@@ -370,6 +283,9 @@ int main(int argc, char *argv[])
                 return EXIT_FAILURE;
             }
             break;
+        case 'w':
+            wait_stats = 1;
+            break;
         case 'i':
             dev = optarg;
             break;



More information about the Commits mailing list