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 +++++++++------------- 5 files changed, 212 insertions(+), 66 deletions(-) create mode 100644 eim/sw/trng_extractor_eim.c (limited to 'eim/sw') 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; -- cgit v1.2.3