aboutsummaryrefslogtreecommitdiff
path: root/eim/sw
diff options
context:
space:
mode:
authorPaul Selkirk <paul@psgd.org>2015-04-02 15:07:22 -0400
committerPaul Selkirk <paul@psgd.org>2015-04-02 15:07:22 -0400
commitb1ebb2a975de7f29e63c3a4046de15c26b44dceb (patch)
tree20c6e29fa7f51953a83629146bcf61ad556092ab /eim/sw
parentaea9e93e560b1468bf0ff2cf5b61e5409ce60dc5 (diff)
Add trng_extractor app to eim and i2c, refactor i2c apps to use common memory map.
Diffstat (limited to 'eim/sw')
-rwxr-xr-xeim/sw/Makefile9
-rw-r--r--eim/sw/cryptech_memory_map.h34
-rw-r--r--eim/sw/hash_tester_eim.c2
-rw-r--r--eim/sw/trng_extractor_eim.c155
-rw-r--r--eim/sw/trng_tester_eim.c78
5 files changed, 212 insertions, 66 deletions
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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#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;