diff options
author | Paul Selkirk <paul@psgd.org> | 2015-04-08 16:01:31 -0400 |
---|---|---|
committer | Paul Selkirk <paul@psgd.org> | 2015-04-08 16:03:15 -0400 |
commit | aeaf94f4e83826fe56f38fc670973a60a5010ef1 (patch) | |
tree | 6f3d3ba5d0caf5be29f2a4f873a97b8070d6adc9 /i2c | |
parent | 891a24d969181f02762c031b9cfe0fd96c116634 (diff) |
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.
Diffstat (limited to 'i2c')
-rw-r--r-- | i2c/sw/cryptech_memory_map.h | 119 | ||||
-rw-r--r-- | i2c/sw/hash_i2c.c | 63 | ||||
-rw-r--r-- | i2c/sw/hash_tester_i2c.c | 48 | ||||
-rw-r--r-- | i2c/sw/tc_i2c.c | 82 | ||||
-rw-r--r-- | i2c/sw/tc_i2c.h | 18 | ||||
-rw-r--r-- | i2c/sw/trng_extractor_i2c.c | 64 | ||||
-rw-r--r-- | i2c/sw/trng_tester_i2c.c | 20 |
7 files changed, 180 insertions, 234 deletions
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) |