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