aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eim/sw/cryptech_memory_map.h120
-rw-r--r--eim/sw/hash_eim.c55
-rw-r--r--eim/sw/hash_tester_eim.c32
-rw-r--r--eim/sw/tc_eim.c70
-rw-r--r--eim/sw/tc_eim.h14
-rw-r--r--eim/sw/trng_extractor_eim.c6
-rw-r--r--eim/sw/trng_tester_eim.c6
-rw-r--r--i2c/sw/cryptech_memory_map.h119
-rw-r--r--i2c/sw/hash_i2c.c63
-rw-r--r--i2c/sw/hash_tester_i2c.c48
-rw-r--r--i2c/sw/tc_i2c.c82
-rw-r--r--i2c/sw/tc_i2c.h18
-rw-r--r--i2c/sw/trng_extractor_i2c.c64
-rw-r--r--i2c/sw/trng_tester_i2c.c20
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)