[Cryptech-Commits] [core/platform/novena] 01/01: Unify and refactor eim and i2c software.

git at cryptech.is git at cryptech.is
Wed Apr 8 20:40:11 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 aeaf94f4e83826fe56f38fc670973a60a5010ef1
Author: Paul Selkirk <paul at psgd.org>
Date:   Wed Apr 8 16:01:31 2015 -0400

    Unify and refactor eim and i2c software.
    
    Unify memory maps.
    Move tc_init, tc_next, tc_wait_* into tc_[eim|i2c].c.
    Move eim_setup into tc_eim.c, move i2c_open into tc_i2c.c.
---
 eim/sw/cryptech_memory_map.h | 120 ++++++++++++++++++++++++-------------------
 eim/sw/hash_eim.c            |  55 ++++----------------
 eim/sw/hash_tester_eim.c     |  32 ------------
 eim/sw/tc_eim.c              |  70 +++++++++++++++++++++----
 eim/sw/tc_eim.h              |  14 +++--
 eim/sw/trng_extractor_eim.c  |   6 ---
 eim/sw/trng_tester_eim.c     |   6 ---
 i2c/sw/cryptech_memory_map.h | 119 ++++++++++++++++++++++++------------------
 i2c/sw/hash_i2c.c            |  63 +++--------------------
 i2c/sw/hash_tester_i2c.c     |  48 +----------------
 i2c/sw/tc_i2c.c              |  82 ++++++++++++++++++++---------
 i2c/sw/tc_i2c.h              |  18 +++++--
 i2c/sw/trng_extractor_i2c.c  |  64 ++++++++++-------------
 i2c/sw/trng_tester_i2c.c     |  20 +-------
 14 files changed, 328 insertions(+), 389 deletions(-)

diff --git a/eim/sw/cryptech_memory_map.h b/eim/sw/cryptech_memory_map.h
index c70e69c..5cf7f42 100644
--- a/eim/sw/cryptech_memory_map.h
+++ b/eim/sw/cryptech_memory_map.h
@@ -5,7 +5,7 @@
 // The memory map for Cryptech cores.
 //
 //
-// Author: Joachim Strombergson
+// Authors: Joachim Strombergson, Paul Selkirk
 // Copyright (c) 2015, NORDUnet A/S All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -36,35 +36,48 @@
 //
 //======================================================================
 
-// Include platform header and define base address based on platform.
-#include "novena-eim.h"
-#define CT_BASE_ADDR EIM_BASE_ADDR
+// BASE_ADDR, SEGMENT_SIZE, and ADDR are defined in tc_[eim|i2c].h,
+// which #includes this file.
 
+// default definitions from i2c, because defaults are good
+#ifndef BASE_ADDR
+#define BASE_ADDR               0
+#endif
+#ifndef SEGMENT_SIZE
+#define SEGMENT_SIZE            0x2000
+#endif
+#ifndef ADDR
+#define ADDR(x)                 (x)
+#endif
+
+#ifndef bitsToBytes
+#define bitsToBytes(x)          (x / 8)
+#endif
 
 // 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  BASE_ADDR + (0 * SEGMENT_SIZE)
+#define SEGMENT_OFFSET_HASHES   BASE_ADDR + (1 * SEGMENT_SIZE)
+#define SEGMENT_OFFSET_RNGS     BASE_ADDR + (2 * SEGMENT_SIZE)
+#define SEGMENT_OFFSET_CIPHERS  BASE_ADDR + (3 * SEGMENT_SIZE)
 
 
 // addresses and codes common to all cores
-#define ADDR_NAME0              (0x00 << 2)
-#define ADDR_NAME1              (0x01 << 2)
-#define ADDR_VERSION            (0x02 << 2)
+#define ADDR_NAME0              ADDR(0x00)
+#define ADDR_NAME1              ADDR(0x01)
+#define ADDR_VERSION            ADDR(0x02)
 
 
 //------------------------------------------------------------------
 // Board segment.
 // Board-level registers and communication channel registers
 //------------------------------------------------------------------
-#define BOARD_CORE_SIZE         (0x100 << 2)
+#define BOARD_CORE_SIZE         ADDR(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 + ADDR(0xFF)
 
 #define COMM_ADDR_BASE          SEGMENT_OFFSET_GLOBALS + (1 * BOARD_CORE_SIZE)
 #define COMM_ADDR_NAME0         COMM_ADDR_BASE + ADDR_NAME0
@@ -75,17 +88,17 @@
 //------------------------------------------------------------------
 // Hashes segment.
 //------------------------------------------------------------------
-#define HASH_CORE_SIZE          (0x100 << 2)
+#define HASH_CORE_SIZE          ADDR(0x100)
 
 // addresses and codes common to all hash cores */
-#define ADDR_CTRL               (0x8 << 2)
+#define ADDR_CTRL               ADDR(0x8)
 #define CTRL_INIT_CMD           1
 #define CTRL_NEXT_CMD           2
-#define ADDR_STATUS             (9 << 2)
+#define ADDR_STATUS             ADDR(0x9)
 #define STATUS_READY_BIT        1
 #define STATUS_VALID_BIT        2
-#define ADDR_BLOCK              (0x10 << 2)
-#define ADDR_DIGEST             (0x20 << 2)    // except SHA512
+#define ADDR_BLOCK              ADDR(0x10)
+#define ADDR_DIGEST             ADDR(0x20)      // except SHA512
 
 // addresses and codes for the specific hash cores.
 #define SHA1_ADDR_BASE          SEGMENT_OFFSET_HASHES + (0 * HASH_CORE_SIZE)
@@ -96,8 +109,9 @@
 #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 SHA1_BLOCK_LEN          bitsToBytes(512)
+#define SHA1_LENGTH_LEN         bitsToBytes(64)
+#define SHA1_DIGEST_LEN         bitsToBytes(160)
 
 #define SHA256_ADDR_BASE        SEGMENT_OFFSET_HASHES + (1 * HASH_CORE_SIZE)
 #define SHA256_ADDR_NAME0       SHA256_ADDR_BASE + ADDR_NAME0
@@ -107,8 +121,9 @@
 #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 SHA256_BLOCK_LEN        bitsToBytes(512)
+#define SHA256_LENGTH_LEN       bitsToBytes(64)
+#define SHA256_DIGEST_LEN       bitsToBytes(256)
 
 #define SHA512_ADDR_BASE        SEGMENT_OFFSET_HASHES + (2 * HASH_CORE_SIZE)
 #define SHA512_ADDR_NAME0       SHA512_ADDR_BASE + ADDR_NAME0
@@ -117,12 +132,13 @@
 #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 << 2)
-#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 SHA512_ADDR_DIGEST      SHA512_ADDR_BASE + ADDR(0x40)
+#define SHA512_BLOCK_LEN        bitsToBytes(1024)
+#define SHA512_LENGTH_LEN       bitsToBytes(128)
+#define SHA512_224_DIGEST_LEN   bitsToBytes(224)
+#define SHA512_256_DIGEST_LEN   bitsToBytes(256)
+#define SHA384_DIGEST_LEN       bitsToBytes(384)
+#define SHA512_DIGEST_LEN       bitsToBytes(512)
 #define MODE_SHA_512_224        0 << 2
 #define MODE_SHA_512_256        1 << 2
 #define MODE_SHA_384            2 << 2
@@ -132,69 +148,69 @@
 // -----------------------------------------------------------------
 // TRNG segment.
 // -----------------------------------------------------------------
-#define TRNG_CORE_SIZE               (0x100 << 2)
+#define TRNG_CORE_SIZE          ADDR(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 + ADDR(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 + ADDR(0x11)
 // no status bits defined (yet)
-#define TRNG_ADDR_DELAY         TRNG_ADDR_BASE + (0x13 << 2)
+#define TRNG_ADDR_DELAY         TRNG_ADDR_BASE + ADDR(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 + ADDR(0x10)
 #define ENTROPY1_CTRL_ENABLE    1
-#define ENTROPY1_ADDR_STATUS    ENTROPY1_ADDR_BASE + (0x11 << 2)
+#define ENTROPY1_ADDR_STATUS    ENTROPY1_ADDR_BASE + ADDR(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 + ADDR(0x20)
+#define ENTROPY1_ADDR_DELTA     ENTROPY1_ADDR_BASE + ADDR(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 + ADDR(0x10)
 #define ENTROPY2_CTRL_ENABLE    1
-#define ENTROPY2_ADDR_STATUS    ENTROPY2_ADDR_BASE + (0x11 << 2)
+#define ENTROPY2_ADDR_STATUS    ENTROPY2_ADDR_BASE + ADDR(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 + ADDR(0x18)
+#define ENTROPY2_ADDR_OPB       ENTROPY2_ADDR_BASE + ADDR(0x19)
+#define ENTROPY2_ADDR_ENTROPY   ENTROPY2_ADDR_BASE + ADDR(0x20)
+#define ENTROPY2_ADDR_RAW       ENTROPY2_ADDR_BASE + ADDR(0x21)
+#define ENTROPY2_ADDR_ROSC      ENTROPY2_ADDR_BASE + ADDR(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 + ADDR(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 + ADDR(0x11)
 // no status bits defined (yet)
-#define MIXER_ADDR_TIMEOUT      MIXER_ADDR_BASE + (0x20 << 2)
+#define MIXER_ADDR_TIMEOUT      MIXER_ADDR_BASE + ADDR(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 + ADDR(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 + ADDR(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 + ADDR(0x20)
+#define CSPRNG_ADDR_NROUNDS     CSPRNG_ADDR_BASE + ADDR(0x40)
+#define CSPRNG_ADDR_NBLOCKS_LO  CSPRNG_ADDR_BASE + ADDR(0x41)
+#define CSPRNG_ADDR_NBLOCKS_HI  CSPRNG_ADDR_BASE + ADDR(0x42)
 
 //======================================================================
 // EOF cryptech_memory_map.h
diff --git a/eim/sw/hash_eim.c b/eim/sw/hash_eim.c
index 8ea761b..e698129 100644
--- a/eim/sw/hash_eim.c
+++ b/eim/sw/hash_eim.c
@@ -101,55 +101,25 @@ struct ctrl *find_algo(char *algo)
     return NULL;
 }
 
-/* ---------------- test-case low-level code ---------------- */
-
-int tc_init(off_t offset, int mode)
-{
-    uint8_t buf[4] = { 0, 0, 0, CTRL_INIT_CMD + mode };
-
-    return tc_write(offset, buf, 4);
-}
-
-int tc_next(off_t offset, int mode)
-{
-    uint8_t buf[4] = { 0, 0, 0, CTRL_NEXT_CMD + mode };
-
-    return tc_write(offset, buf, 4);
-}
-
-int tc_wait_ready(off_t offset)
-{
-    return tc_wait(offset, STATUS_READY_BIT, NULL);
-}
-
-int tc_wait_valid(off_t offset)
-{
-    return tc_wait(offset, STATUS_VALID_BIT, NULL);
-}
-
 /* ---------------- hash ---------------- */
 
-int transmit(off_t offset, uint8_t *block, int blen, int mode, int first)
+static int transmit(off_t offset, uint8_t *block, int blen, int mode, int first)
 {
-    off_t base = offset & ~(0xff);
+    off_t base = offset & ~(0x1ff);
+    uint8_t ctrl_cmd[4] = { 0 };
 
     if (tc_write(offset, block, blen) != 0)
         return 1;
 
-    if (first) {
-        if (tc_init(base + ADDR_CTRL, mode) != 0)
-            return 1;
-    }
-    else {
-        if (tc_next(base + ADDR_CTRL, mode) != 0)
-            return 1;
-    }
+    ctrl_cmd[3] = (first ? CTRL_INIT_CMD : CTRL_NEXT_CMD) | mode;
 
-    return tc_wait_ready(base + ADDR_STATUS);
+    return
+	tc_write(base + ADDR_CTRL, ctrl_cmd, 4) ||
+	tc_wait_ready(base + ADDR_STATUS);
 }
 
-int pad_transmit(off_t offset, uint8_t *block, uint8_t flen, uint8_t blen,
-                 uint8_t mode, long long tlen, int first)
+static int pad_transmit(off_t offset, uint8_t *block, uint8_t flen, uint8_t blen,
+			uint8_t mode, long long tlen, int first)
 {
     assert(flen < blen);
 
@@ -173,7 +143,7 @@ int pad_transmit(off_t offset, uint8_t *block, uint8_t flen, uint8_t blen,
 }
 
 /* return number of digest bytes read */
-int hash(char *algo, char *file, uint8_t *digest)
+static int hash(char *algo, char *file, uint8_t *digest)
 {
     uint8_t block[SHA512_BLOCK_LEN];
     struct ctrl *ctrl;
@@ -305,11 +275,6 @@ int main(int argc, char *argv[])
             printf("reading from stdin\n");
     }
 
-    if (eim_setup() != 0) {
-        fprintf(stderr, "EIM setup failed\n");
-        return EXIT_FAILURE;
-    }
-
     dlen = hash(algo, file, digest);
     if (dlen < 0)
         return EXIT_FAILURE;
diff --git a/eim/sw/hash_tester_eim.c b/eim/sw/hash_tester_eim.c
index 75b0f1d..8b4f04b 100644
--- a/eim/sw/hash_tester_eim.c
+++ b/eim/sw/hash_tester_eim.c
@@ -227,32 +227,6 @@ const uint8_t SHA512_DOUBLE_DIGEST[] =
   0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
   0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 };
 
-/* ---------------- test-case low-level code ---------------- */
-
-int tc_init(off_t offset)
-{
-    uint8_t buf[4] = { 0, 0, 0, CTRL_INIT_CMD };
-
-    return tc_write(offset, buf, 4);
-}
-
-int tc_next(off_t offset)
-{
-    uint8_t buf[4] = { 0, 0, 0, CTRL_NEXT_CMD };
-
-    return tc_write(offset, buf, 4);
-}
-
-int tc_wait_ready(off_t offset)
-{
-    return tc_wait(offset, STATUS_READY_BIT, NULL);
-}
-
-int tc_wait_valid(off_t offset)
-{
-    return tc_wait(offset, STATUS_VALID_BIT, NULL);
-}
-
 /* ---------------- sanity test case ---------------- */
 
 int TC0()
@@ -635,12 +609,6 @@ int main(int argc, char *argv[])
         }
     }
 
-    /* set up EIM */
-    if (eim_setup() != 0) {
-        fprintf(stderr, "EIM setup failed\n");
-        return EXIT_FAILURE;
-    }
-
     /* repeat one test until interrupted */
     if (repeat) {
         tcfp tc;
diff --git a/eim/sw/tc_eim.c b/eim/sw/tc_eim.c
index 0d8c83c..d44b685 100644
--- a/eim/sw/tc_eim.c
+++ b/eim/sw/tc_eim.c
@@ -44,10 +44,26 @@
 #include "tc_eim.h"
 
 extern int debug;
+static int inited = 0;
+
+/* ---------------- EIM low-level code ---------------- */
+static int init(void)
+{
+    if (inited)
+        return 0;
+
+    if (eim_setup() != 0) {
+        fprintf(stderr, "EIM setup failed\n");
+        return -1;
+    }
+
+    inited = 1;
+    return 0;
+}
 
 /* ---------------- test-case low-level code ---------------- */
 
-static void dump(char *label, const uint8_t *buf, int len)
+static void dump(char *label, const uint8_t *buf, size_t len)
 {
     if (debug) {
         int i;
@@ -58,8 +74,11 @@ static void dump(char *label, const uint8_t *buf, int len)
     }
 }
 
-int tc_write(off_t offset, const uint8_t *buf, int len)
+int tc_write(off_t offset, const uint8_t *buf, size_t len)
 {
+    if (init() != 0)
+        return -1;
+
     dump("write ", buf, len);
 
     for (; len > 0; offset += 4, buf += 4, len -= 4) {
@@ -71,11 +90,14 @@ int tc_write(off_t offset, const uint8_t *buf, int len)
     return 0;
 }
 
-int tc_read(off_t offset, uint8_t *buf, int len)
+int tc_read(off_t offset, uint8_t *buf, size_t len)
 {
     uint8_t *rbuf = buf;
     int rlen = len;
 
+    if (init() != 0)
+        return -1;
+
     for (; rlen > 0; offset += 4, rbuf += 4, rlen -= 4) {
         uint32_t val;
         eim_read_32(offset, &val);
@@ -87,7 +109,7 @@ int tc_read(off_t offset, uint8_t *buf, int len)
     return 0;
 }
 
-int tc_expected(off_t offset, const uint8_t *expected, int len)
+int tc_expected(off_t offset, const uint8_t *expected, size_t len)
 {
     uint8_t *buf;
     int i;
@@ -116,22 +138,48 @@ errout:
     return 1;
 }
 
+int tc_init(off_t offset)
+{
+    uint8_t buf[4] = { 0, 0, 0, CTRL_INIT_CMD };
+
+    return tc_write(offset, buf, 4);
+}
+
+int tc_next(off_t offset)
+{
+    uint8_t buf[4] = { 0, 0, 0, CTRL_NEXT_CMD };
+
+    return tc_write(offset, buf, 4);
+}
+
 int tc_wait(off_t offset, uint8_t status, int *count)
 {
     uint8_t buf[4];
     int i;
 
     for (i = 1; ; ++i) {
-	if (count && (*count > 0) && (i >= *count)) {
-	    fprintf(stderr, "tc_wait timed out\n");
-	    return 1;
-	}
+        if (count && (*count > 0) && (i >= *count)) {
+            fprintf(stderr, "tc_wait timed out\n");
+            return 1;
+        }
         if (tc_read(offset, buf, 4) != 0)
             return -1;
         if (buf[3] & status) {
-	    if (count)
-		*count = i;
+            if (count)
+                *count = i;
             return 0;
-	}
+        }
     }
 }
+
+int tc_wait_ready(off_t offset)
+{
+    int limit = 256;
+    return tc_wait(offset, STATUS_READY_BIT, &limit);
+}
+
+int tc_wait_valid(off_t offset)
+{
+    int limit = 256;
+    return tc_wait(offset, STATUS_VALID_BIT, &limit);
+}
diff --git a/eim/sw/tc_eim.h b/eim/sw/tc_eim.h
index 257822d..5da18e4 100644
--- a/eim/sw/tc_eim.h
+++ b/eim/sw/tc_eim.h
@@ -34,9 +34,17 @@
  */
 
 #include "novena-eim.h"
+#define BASE_ADDR               EIM_BASE_ADDR
+#define SEGMENT_SIZE            0x10000
+#define ADDR(x)                 (x << 2)
+#include "cryptech_memory_map.h"
 
 /* test case public functions */
-int tc_write(off_t offset, const uint8_t *buf, int len);
-int tc_read(off_t offset, uint8_t *buf, int len);
-int tc_expected(off_t offset, const uint8_t *expected, int len);
+int tc_write(off_t offset, const uint8_t *buf, size_t len);
+int tc_read(off_t offset, uint8_t *buf, size_t len);
+int tc_expected(off_t offset, const uint8_t *expected, size_t len);
+int tc_init(off_t offset);
+int tc_next(off_t offset);
 int tc_wait(off_t offset, uint8_t status, int *count);
+int tc_wait_ready(off_t offset);
+int tc_wait_valid(off_t offset);
diff --git a/eim/sw/trng_extractor_eim.c b/eim/sw/trng_extractor_eim.c
index 18fc1d6..be6ab16 100644
--- a/eim/sw/trng_extractor_eim.c
+++ b/eim/sw/trng_extractor_eim.c
@@ -145,12 +145,6 @@ int main(int argc, char *argv[])
         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)
diff --git a/eim/sw/trng_tester_eim.c b/eim/sw/trng_tester_eim.c
index d25b784..def75ab 100644
--- a/eim/sw/trng_tester_eim.c
+++ b/eim/sw/trng_tester_eim.c
@@ -312,12 +312,6 @@ int main(int argc, char *argv[])
         }
     }
 
-    /* set up EIM */
-    if (eim_setup() != 0) {
-        fprintf(stderr, "EIM setup failed\n");
-        return EXIT_FAILURE;
-    }
-
     /* repeat one test until interrupted */
     if (repeat) {
         tcfp tc;
diff --git a/i2c/sw/cryptech_memory_map.h b/i2c/sw/cryptech_memory_map.h
index cf5cb89..5cf7f42 100644
--- a/i2c/sw/cryptech_memory_map.h
+++ b/i2c/sw/cryptech_memory_map.h
@@ -5,7 +5,7 @@
 // The memory map for Cryptech cores.
 //
 //
-// Author: Joachim Strombergson
+// Authors: Joachim Strombergson, Paul Selkirk
 // Copyright (c) 2015, NORDUnet A/S All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -36,30 +36,48 @@
 //
 //======================================================================
 
+// BASE_ADDR, SEGMENT_SIZE, and ADDR are defined in tc_[eim|i2c].h,
+// which #includes this file.
+
+// default definitions from i2c, because defaults are good
+#ifndef BASE_ADDR
+#define BASE_ADDR               0
+#endif
+#ifndef SEGMENT_SIZE
+#define SEGMENT_SIZE            0x2000
+#endif
+#ifndef ADDR
+#define ADDR(x)                 (x)
+#endif
+
+#ifndef bitsToBytes
+#define bitsToBytes(x)          (x / 8)
+#endif
+
 // Segments.
-#define SEGMENT_OFFSET_GLOBALS  0x0000
-#define SEGMENT_OFFSET_HASHES   0x2000
-#define SEGMENT_OFFSET_RNGS     0x4000
-#define SEGMENT_OFFSET_CIPHERS  0x6000
+#define SEGMENT_OFFSET_GLOBALS  BASE_ADDR + (0 * SEGMENT_SIZE)
+#define SEGMENT_OFFSET_HASHES   BASE_ADDR + (1 * SEGMENT_SIZE)
+#define SEGMENT_OFFSET_RNGS     BASE_ADDR + (2 * SEGMENT_SIZE)
+#define SEGMENT_OFFSET_CIPHERS  BASE_ADDR + (3 * SEGMENT_SIZE)
 
 
 // addresses and codes common to all cores
-#define ADDR_NAME0              0x00
-#define ADDR_NAME1              0x01
-#define ADDR_VERSION            0x02
+#define ADDR_NAME0              ADDR(0x00)
+#define ADDR_NAME1              ADDR(0x01)
+#define ADDR_VERSION            ADDR(0x02)
 
 
 //------------------------------------------------------------------
 // Board segment.
 // Board-level registers and communication channel registers
 //------------------------------------------------------------------
-#define BOARD_CORE_SIZE         0x100
+#define BOARD_CORE_SIZE         ADDR(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
+#define BOARD_ADDR_DUMMY        BOARD_ADDR_BASE + ADDR(0xFF)
 
 #define COMM_ADDR_BASE          SEGMENT_OFFSET_GLOBALS + (1 * BOARD_CORE_SIZE)
 #define COMM_ADDR_NAME0         COMM_ADDR_BASE + ADDR_NAME0
@@ -70,17 +88,17 @@
 //------------------------------------------------------------------
 // Hashes segment.
 //------------------------------------------------------------------
-#define HASH_CORE_SIZE          0x100
+#define HASH_CORE_SIZE          ADDR(0x100)
 
 // addresses and codes common to all hash cores */
-#define ADDR_CTRL               0x8
+#define ADDR_CTRL               ADDR(0x8)
 #define CTRL_INIT_CMD           1
 #define CTRL_NEXT_CMD           2
-#define ADDR_STATUS             9
+#define ADDR_STATUS             ADDR(0x9)
 #define STATUS_READY_BIT        1
 #define STATUS_VALID_BIT        2
-#define ADDR_BLOCK              0x10
-#define ADDR_DIGEST             0x20    // except SHA512
+#define ADDR_BLOCK              ADDR(0x10)
+#define ADDR_DIGEST             ADDR(0x20)      // except SHA512
 
 // addresses and codes for the specific hash cores.
 #define SHA1_ADDR_BASE          SEGMENT_OFFSET_HASHES + (0 * HASH_CORE_SIZE)
@@ -91,8 +109,9 @@
 #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 SHA1_BLOCK_LEN          bitsToBytes(512)
+#define SHA1_LENGTH_LEN         bitsToBytes(64)
+#define SHA1_DIGEST_LEN         bitsToBytes(160)
 
 #define SHA256_ADDR_BASE        SEGMENT_OFFSET_HASHES + (1 * HASH_CORE_SIZE)
 #define SHA256_ADDR_NAME0       SHA256_ADDR_BASE + ADDR_NAME0
@@ -102,8 +121,9 @@
 #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 SHA256_BLOCK_LEN        bitsToBytes(512)
+#define SHA256_LENGTH_LEN       bitsToBytes(64)
+#define SHA256_DIGEST_LEN       bitsToBytes(256)
 
 #define SHA512_ADDR_BASE        SEGMENT_OFFSET_HASHES + (2 * HASH_CORE_SIZE)
 #define SHA512_ADDR_NAME0       SHA512_ADDR_BASE + ADDR_NAME0
@@ -112,12 +132,13 @@
 #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 SHA512_ADDR_DIGEST      SHA512_ADDR_BASE + ADDR(0x40)
+#define SHA512_BLOCK_LEN        bitsToBytes(1024)
+#define SHA512_LENGTH_LEN       bitsToBytes(128)
+#define SHA512_224_DIGEST_LEN   bitsToBytes(224)
+#define SHA512_256_DIGEST_LEN   bitsToBytes(256)
+#define SHA384_DIGEST_LEN       bitsToBytes(384)
+#define SHA512_DIGEST_LEN       bitsToBytes(512)
 #define MODE_SHA_512_224        0 << 2
 #define MODE_SHA_512_256        1 << 2
 #define MODE_SHA_384            2 << 2
@@ -127,69 +148,69 @@
 // -----------------------------------------------------------------
 // TRNG segment.
 // -----------------------------------------------------------------
-#define TRNG_CORE_SIZE               0x100
+#define TRNG_CORE_SIZE          ADDR(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
+#define TRNG_ADDR_CTRL          TRNG_ADDR_BASE + ADDR(0x10)
 #define TRNG_CTRL_DISCARD       1
 #define TRNG_CTRL_TEST_MODE     2
-#define TRNG_ADDR_STATUS        TRNG_ADDR_BASE + 0x11
+#define TRNG_ADDR_STATUS        TRNG_ADDR_BASE + ADDR(0x11)
 // no status bits defined (yet)
-#define TRNG_ADDR_DELAY         TRNG_ADDR_BASE + 0x13
+#define TRNG_ADDR_DELAY         TRNG_ADDR_BASE + ADDR(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
+#define ENTROPY1_ADDR_CTRL      ENTROPY1_ADDR_BASE + ADDR(0x10)
 #define ENTROPY1_CTRL_ENABLE    1
-#define ENTROPY1_ADDR_STATUS    ENTROPY1_ADDR_BASE + 0x11
+#define ENTROPY1_ADDR_STATUS    ENTROPY1_ADDR_BASE + ADDR(0x11)
 #define ENTROPY1_STATUS_VALID   1
-#define ENTROPY1_ADDR_ENTROPY   ENTROPY1_ADDR_BASE + 0x20
-#define ENTROPY1_ADDR_DELTA     ENTROPY1_ADDR_BASE + 0x30
+#define ENTROPY1_ADDR_ENTROPY   ENTROPY1_ADDR_BASE + ADDR(0x20)
+#define ENTROPY1_ADDR_DELTA     ENTROPY1_ADDR_BASE + ADDR(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
+#define ENTROPY2_ADDR_CTRL      ENTROPY2_ADDR_BASE + ADDR(0x10)
 #define ENTROPY2_CTRL_ENABLE    1
-#define ENTROPY2_ADDR_STATUS    ENTROPY2_ADDR_BASE + 0x11
+#define ENTROPY2_ADDR_STATUS    ENTROPY2_ADDR_BASE + ADDR(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 ENTROPY2_ADDR_OPA       ENTROPY2_ADDR_BASE + ADDR(0x18)
+#define ENTROPY2_ADDR_OPB       ENTROPY2_ADDR_BASE + ADDR(0x19)
+#define ENTROPY2_ADDR_ENTROPY   ENTROPY2_ADDR_BASE + ADDR(0x20)
+#define ENTROPY2_ADDR_RAW       ENTROPY2_ADDR_BASE + ADDR(0x21)
+#define ENTROPY2_ADDR_ROSC      ENTROPY2_ADDR_BASE + ADDR(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
+#define MIXER_ADDR_CTRL         MIXER_ADDR_BASE + ADDR(0x10)
 #define MIXER_CTRL_ENABLE       1
 #define MIXER_CTRL_RESTART      2
-#define MIXER_ADDR_STATUS       MIXER_ADDR_BASE + 0x11
+#define MIXER_ADDR_STATUS       MIXER_ADDR_BASE + ADDR(0x11)
 // no status bits defined (yet)
-#define MIXER_ADDR_TIMEOUT      MIXER_ADDR_BASE + 0x20
+#define MIXER_ADDR_TIMEOUT      MIXER_ADDR_BASE + ADDR(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
+#define CSPRNG_ADDR_CTRL        CSPRNG_ADDR_BASE + ADDR(0x10)
 #define CSPRNG_CTRL_ENABLE      1
 #define CSPRNG_CTRL_SEED        2
-#define CSPRNG_ADDR_STATUS      CSPRNG_ADDR_BASE + 0x11
+#define CSPRNG_ADDR_STATUS      CSPRNG_ADDR_BASE + ADDR(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
+#define CSPRNG_ADDR_RANDOM      CSPRNG_ADDR_BASE + ADDR(0x20)
+#define CSPRNG_ADDR_NROUNDS     CSPRNG_ADDR_BASE + ADDR(0x40)
+#define CSPRNG_ADDR_NBLOCKS_LO  CSPRNG_ADDR_BASE + ADDR(0x41)
+#define CSPRNG_ADDR_NBLOCKS_HI  CSPRNG_ADDR_BASE + ADDR(0x42)
 
 //======================================================================
 // EOF cryptech_memory_map.h
diff --git a/i2c/sw/hash_i2c.c b/i2c/sw/hash_i2c.c
index 04006d3..3a9f0cf 100644
--- a/i2c/sw/hash_i2c.c
+++ b/i2c/sw/hash_i2c.c
@@ -49,7 +49,7 @@
 #include "cryptech_memory_map.h"
 
 char *usage =
-"Usage: %s [-d] [-v] [-q] [-i I2C_device] [-a I2C_addr] [algorithm [file]]\n"
+"Usage: %s [-d] [-v] [-q] [algorithm [file]]\n"
 "algorithms: sha-1, sha-256, sha-512/224, sha-512/256, sha-384, sha-512\n";
 
 int debug = 0;
@@ -96,53 +96,21 @@ struct ctrl *find_algo(char *algo)
     return NULL;
 }
 
-/* ---------------- test-case low-level code ---------------- */
-
-int tc_init(off_t offset, int mode)
-{
-    uint8_t buf[4] = { 0, 0, 0, CTRL_INIT_CMD + mode };
-
-    return tc_write(offset, buf, 4);
-}
-
-int tc_next(off_t offset, int mode)
-{
-    uint8_t buf[4] = { 0, 0, 0, CTRL_NEXT_CMD + mode };
-
-    return tc_write(offset, buf, 4);
-}
-
-int tc_wait_ready(off_t offset)
-{
-    int limit = 10;
-    return tc_wait(offset, STATUS_READY_BIT, &limit);
-}
-
-int tc_wait_valid(off_t offset)
-{
-    int limit = 10;
-    return tc_wait(offset, STATUS_VALID_BIT, &limit);
-}
-
 /* ---------------- hash ---------------- */
 
 int transmit(off_t offset, uint8_t *block, int blen, int mode, int first)
 {
-    off_t base = offset & ~(0xff);
+    off_t base = offset & ~(0x1ff);
+    uint8_t ctrl_cmd[4] = { 0 };
 
     if (tc_write(offset, block, blen) != 0)
         return 1;
 
-    if (first) {
-        if (tc_init(base + ADDR_CTRL, mode) != 0)
-            return 1;
-    }
-    else {
-        if (tc_next(base + ADDR_CTRL, mode) != 0)
-            return 1;
-    }
+    ctrl_cmd[3] = (first ? CTRL_INIT_CMD : CTRL_NEXT_CMD) | mode;
 
-    return tc_wait_ready(base + ADDR_STATUS);
+    return
+	tc_write(base + ADDR_CTRL, ctrl_cmd, 4) ||
+	tc_wait_ready(base + ADDR_STATUS);
 }
 
 int pad_transmit(off_t offset, uint8_t *block, uint8_t flen, uint8_t blen,
@@ -257,15 +225,13 @@ out:
 
 int main(int argc, char *argv[])
 {
-    char *dev = I2C_dev;
-    int addr = I2C_addr;
     int i, opt;
     char *algo = "sha-1";
     char *file = "-";
     uint8_t digest[512/8];
     int dlen;
 
-    while ((opt = getopt(argc, argv, "h?dvqi:a:")) != -1) {
+    while ((opt = getopt(argc, argv, "h?dvq")) != -1) {
         switch (opt) {
         case 'h':
         case '?':
@@ -280,16 +246,6 @@ int main(int argc, char *argv[])
         case 'q':
             quiet = 1;
             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 EXIT_FAILURE;
-            }
-            break;
         default:
             fprintf(stderr, usage, argv[0]);
             return EXIT_FAILURE;
@@ -314,9 +270,6 @@ int main(int argc, char *argv[])
             printf("reading from stdin\n");
     }
 
-    if (i2c_open(dev, addr) != 0)
-        return EXIT_FAILURE;
-
     dlen = hash(algo, file, digest);
     if (dlen < 0)
         return EXIT_FAILURE;
diff --git a/i2c/sw/hash_tester_i2c.c b/i2c/sw/hash_tester_i2c.c
index c9b8f5f..41a117e 100644
--- a/i2c/sw/hash_tester_i2c.c
+++ b/i2c/sw/hash_tester_i2c.c
@@ -224,34 +224,6 @@ const uint8_t SHA512_DOUBLE_DIGEST[] =
   0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
   0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 };
 
-/* ---------------- test-case low-level code ---------------- */
-
-int tc_init(off_t offset)
-{
-    uint8_t buf[4] = { 0, 0, 0, CTRL_INIT_CMD };
-
-    return tc_write(offset, buf, 4);
-}
-
-int tc_next(off_t offset)
-{
-    uint8_t buf[4] = { 0, 0, 0, CTRL_NEXT_CMD };
-
-    return tc_write(offset, buf, 4);
-}
-
-int tc_wait_ready(off_t offset)
-{
-    int limit = 10;
-    return tc_wait(offset, STATUS_READY_BIT, &limit);
-}
-
-int tc_wait_valid(off_t offset)
-{
-    int limit = 10;
-    return tc_wait(offset, STATUS_VALID_BIT, &limit);
-}
-
 /* ---------------- sanity test case ---------------- */
 
 int TC0()
@@ -595,12 +567,10 @@ int main(int argc, char *argv[])
     tcfp sha256_tests[] = { TC4, TC5, TC6, TC7 };
     tcfp sha512_tests[] = { TC8, TC9, TC10 };
 
-    char *usage = "Usage: %s [-h] [-d] [-q] [-i I2C_device] [-a I2C_addr] tc...\n";
-    char *dev = I2C_dev;
-    int addr = I2C_addr;
+    char *usage = "Usage: %s [-h] [-d] [-q] tc...\n";
     int i, j, opt;
 
-    while ((opt = getopt(argc, argv, "h?dqi:a:")) != -1) {
+    while ((opt = getopt(argc, argv, "h?dq")) != -1) {
         switch (opt) {
         case 'h':
         case '?':
@@ -612,26 +582,12 @@ int main(int argc, char *argv[])
         case 'q':
             quiet = 1;
             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 EXIT_FAILURE;
-            }
-            break;
         default:
             fprintf(stderr, usage, argv[0]);
             return EXIT_FAILURE;
         }
     }
 
-    /* set up I2C */
-    if (i2c_open(dev, addr) != 0)
-        return EXIT_FAILURE;
-
     /* no args == run all tests */
     if (optind >= argc) {
         for (j = 0; j < sizeof(all_tests)/sizeof(all_tests[0]); ++j)
diff --git a/i2c/sw/tc_i2c.c b/i2c/sw/tc_i2c.c
index da1ab14..613d1c6 100644
--- a/i2c/sw/tc_i2c.c
+++ b/i2c/sw/tc_i2c.c
@@ -37,7 +37,6 @@
 #include <stdlib.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <linux/i2c-dev.h>
 #include <sys/ioctl.h>
 #include <stdint.h>
 
@@ -47,7 +46,7 @@ extern int debug;
 
 /* ---------------- I2C low-level code ---------------- */
 
-static int i2cfd;
+static int i2cfd = -1;
 
 static void dump(char *label, const uint8_t *buf, size_t len)
 {
@@ -65,25 +64,28 @@ static void i2c_close(void)
     close(i2cfd);
 }
 
-int i2c_open(char *dev, int addr)
+static int i2c_open(void)
 {
-    i2cfd = open(dev, O_RDWR);
+    if (i2cfd >= 0)
+        return 0;
+
+    i2cfd = open(I2C_dev, O_RDWR);
     if (i2cfd < 0) {
-        fprintf(stderr, "Unable to open %s: ", dev);
+        fprintf(stderr, "Unable to open %s: ", I2C_dev);
         perror("");
         i2cfd = 0;
         return 1;
     }
 
-    if (ioctl(i2cfd, I2C_SLAVE, addr) < 0) {
-        fprintf(stderr, "Unable to set I2C slave device 0x%02x: ", addr);
+    if (ioctl(i2cfd, I2C_SLAVE, I2C_addr) < 0) {
+        fprintf(stderr, "Unable to set I2C slave device 0x%02x: ", I2C_addr);
         perror("");
         return 1;
     }
 
     if (atexit(i2c_close) != 0) {
-	fprintf(stderr, "Unable to set I2C atexit handler.");
-	return 1;
+        fprintf(stderr, "Unable to set I2C atexit handler.");
+        return 1;
     }
 
     return 0;
@@ -91,6 +93,9 @@ int i2c_open(char *dev, int addr)
 
 static int i2c_write(const uint8_t *buf, size_t len)
 {
+    if (i2c_open() != 0)
+        return 1;
+
     dump("write ", buf, len);
 
     if (write(i2cfd, buf, len) != len) {
@@ -103,6 +108,9 @@ static int i2c_write(const uint8_t *buf, size_t len)
 
 static int i2c_read(uint8_t *b)
 {
+    if (i2c_open() != 0)
+        return 1;
+
     /* read() on the i2c device only returns one byte at a time,
      * and tc_get_resp() needs to parse the response one byte at a time
      */
@@ -235,20 +243,20 @@ static int tc_get_read_resp_expected(off_t offset, const uint8_t *data)
 {
     uint8_t buf[9];
     uint8_t expected[9] = { SOR, READ_OK, (offset >> 8) & 0xff, offset & 0xff,
-			    data[0], data[1], data[2], data[3], EOR };
+                            data[0], data[1], data[2], data[3], EOR };
 
     dump("expect", expected, 9);
 
     return (tc_get_resp(buf, sizeof(buf)) ||
-	    tc_compare(buf, expected, sizeof(buf)));
+            tc_compare(buf, expected, sizeof(buf)));
 }
 
 int tc_write(off_t offset, const uint8_t *buf, size_t len)
 {
     for (; len > 0; offset++, buf += 4, len -= 4) {
-	if (tc_send_write_cmd(offset, buf) ||
+        if (tc_send_write_cmd(offset, buf) ||
             tc_get_write_resp(offset))
-	    return 1;
+            return 1;
     }
 
     return 0;
@@ -257,9 +265,9 @@ int tc_write(off_t offset, const uint8_t *buf, size_t len)
 int tc_read(off_t offset, uint8_t *buf, size_t len)
 {
     for (; len > 0; offset++, buf += 4, len -= 4) {
-	if (tc_send_read_cmd(offset) ||
+        if (tc_send_read_cmd(offset) ||
             tc_get_read_resp(offset, buf))
-	    return 1;
+            return 1;
     }
 
     return 0;
@@ -268,30 +276,56 @@ int tc_read(off_t offset, uint8_t *buf, size_t len)
 int tc_expected(off_t offset, const uint8_t *buf, size_t len)
 {
     for (; len > 0; offset++, buf += 4, len -= 4) {
-	if (tc_send_read_cmd(offset) ||
+        if (tc_send_read_cmd(offset) ||
             tc_get_read_resp_expected(offset, buf))
-	    return 1;
+            return 1;
     }
 
     return 0;
 }
 
+int tc_init(off_t offset)
+{
+    uint8_t buf[4] = { 0, 0, 0, CTRL_INIT_CMD };
+
+    return tc_write(offset, buf, 4);
+}
+
+int tc_next(off_t offset)
+{
+    uint8_t buf[4] = { 0, 0, 0, CTRL_NEXT_CMD };
+
+    return tc_write(offset, buf, 4);
+}
+
 int tc_wait(off_t offset, uint8_t status, int *count)
 {
     uint8_t buf[4];
     int i;
 
     for (i = 1; ; ++i) {
-	if (count && (*count > 0) && (i >= *count)) {
-	    fprintf(stderr, "tc_wait timed out\n");
-	    return 1;
-	}
+        if (count && (*count > 0) && (i >= *count)) {
+            fprintf(stderr, "tc_wait timed out\n");
+            return 1;
+        }
         if (tc_read(offset, buf, 4) != 0)
             return -1;
         if (buf[3] & status) {
-	    if (count)
-		*count = i;
+            if (count)
+                *count = i;
             return 0;
-	}
+        }
     }
 }
+
+int tc_wait_ready(off_t offset)
+{
+    int limit = 10;
+    return tc_wait(offset, STATUS_READY_BIT, &limit);
+}
+
+int tc_wait_valid(off_t offset)
+{
+    int limit = 10;
+    return tc_wait(offset, STATUS_VALID_BIT, &limit);
+}
diff --git a/i2c/sw/tc_i2c.h b/i2c/sw/tc_i2c.h
index f9648da..b1afae1 100644
--- a/i2c/sw/tc_i2c.h
+++ b/i2c/sw/tc_i2c.h
@@ -33,15 +33,23 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* I2C configuration */
-#define I2C_dev  "/dev/i2c-2"
-#define I2C_addr 0x0f
+/* cryptech memory map */
+#define BASE_ADDR               0
+#define SEGMENT_SIZE            0x2000
+#define ADDR(x)                 (x)
+#include "cryptech_memory_map.h"
 
-/* I2C public functions */
-int i2c_open(char *dev, int addr);
+/* I2C configuration */
+#define I2C_dev                 "/dev/i2c-2"
+#define I2C_addr                0x0f
+#define I2C_SLAVE               0x0703
 
 /* test case public functions */
 int tc_write(off_t offset, const uint8_t *data, size_t len);
 int tc_read(off_t offset, uint8_t *data, size_t len);
 int tc_expected(off_t offset, const uint8_t *data, size_t len);
+int tc_init(off_t offset);
+int tc_next(off_t offset);
 int tc_wait(off_t offset, uint8_t status, int *count);
+int tc_wait_ready(off_t offset);
+int tc_wait_valid(off_t offset);
diff --git a/i2c/sw/trng_extractor_i2c.c b/i2c/sw/trng_extractor_i2c.c
index 7b5b3b2..7b3c2ef 100644
--- a/i2c/sw/trng_extractor_i2c.c
+++ b/i2c/sw/trng_extractor_i2c.c
@@ -44,7 +44,7 @@
 #include "cryptech_memory_map.h"
 
 char *usage = 
-"%s [-a|r|c] [-n #] [-o file] [-I I2C_device] [-A I2C_addr]\n\
+"%s [-a|r|c] [-n #] [-o file]\n\
 \n\
 -a      avalanche entropy\n\
 -r      rosc entropy\n\
@@ -58,10 +58,18 @@ int debug = 0;          /* for dump() */
 /* extract one data sample */
 static int extract(off_t status_addr, off_t data_addr, uint32_t *data)
 {
+/* In theory, we should wait for "valid" before reading random
+ * data, but as long as this is running over I2C we're going to be so
+ * slow that there's no point, and checking would just make us slower.
+ */
+#define WAIT_FOR_TRNG_VALID     0
+
+#if WAIT_FOR_TRNG_VALID
     if (tc_wait(status_addr, ENTROPY1_STATUS_VALID, NULL) != 0) {
         fprintf(stderr, "tc_wait failed\n");
         return 1;
     }
+#endif
 
     if (tc_read(data_addr, (uint8_t *)data, 4) != 0) {
         fprintf(stderr, "tc_read failed\n");
@@ -81,11 +89,9 @@ int main(int argc, char *argv[])
     off_t data_addr = CSPRNG_ADDR_RANDOM;
     FILE *output = stdout;
     uint32_t data;
-    char *dev = I2C_dev;
-    int addr = I2C_addr;
 
     /* parse command line */
-    while ((opt = getopt(argc, argv, "h?arcn:o:I:A:")) != -1) {
+    while ((opt = getopt(argc, argv, "h?arcn:o:")) != -1) {
         switch (opt) {
         case 'h':
         case '?':
@@ -104,23 +110,23 @@ int main(int argc, char *argv[])
             data_addr = CSPRNG_ADDR_RANDOM;
             break;
         case 'n':
-	    num_words = strtoul(optarg, &endptr, 10);
-	    switch (toupper(*endptr)) {
-	    case '\0':
-		break;
-	    case 'K':
-		num_words *= 1000;
-		break;
-	    case 'M':
-		num_words *= 1000000;
-		break;
-	    case 'G':
-		num_words *= 1000000000;
-		break;
-	    default:
-		fprintf(stderr, "unsupported -n suffix %s\n", endptr);
-		return EXIT_FAILURE;
-	    }
+            num_words = strtoul(optarg, &endptr, 10);
+            switch (toupper(*endptr)) {
+            case '\0':
+                break;
+            case 'K':
+                num_words *= 1000;
+                break;
+            case 'M':
+                num_words *= 1000000;
+                break;
+            case 'G':
+                num_words *= 1000000000;
+                break;
+            default:
+                fprintf(stderr, "unsupported -n suffix %s\n", endptr);
+                return EXIT_FAILURE;
+            }
             break;
         case 'o':
             output = fopen(optarg, "wb+");
@@ -130,16 +136,6 @@ int main(int argc, char *argv[])
                 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]);
@@ -157,12 +153,6 @@ int main(int argc, char *argv[])
         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)
diff --git a/i2c/sw/trng_tester_i2c.c b/i2c/sw/trng_tester_i2c.c
index a5dfb81..92b2c94 100644
--- a/i2c/sw/trng_tester_i2c.c
+++ b/i2c/sw/trng_tester_i2c.c
@@ -48,7 +48,7 @@
 #include "tc_i2c.h"
 #include "cryptech_memory_map.h"
 
-char *usage = "Usage: %s [-h] [-d] [-q] [-w] [-n #] [-i I2C_device] [-a I2C_addr] tc...\n";
+char *usage = "Usage: %s [-h] [-d] [-q] [-w] [-n #] tc...\n";
 
 int debug = 0;
 int quiet = 0;
@@ -260,11 +260,9 @@ int main(int argc, char *argv[])
 {
     typedef int (*tcfp)(void);
     tcfp all_tests[] = { TC0, TC1, TC2, TC3, TC4, TC5, TC6, TC7 };
-    char *dev = I2C_dev;
-    int addr = I2C_addr;
     int i, j, opt;
 
-    while ((opt = getopt(argc, argv, "h?dqn:wi:a:")) != -1) {
+    while ((opt = getopt(argc, argv, "h?dqn:w")) != -1) {
         switch (opt) {
         case 'h':
         case '?':
@@ -286,26 +284,12 @@ int main(int argc, char *argv[])
         case 'w':
             wait_stats = 1;
             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:
             fprintf(stderr, usage, argv[0]);
             return EXIT_FAILURE;
         }
     }
 
-    /* set up I2C */
-    if (i2c_open(dev, addr) != 0)
-        return EXIT_FAILURE;
-
     /* no args == run all tests */
     if (optind >= argc) {
         for (j = 0; j < sizeof(all_tests)/sizeof(all_tests[0]); ++j)



More information about the Commits mailing list