aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Selkirk <paul@psgd.org>2015-06-10 12:30:58 -0400
committerPaul Selkirk <paul@psgd.org>2015-06-10 12:30:58 -0400
commitf141a79d805acbab07876d9f007e8809603718b5 (patch)
tree62e2a730ce6b388efef8b20d32ccbef940697bdd
parent80205a9ff9a8b4da93aa74d7b73f16832682384a (diff)
generate core_selector, probe FPGA for cores at software startup
-rw-r--r--config/config.cfg19
-rwxr-xr-xconfig/config.py212
-rw-r--r--config/core_selector.v250
-rw-r--r--eim/build/Makefile7
-rwxr-xr-xsw/Makefile2
-rwxr-xr-xsw/Makefile.i2c2
-rw-r--r--sw/aes_tester.c102
-rw-r--r--sw/capability.c145
-rw-r--r--sw/cryptech.h381
-rw-r--r--sw/hash.c84
-rw-r--r--sw/hash_tester.c206
-rw-r--r--sw/modexp_tester.c333
-rw-r--r--sw/tc_eim.c22
-rw-r--r--sw/trng_extractor.c58
-rw-r--r--sw/trng_tester.c119
15 files changed, 1363 insertions, 579 deletions
diff --git a/config/config.cfg b/config/config.cfg
new file mode 100644
index 0000000..360988e
--- /dev/null
+++ b/config/config.cfg
@@ -0,0 +1,19 @@
+# Config file for the Cryptech Novena FPGA framework.
+
+[default]
+default = rsa
+
+[hash-only]
+cores = sha1, sha256, sha512
+
+[trng-only]
+cores = trng
+
+[modexp-only]
+cores = modexp
+
+[rsa]
+cores = sha256, aes, trng, modexp
+
+[multi-test]
+cores = sha256, aes, aes, chacha, aes
diff --git a/config/config.py b/config/config.py
new file mode 100755
index 0000000..86c8615
--- /dev/null
+++ b/config/config.py
@@ -0,0 +1,212 @@
+#!/usr/bin/env python
+#
+# Generate core_selector.v for a set of cores
+
+import argparse
+import re
+import sys
+if sys.version > '3':
+ import configparser
+else:
+ import ConfigParser as configparser
+
+# defaults
+config = 'config.cfg'
+outfile = 'core_selector.v'
+section = ''
+cores = []
+
+# added cores for TRNG, muxed through trng.v
+trng_cores = ['avalanche_entropy', 'rosc_entropy', 'trng_mixer', 'trng_csprng']
+
+# parse the command line
+def cmdParse():
+ global config, outfile, section, cores
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--cores', help='comma-delimited list of cores')
+ parser.add_argument('-c', '--config', default=config,
+ help='config file (default "%s")' % config)
+ parser.add_argument('-s', '--section', help='config file section')
+ parser.add_argument('-o', '--outfile',
+ help='output file (default "%s")' % outfile)
+ args = parser.parse_args()
+
+ if args.cores:
+ cores = re.split(',\s*', args.cores)
+ if args.config:
+ config = args.config
+ if args.outfile:
+ outfile = args.outfile
+ if args.section:
+ section = args.section
+
+# parse the config file
+def configParse(section):
+ cfg = configparser.ConfigParser()
+ try:
+ with open(config, 'r') as f:
+ cfg.readfp(f)
+ except (IOError, configparser.MissingSectionHeaderError) as e:
+ print e
+ exit(1);
+
+ try:
+ if not section:
+ section = cfg.get('default', 'default')
+ cores = cfg.get(section, 'cores')
+ except (configparser.NoSectionError, configparser.NoOptionError) as e:
+ print e
+ exit(1);
+
+ return re.split(r',\s*', cores)
+
+# create an entry in the Core Address Table
+def createAddr(core, corenum):
+ return " localparam CORE_ADDR_{:21s} = 9'h{:02x};\n".format(core.upper(), corenum)
+
+# create an instantiation of the core
+# This is complicated because TRNG is a mux for 5 cores.
+def createInstance(core):
+ core_stripped = re.sub('_\d+$', '', core)
+ if core_stripped == 'trng':
+ s3 = "(addr_core_num >= CORE_ADDR_TRNG) && (addr_core_num <= CORE_ADDR_TRNG_CSPRNG)"
+ s4 = " wire [3:0] trng_prefix = addr_core_num[3:0] - CORE_ADDR_TRNG;\n"
+ s5 = "{trng_prefix, addr_core_reg}"
+ s6 = ",\n\n .avalanche_noise(noise),\n .debug(debug)"
+ else:
+ s3 = "(addr_core_num == CORE_ADDR_{0})".format(core.upper())
+ s4 = ""
+ s5 = "addr_core_reg"
+ s6 = ""
+
+ return "\
+ //----------------------------------------------------------------\n\
+ // {1}\n\
+ //----------------------------------------------------------------\n\
+ wire enable_{0} = {3};\n\
+ wire [31: 0] read_data_{0};\n\
+ wire error_{0};\n\
+{4}\n\
+ {2} {0}_inst\n\
+ (\n\
+ .clk(sys_clk),\n\
+ .reset_n(~sys_rst),\n\
+\n\
+ .cs(enable_{0} & (sys_eim_rd | sys_eim_wr)),\n\
+ .we(sys_eim_wr),\n\
+\n\
+ .address({5}),\n\
+ .write_data(sys_write_data),\n\
+ .read_data(read_data_{0}){6}\n\
+ );\n\n\n".format(core, core.upper(), core_stripped, s3, s4, s5, s6)
+
+# create an entry in the Output (Read Data) Multiplexer
+def createMux(core, core0):
+ return "\
+ CORE_ADDR_{0}:\n\
+ begin\n\
+ sys_read_data_mux = read_data_{1};\n\
+ sys_error_mux = error_{1};\n\
+ end\n".format(core.upper(), core0)
+
+# create the core_selector module
+def createModule(cores):
+ cores = ['board_regs', 'comm_regs'] + cores
+
+ # if multiple instances of a core, number them
+ for a in set([x for x in cores if cores.count(x) > 1]):
+ i = 0
+ j = 0
+ while (1):
+ try:
+ j = cores.index(a, j)
+ except ValueError:
+ break
+ cores[j] += '_' + str(i)
+ i += 1
+ j += 1
+
+ addrs = ""
+ insts = ""
+ muxs = ""
+ corenum = 0
+ for core in cores:
+ addrs += createAddr(core, corenum)
+ insts += createInstance(core)
+ muxs += createMux(core, core)
+ corenum += 1
+ if core == 'trng':
+ for tcore in trng_cores:
+ addrs += createAddr(tcore, corenum)
+ muxs += createMux(tcore, core)
+ corenum += 1
+
+ # write the boilerplate and all per-core bits
+ with open(outfile, 'w') as f:
+ f.write("\
+// NOTE: This file is generated; do not edit by hand.\n\
+\n\
+module core_selector\n\
+ (\n\
+ input wire sys_clk,\n\
+ input wire sys_rst,\n\
+\n\
+ input wire [16: 0] sys_eim_addr,\n\
+ input wire sys_eim_wr,\n\
+ input wire sys_eim_rd,\n\
+ output wire [31: 0] sys_read_data,\n\
+ input wire [31: 0] sys_write_data,\n\
+ output wire sys_error,\n\
+\n\
+ input wire noise,\n\
+ output wire [7 : 0] debug\n\
+ );\n\
+\n\
+\n\
+ //----------------------------------------------------------------\n\
+ // Address Decoder\n\
+ //----------------------------------------------------------------\n\
+ // upper 9 bits specify core being addressed\n\
+ wire [ 8: 0] addr_core_num = sys_eim_addr[16: 8];\n\
+ // lower 8 bits specify register offset in core\n\
+ wire [ 7: 0] addr_core_reg = sys_eim_addr[ 7: 0];\n\
+\n\n\
+ //----------------------------------------------------------------\n\
+ // Core Address Table\n\
+ //----------------------------------------------------------------\n\
+{0}\n\
+\n\
+{1}\n\
+ //----------------------------------------------------------------\n\
+ // Output (Read Data) Multiplexer\n\
+ //----------------------------------------------------------------\n\
+ reg [31: 0] sys_read_data_mux;\n\
+ assign sys_read_data = sys_read_data_mux;\n\
+ reg sys_error_mux;\n\
+ assign sys_error = sys_error_mux;\n\
+\n\
+ always @*\n\
+\n\
+ case (addr_core_num)\n\
+{2}\n\
+ default:\n\
+ begin\n\
+ sys_read_data_mux = {{32{{1'b0}}}};\n\
+ sys_error_mux = 1;\n\
+ end\n\
+ endcase\n\
+\n\
+\n\
+endmodule\n\
+\n\
+\n\
+//======================================================================\n\
+// EOF core_selector.v\n\
+//======================================================================\n".format(addrs, insts, muxs))
+
+# main
+cmdParse()
+if not cores:
+ cores = configParse(section)
+createModule(cores)
diff --git a/config/core_selector.v b/config/core_selector.v
new file mode 100644
index 0000000..4debd60
--- /dev/null
+++ b/config/core_selector.v
@@ -0,0 +1,250 @@
+// NOTE: This file is generated; do not edit by hand.
+
+module core_selector
+ (
+ input wire sys_clk,
+ input wire sys_rst,
+
+ input wire [16: 0] sys_eim_addr,
+ input wire sys_eim_wr,
+ input wire sys_eim_rd,
+ output wire [31: 0] sys_read_data,
+ input wire [31: 0] sys_write_data,
+ output wire sys_error,
+
+ input wire noise,
+ output wire [7 : 0] debug
+ );
+
+
+ //----------------------------------------------------------------
+ // Address Decoder
+ //----------------------------------------------------------------
+ // upper 9 bits specify core being addressed
+ wire [ 8: 0] addr_core_num = sys_eim_addr[16: 8];
+ // lower 8 bits specify register offset in core
+ wire [ 7: 0] addr_core_reg = sys_eim_addr[ 7: 0];
+
+
+ //----------------------------------------------------------------
+ // Core Address Table
+ //----------------------------------------------------------------
+ localparam CORE_ADDR_BOARD_REGS = 9'h00;
+ localparam CORE_ADDR_COMM_REGS = 9'h01;
+ localparam CORE_ADDR_SHA256 = 9'h02;
+ localparam CORE_ADDR_AES = 9'h03;
+ localparam CORE_ADDR_TRNG = 9'h04;
+ localparam CORE_ADDR_AVALANCHE_ENTROPY = 9'h05;
+ localparam CORE_ADDR_ROSC_ENTROPY = 9'h06;
+ localparam CORE_ADDR_TRNG_MIXER = 9'h07;
+ localparam CORE_ADDR_TRNG_CSPRNG = 9'h08;
+ localparam CORE_ADDR_MODEXP = 9'h09;
+
+
+ //----------------------------------------------------------------
+ // BOARD_REGS
+ //----------------------------------------------------------------
+ wire enable_board_regs = (addr_core_num == CORE_ADDR_BOARD_REGS);
+ wire [31: 0] read_data_board_regs;
+ wire error_board_regs;
+
+ board_regs board_regs_inst
+ (
+ .clk(sys_clk),
+ .reset_n(~sys_rst),
+
+ .cs(enable_board_regs & (sys_eim_rd | sys_eim_wr)),
+ .we(sys_eim_wr),
+
+ .address(addr_core_reg),
+ .write_data(sys_write_data),
+ .read_data(read_data_board_regs)
+ );
+
+
+ //----------------------------------------------------------------
+ // COMM_REGS
+ //----------------------------------------------------------------
+ wire enable_comm_regs = (addr_core_num == CORE_ADDR_COMM_REGS);
+ wire [31: 0] read_data_comm_regs;
+ wire error_comm_regs;
+
+ comm_regs comm_regs_inst
+ (
+ .clk(sys_clk),
+ .reset_n(~sys_rst),
+
+ .cs(enable_comm_regs & (sys_eim_rd | sys_eim_wr)),
+ .we(sys_eim_wr),
+
+ .address(addr_core_reg),
+ .write_data(sys_write_data),
+ .read_data(read_data_comm_regs)
+ );
+
+
+ //----------------------------------------------------------------
+ // SHA256
+ //----------------------------------------------------------------
+ wire enable_sha256 = (addr_core_num == CORE_ADDR_SHA256);
+ wire [31: 0] read_data_sha256;
+ wire error_sha256;
+
+ sha256 sha256_inst
+ (
+ .clk(sys_clk),
+ .reset_n(~sys_rst),
+
+ .cs(enable_sha256 & (sys_eim_rd | sys_eim_wr)),
+ .we(sys_eim_wr),
+
+ .address(addr_core_reg),
+ .write_data(sys_write_data),
+ .read_data(read_data_sha256)
+ );
+
+
+ //----------------------------------------------------------------
+ // AES
+ //----------------------------------------------------------------
+ wire enable_aes = (addr_core_num == CORE_ADDR_AES);
+ wire [31: 0] read_data_aes;
+ wire error_aes;
+
+ aes aes_inst
+ (
+ .clk(sys_clk),
+ .reset_n(~sys_rst),
+
+ .cs(enable_aes & (sys_eim_rd | sys_eim_wr)),
+ .we(sys_eim_wr),
+
+ .address(addr_core_reg),
+ .write_data(sys_write_data),
+ .read_data(read_data_aes)
+ );
+
+
+ //----------------------------------------------------------------
+ // TRNG
+ //----------------------------------------------------------------
+ wire enable_trng = (addr_core_num >= CORE_ADDR_TRNG) && (addr_core_num <= CORE_ADDR_TRNG_CSPRNG);
+ wire [31: 0] read_data_trng;
+ wire error_trng;
+ wire [3:0] trng_prefix = addr_core_num[3:0] - CORE_ADDR_TRNG;
+
+ trng trng_inst
+ (
+ .clk(sys_clk),
+ .reset_n(~sys_rst),
+
+ .cs(enable_trng & (sys_eim_rd | sys_eim_wr)),
+ .we(sys_eim_wr),
+
+ .address({trng_prefix, addr_core_reg}),
+ .write_data(sys_write_data),
+ .read_data(read_data_trng),
+
+ .avalanche_noise(noise),
+ .debug(debug)
+ );
+
+
+ //----------------------------------------------------------------
+ // MODEXP
+ //----------------------------------------------------------------
+ wire enable_modexp = (addr_core_num == CORE_ADDR_MODEXP);
+ wire [31: 0] read_data_modexp;
+ wire error_modexp;
+
+ modexp modexp_inst
+ (
+ .clk(sys_clk),
+ .reset_n(~sys_rst),
+
+ .cs(enable_modexp & (sys_eim_rd | sys_eim_wr)),
+ .we(sys_eim_wr),
+
+ .address(addr_core_reg),
+ .write_data(sys_write_data),
+ .read_data(read_data_modexp)
+ );
+
+
+
+ //----------------------------------------------------------------
+ // Output (Read Data) Multiplexer
+ //----------------------------------------------------------------
+ reg [31: 0] sys_read_data_mux;
+ assign sys_read_data = sys_read_data_mux;
+ reg sys_error_mux;
+ assign sys_error = sys_error_mux;
+
+ always @*
+
+ case (addr_core_num)
+ CORE_ADDR_BOARD_REGS:
+ begin
+ sys_read_data_mux = read_data_board_regs;
+ sys_error_mux = error_board_regs;
+ end
+ CORE_ADDR_COMM_REGS:
+ begin
+ sys_read_data_mux = read_data_comm_regs;
+ sys_error_mux = error_comm_regs;
+ end
+ CORE_ADDR_SHA256:
+ begin
+ sys_read_data_mux = read_data_sha256;
+ sys_error_mux = error_sha256;
+ end
+ CORE_ADDR_AES:
+ begin
+ sys_read_data_mux = read_data_aes;
+ sys_error_mux = error_aes;
+ end
+ CORE_ADDR_TRNG:
+ begin
+ sys_read_data_mux = read_data_trng;
+ sys_error_mux = error_trng;
+ end
+ CORE_ADDR_AVALANCHE_ENTROPY:
+ begin
+ sys_read_data_mux = read_data_trng;
+ sys_error_mux = error_trng;
+ end
+ CORE_ADDR_ROSC_ENTROPY:
+ begin
+ sys_read_data_mux = read_data_trng;
+ sys_error_mux = error_trng;
+ end
+ CORE_ADDR_TRNG_MIXER:
+ begin
+ sys_read_data_mux = read_data_trng;
+ sys_error_mux = error_trng;
+ end
+ CORE_ADDR_TRNG_CSPRNG:
+ begin
+ sys_read_data_mux = read_data_trng;
+ sys_error_mux = error_trng;
+ end
+ CORE_ADDR_MODEXP:
+ begin
+ sys_read_data_mux = read_data_modexp;
+ sys_error_mux = error_modexp;
+ end
+
+ default:
+ begin
+ sys_read_data_mux = {32{1'b0}};
+ sys_error_mux = 1;
+ end
+ endcase
+
+
+endmodule
+
+
+//======================================================================
+// EOF core_selector.v
+//======================================================================
diff --git a/eim/build/Makefile b/eim/build/Makefile
index 7bb4ffd..d598126 100644
--- a/eim/build/Makefile
+++ b/eim/build/Makefile
@@ -12,12 +12,7 @@ vfiles = \
../../common/rtl/novena_regs.v \
../../common/rtl/novena_clkmgr.v \
../../common/rtl/ipcore/clkmgr_dcm.v \
- ../../../common/core_selector/src/rtl/core_selector.v \
- ../../../common/core_selector/src/rtl/global_selector.v \
- ../../../common/core_selector/src/rtl/hash_selector.v \
- ../../../common/core_selector/src/rtl/rng_selector.v \
- ../../../common/core_selector/src/rtl/cipher_selector.v \
- ../../../common/core_selector/src/rtl/math_selector.v \
+ ../../config/core_selector.v \
../../../../comm/eim/src/rtl/cdc_bus_pulse.v \
../../../../comm/eim/src/rtl/eim_arbiter_cdc.v \
../../../../comm/eim/src/rtl/eim_arbiter.v \
diff --git a/sw/Makefile b/sw/Makefile
index 2aa4927..d1f33f2 100755
--- a/sw/Makefile
+++ b/sw/Makefile
@@ -15,7 +15,7 @@ all: $(LIB) $(BIN)
%.o: %.c $(INC)
$(CC) $(CFLAGS) -c -o $@ $<
-libcryptech.a: tc_eim.o novena-eim.o
+libcryptech.a: tc_eim.o novena-eim.o capability.o
ar rcs $@ $^
hash_tester: hash_tester.o $(LIB)
diff --git a/sw/Makefile.i2c b/sw/Makefile.i2c
index 98cd541..1294360 100755
--- a/sw/Makefile.i2c
+++ b/sw/Makefile.i2c
@@ -15,7 +15,7 @@ all: $(LIB) $(BIN)
%.o: %.c $(INC)
$(CC) $(CFLAGS) -c -o $@ $<
-libcryptech_i2c.a: tc_i2c.o
+libcryptech_i2c.a: tc_i2c.o capability.o
ar rcs $@ $^
hash_tester_i2c: hash_tester.o $(LIB)
diff --git a/sw/aes_tester.c b/sw/aes_tester.c
index 36a3e0d..497f334 100644
--- a/sw/aes_tester.c
+++ b/sw/aes_tester.c
@@ -69,16 +69,12 @@
//------------------------------------------------------------------
//------------------------------------------------------------------
+static off_t aes_addr_base;
+
static void check_aes_access(void)
{
- uint8_t name0[4], name1[4], version[4];
-
- printf("Trying to read the aes core name\n");
-
- check(tc_read(AES_ADDR_NAME0, name0, sizeof(name0)));
- check(tc_read(AES_ADDR_NAME1, name1, sizeof(name1)));
- check(tc_read(AES_ADDR_VERSION, version, sizeof(version)));
- printf("%4.4s%4.4s %4.4s\n\n", name0, name1, version);
+ aes_addr_base = tc_core_base("aes");
+ assert(aes_addr_base != 0);
}
@@ -126,24 +122,24 @@ static void single_block_test(const uint32_t keylength, const uint32_t *key,
key[0], key[1], key[2], key[3]);
}
- tc_w32(AES_ADDR_KEY0, key[0]);
- tc_w32(AES_ADDR_KEY1, key[1]);
- tc_w32(AES_ADDR_KEY2, key[2]);
- tc_w32(AES_ADDR_KEY3, key[3]);
+ tc_w32(aes_addr_base + AES_ADDR_KEY0, key[0]);
+ tc_w32(aes_addr_base + AES_ADDR_KEY1, key[1]);
+ tc_w32(aes_addr_base + AES_ADDR_KEY2, key[2]);
+ tc_w32(aes_addr_base + AES_ADDR_KEY3, key[3]);
if (keylength == 256) {
- tc_w32(AES_ADDR_KEY4, key[4]);
- tc_w32(AES_ADDR_KEY5, key[5]);
- tc_w32(AES_ADDR_KEY6, key[6]);
- tc_w32(AES_ADDR_KEY7, key[7]);
+ tc_w32(aes_addr_base + AES_ADDR_KEY4, key[4]);
+ tc_w32(aes_addr_base + AES_ADDR_KEY5, key[5]);
+ tc_w32(aes_addr_base + AES_ADDR_KEY6, key[6]);
+ tc_w32(aes_addr_base + AES_ADDR_KEY7, key[7]);
}
if (CHECK_WRITE) {
const uint32_t
- k0 = tc_r32(AES_ADDR_KEY0), k1 = tc_r32(AES_ADDR_KEY1),
- k2 = tc_r32(AES_ADDR_KEY2), k3 = tc_r32(AES_ADDR_KEY3),
- k4 = tc_r32(AES_ADDR_KEY4), k5 = tc_r32(AES_ADDR_KEY5),
- k6 = tc_r32(AES_ADDR_KEY6), k7 = tc_r32(AES_ADDR_KEY7);
+ k0 = tc_r32(aes_addr_base + AES_ADDR_KEY0), k1 = tc_r32(aes_addr_base + AES_ADDR_KEY1),
+ k2 = tc_r32(aes_addr_base + AES_ADDR_KEY2), k3 = tc_r32(aes_addr_base + AES_ADDR_KEY3),
+ k4 = tc_r32(aes_addr_base + AES_ADDR_KEY4), k5 = tc_r32(aes_addr_base + AES_ADDR_KEY5),
+ k6 = tc_r32(aes_addr_base + AES_ADDR_KEY6), k7 = tc_r32(aes_addr_base + AES_ADDR_KEY7);
const int
ok1 = k0 == key[0] && k1 == key[1] && k2 == key[2] && k3 == key[3],
ok2 = k4 == key[4] && k5 == key[5] && k6 == key[6] && k7 == key[7];
@@ -158,26 +154,26 @@ static void single_block_test(const uint32_t keylength, const uint32_t *key,
// Performing init i.e. key expansion,
printf("Doing key init\n");
if (keylength == 256)
- tc_w32(AES_ADDR_CONFIG, 0x00000002);
+ tc_w32(aes_addr_base + AES_ADDR_CONFIG, 0x00000002);
else
- tc_w32(AES_ADDR_CONFIG, 0x00000000);
+ tc_w32(aes_addr_base + AES_ADDR_CONFIG, 0x00000000);
- tc_w32(AES_ADDR_CTRL, 0x00000001);
+ tc_w32(aes_addr_base + AES_ADDR_CTRL, 0x00000001);
if (VERBOSE)
printf("Writing block 0x%08x 0x%08x 0x%08x 0x%08x\n",
block[0], block[1], block[2], block[3]);
- tc_w32(AES_ADDR_BLOCK0, block[0]);
- tc_w32(AES_ADDR_BLOCK1, block[1]);
- tc_w32(AES_ADDR_BLOCK2, block[2]);
- tc_w32(AES_ADDR_BLOCK3, block[3]);
+ tc_w32(aes_addr_base + AES_ADDR_BLOCK0, block[0]);
+ tc_w32(aes_addr_base + AES_ADDR_BLOCK1, block[1]);
+ tc_w32(aes_addr_base + AES_ADDR_BLOCK2, block[2]);
+ tc_w32(aes_addr_base + AES_ADDR_BLOCK3, block[3]);
if (CHECK_WRITE) {
const uint32_t
- b0 = tc_r32(AES_ADDR_BLOCK0), b1 = tc_r32(AES_ADDR_BLOCK1),
- b2 = tc_r32(AES_ADDR_BLOCK2), b3 = tc_r32(AES_ADDR_BLOCK3);
+ b0 = tc_r32(aes_addr_base + AES_ADDR_BLOCK0), b1 = tc_r32(aes_addr_base + AES_ADDR_BLOCK1),
+ b2 = tc_r32(aes_addr_base + AES_ADDR_BLOCK2), b3 = tc_r32(aes_addr_base + AES_ADDR_BLOCK3);
const int
ok = b0 == block[0] && b1 == block[1] && b2 == block[2] && b3 == block[3];
printf("Reading back block: 0x%08x 0x%08x 0x%08x 0x%08x %s\n",
@@ -188,46 +184,46 @@ static void single_block_test(const uint32_t keylength, const uint32_t *key,
printf("Starting single block encipher operation\n");
if (keylength == 256)
- tc_w32(AES_ADDR_CONFIG, 0x00000003);
+ tc_w32(aes_addr_base + AES_ADDR_CONFIG, 0x00000003);
else
- tc_w32(AES_ADDR_CONFIG, 0x00000001);
+ tc_w32(aes_addr_base + AES_ADDR_CONFIG, 0x00000001);
- tc_w32(AES_ADDR_CTRL, 0x00000002);
+ tc_w32(aes_addr_base + AES_ADDR_CTRL, 0x00000002);
if (VERBOSE)
printf("Checking ready: 0x%08x\n",
- tc_r32(AES_ADDR_STATUS));
+ tc_r32(aes_addr_base + AES_ADDR_STATUS));
- check(tc_wait_ready(AES_ADDR_STATUS));
+ check(tc_wait_ready(aes_addr_base + AES_ADDR_STATUS));
if (VERBOSE)
printf("Ready seen. Result: 0x%08x 0x%08x 0x%08x 0x%08x\n",
- tc_r32(AES_ADDR_RESULT0), tc_r32(AES_ADDR_RESULT1),
- tc_r32(AES_ADDR_RESULT2), tc_r32(AES_ADDR_RESULT3));
+ tc_r32(aes_addr_base + AES_ADDR_RESULT0), tc_r32(aes_addr_base + AES_ADDR_RESULT1),
+ tc_r32(aes_addr_base + AES_ADDR_RESULT2), tc_r32(aes_addr_base + AES_ADDR_RESULT3));
- enc_result[0] = tc_r32(AES_ADDR_RESULT0);
- enc_result[1] = tc_r32(AES_ADDR_RESULT1);
- enc_result[2] = tc_r32(AES_ADDR_RESULT2);
- enc_result[3] = tc_r32(AES_ADDR_RESULT3);
+ enc_result[0] = tc_r32(aes_addr_base + AES_ADDR_RESULT0);
+ enc_result[1] = tc_r32(aes_addr_base + AES_ADDR_RESULT1);
+ enc_result[2] = tc_r32(aes_addr_base + AES_ADDR_RESULT2);
+ enc_result[3] = tc_r32(aes_addr_base + AES_ADDR_RESULT3);
- tc_w32(AES_ADDR_BLOCK0, enc_result[0]);
- tc_w32(AES_ADDR_BLOCK1, enc_result[1]);
- tc_w32(AES_ADDR_BLOCK2, enc_result[2]);
- tc_w32(AES_ADDR_BLOCK3, enc_result[3]);
+ tc_w32(aes_addr_base + AES_ADDR_BLOCK0, enc_result[0]);
+ tc_w32(aes_addr_base + AES_ADDR_BLOCK1, enc_result[1]);
+ tc_w32(aes_addr_base + AES_ADDR_BLOCK2, enc_result[2]);
+ tc_w32(aes_addr_base + AES_ADDR_BLOCK3, enc_result[3]);
// Single block decipher operation.
if (keylength == 256)
- tc_w32(AES_ADDR_CONFIG, 0x00000002);
+ tc_w32(aes_addr_base + AES_ADDR_CONFIG, 0x00000002);
else
- tc_w32(AES_ADDR_CONFIG, 0x00000000);
- tc_w32(AES_ADDR_CTRL, 0x00000002);
+ tc_w32(aes_addr_base + AES_ADDR_CONFIG, 0x00000000);
+ tc_w32(aes_addr_base + AES_ADDR_CTRL, 0x00000002);
- check(tc_wait_ready(AES_ADDR_STATUS));
+ check(tc_wait_ready(aes_addr_base + AES_ADDR_STATUS));
- dec_result[0] = tc_r32(AES_ADDR_RESULT0);
- dec_result[1] = tc_r32(AES_ADDR_RESULT1);
- dec_result[2] = tc_r32(AES_ADDR_RESULT2);
- dec_result[3] = tc_r32(AES_ADDR_RESULT3);
+ dec_result[0] = tc_r32(aes_addr_base + AES_ADDR_RESULT0);
+ dec_result[1] = tc_r32(aes_addr_base + AES_ADDR_RESULT1);
+ dec_result[2] = tc_r32(aes_addr_base + AES_ADDR_RESULT2);
+ dec_result[3] = tc_r32(aes_addr_base + AES_ADDR_RESULT3);
printf("Generated cipher block: 0x%08x 0x%08x 0x%08x 0x%08x\n",
enc_result[0], enc_result[1], enc_result[2], enc_result[3]);
@@ -298,7 +294,7 @@ static void run_nist_tests()
int main(int argc, char *argv[])
{
check_aes_access();
- tc_set_debug(1);
+// tc_set_debug(1);
run_nist_tests();
return 0;
diff --git a/sw/capability.c b/sw/capability.c
new file mode 100644
index 0000000..9b29c98
--- /dev/null
+++ b/sw/capability.c
@@ -0,0 +1,145 @@
+/*
+ * capability.c
+ * ------------
+ * This module contains code to probe the FPGA for its installed 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 <stdint.h>
+#include <string.h>
+
+#include "cryptech.h"
+
+static struct core_info *tc_probe_cores(void)
+{
+ static struct core_info *head = NULL;
+ struct core_info *tail = NULL, *node;
+ off_t offset;
+
+ if (head != NULL)
+ return head;
+
+ /* XXX could use unix linked-list macros */
+ for (offset = 0; offset < 0x10000; offset += CORE_SIZE) {
+ node = calloc(1, sizeof(struct core_info));
+ if (node == NULL) {
+ perror("malloc");
+ goto fail;
+ }
+
+ if (tc_read(offset, (uint8_t *)&node->name[0], 8) ||
+ tc_read(offset + 2, (uint8_t *)&node->version[0], 4)) {
+ fprintf(stderr, "tc_read(%04x) error\n", (unsigned int)offset);
+ free(node);
+ goto fail;
+ }
+ if (node->name[0] == 0) {
+ free(node);
+ break;
+ }
+
+ node->base = offset;
+
+ if (head == NULL) {
+ head = tail = node;
+ }
+ else {
+ tail->next = node;
+ tail = node;
+ }
+ }
+
+ return head;
+
+fail:
+ while (head) {
+ node = head;
+ head = node->next;
+ free(node);
+ }
+ return NULL;
+}
+
+static struct core_info *tc_core_find(struct core_info *node, char *name)
+{
+ struct core_info *core;
+ size_t len;
+
+ if ((name == NULL) || (*name == '\0'))
+ return node;
+
+ len = strlen(name);
+ for (core = node->next; core != NULL; core = core->next) {
+ if (strncmp(core->name, name, len) == 0)
+ return core;
+ }
+
+ return NULL;
+}
+
+struct core_info *tc_core_first(char *name)
+{
+ struct core_info *head;
+
+ head = tc_probe_cores();
+ if (head == NULL)
+ return NULL;
+
+ return tc_core_find(head, name);
+}
+
+struct core_info *tc_core_next(struct core_info *node, char *name)
+{
+ if (node == NULL) {
+ node = tc_core_first(name);
+ if (node == NULL)
+ return NULL;
+ }
+
+ return tc_core_find(node->next, name);
+}
+
+off_t tc_core_base(char *name)
+{
+ struct core_info *node;
+
+ node = tc_core_first(name);
+ if (node == NULL)
+ return 0;
+ /* 0 is the base address for the "board-regs" core, installed
+ * unconditionally at that address. Probing for any other core,
+ * and getting 0, should be considered an error.
+ */
+
+ return node->base;
+}
diff --git a/sw/cryptech.h b/sw/cryptech.h
index 5b01bc9..9535061 100644
--- a/sw/cryptech.h
+++ b/sw/cryptech.h
@@ -70,17 +70,6 @@ in order to map it into a 16-bit address space.
// Default sizes
//------------------------------------------------------------------
#define CORE_SIZE 0x100
-#define SEGMENT_SIZE 0x20 * CORE_SIZE
-
-
-//------------------------------------------------------------------
-// Segments
-//------------------------------------------------------------------
-#define SEGMENT_OFFSET_GLOBALS 0 * SEGMENT_SIZE
-#define SEGMENT_OFFSET_HASHES 1 * SEGMENT_SIZE
-#define SEGMENT_OFFSET_RNGS 2 * SEGMENT_SIZE
-#define SEGMENT_OFFSET_CIPHERS 3 * SEGMENT_SIZE
-#define SEGMENT_OFFSET_MATH 4 * SEGMENT_SIZE
//------------------------------------------------------------------
@@ -104,19 +93,16 @@ in order to map it into a 16-bit address space.
//------------------------------------------------------------------
-// Board segment.
// Board-level registers and communication channel registers
//------------------------------------------------------------------
-#define BOARD_ADDR_BASE SEGMENT_OFFSET_GLOBALS + (0 * 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_NAME0 ADDR_NAME0
+#define BOARD_ADDR_NAME1 ADDR_NAME1
+#define BOARD_ADDR_VERSION ADDR_VERSION
+#define BOARD_ADDR_DUMMY 0xFF
-#define COMM_ADDR_BASE SEGMENT_OFFSET_GLOBALS + (1 * 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
+#define COMM_ADDR_NAME0 ADDR_NAME0
+#define COMM_ADDR_NAME1 ADDR_NAME1
+#define COMM_ADDR_VERSION ADDR_VERSION
// current name and version values
#define NOVENA_BOARD_NAME0 "PVT1"
@@ -133,45 +119,42 @@ in order to map it into a 16-bit address space.
//------------------------------------------------------------------
-// Hashes segment.
+// Hash cores
//------------------------------------------------------------------
// addresses common to all hash cores
#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 * 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
+// SHA-1 core
+#define SHA1_ADDR_NAME0 ADDR_NAME0
+#define SHA1_ADDR_NAME1 ADDR_NAME1
+#define SHA1_ADDR_VERSION ADDR_VERSION
+#define SHA1_ADDR_CTRL ADDR_CTRL
+#define SHA1_ADDR_STATUS ADDR_STATUS
+#define SHA1_ADDR_BLOCK ADDR_BLOCK
+#define SHA1_ADDR_DIGEST ADDR_DIGEST
#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 * 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_ADDR_NAME0 ADDR_NAME0
+#define SHA256_ADDR_NAME1 ADDR_NAME1
+#define SHA256_ADDR_VERSION ADDR_VERSION
+#define SHA256_ADDR_CTRL ADDR_CTRL
+#define SHA256_ADDR_STATUS ADDR_STATUS
+#define SHA256_ADDR_BLOCK ADDR_BLOCK
+#define SHA256_ADDR_DIGEST ADDR_DIGEST
#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 * 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_ADDR_NAME0 ADDR_NAME0
+#define SHA512_ADDR_NAME1 ADDR_NAME1
+#define SHA512_ADDR_VERSION ADDR_VERSION
+#define SHA512_ADDR_CTRL ADDR_CTRL
+#define SHA512_ADDR_STATUS ADDR_STATUS
+#define SHA512_ADDR_BLOCK ADDR_BLOCK
+#define SHA512_ADDR_DIGEST 0x40
#define SHA512_BLOCK_LEN bitsToBytes(1024)
#define SHA512_LENGTH_LEN bitsToBytes(128)
#define SHA512_224_DIGEST_LEN bitsToBytes(224)
@@ -198,69 +181,64 @@ in order to map it into a 16-bit address space.
//-----------------------------------------------------------------
-// TRNG segment.
+// TRNG cores
//-----------------------------------------------------------------
// 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_ADDR_NAME0 ADDR_NAME0
+#define TRNG_ADDR_NAME1 ADDR_NAME1
+#define TRNG_ADDR_VERSION ADDR_VERSION
+#define TRNG_ADDR_CTRL 0x10
#define TRNG_CTRL_DISCARD 1
#define TRNG_CTRL_TEST_MODE 2
-#define TRNG_ADDR_STATUS TRNG_ADDR_BASE + 0x11
+#define TRNG_ADDR_STATUS 0x11
// no status bits defined (yet)
-#define TRNG_ADDR_DELAY TRNG_ADDR_BASE + 0x13
+#define TRNG_ADDR_DELAY 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_ADDR_NAME0 ADDR_NAME0
+#define ENTROPY1_ADDR_NAME1 ADDR_NAME1
+#define ENTROPY1_ADDR_VERSION ADDR_VERSION
+#define ENTROPY1_ADDR_CTRL 0x10
#define ENTROPY1_CTRL_ENABLE 1
-#define ENTROPY1_ADDR_STATUS ENTROPY1_ADDR_BASE + 0x11
+#define ENTROPY1_ADDR_STATUS 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 ENTROPY1_ADDR_ENTROPY 0x20
+#define ENTROPY1_ADDR_DELTA 0x30
+
+#define ENTROPY2_ADDR_NAME0 ADDR_NAME0
+#define ENTROPY2_ADDR_NAME1 ADDR_NAME1
+#define ENTROPY2_ADDR_VERSION ADDR_VERSION
+#define ENTROPY2_ADDR_CTRL 0x10
#define ENTROPY2_CTRL_ENABLE 1
-#define ENTROPY2_ADDR_STATUS ENTROPY2_ADDR_BASE + 0x11
+#define ENTROPY2_ADDR_STATUS 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 ENTROPY2_ADDR_OPA 0x18
+#define ENTROPY2_ADDR_OPB 0x19
+#define ENTROPY2_ADDR_ENTROPY 0x20
+#define ENTROPY2_ADDR_RAW 0x21
+#define ENTROPY2_ADDR_ROSC 0x22
+
+#define MIXER_ADDR_NAME0 ADDR_NAME0
+#define MIXER_ADDR_NAME1 ADDR_NAME1
+#define MIXER_ADDR_VERSION ADDR_VERSION
+#define MIXER_ADDR_CTRL 0x10
#define MIXER_CTRL_ENABLE 1
#define MIXER_CTRL_RESTART 2
-#define MIXER_ADDR_STATUS MIXER_ADDR_BASE + 0x11
+#define MIXER_ADDR_STATUS 0x11
// no status bits defined (yet)
-#define MIXER_ADDR_TIMEOUT MIXER_ADDR_BASE + 0x20
+#define MIXER_ADDR_TIMEOUT 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_ADDR_NAME0 ADDR_NAME0
+#define CSPRNG_ADDR_NAME1 ADDR_NAME1
+#define CSPRNG_ADDR_VERSION ADDR_VERSION
+#define CSPRNG_ADDR_CTRL 0x10
#define CSPRNG_CTRL_ENABLE 1
#define CSPRNG_CTRL_SEED 2
-#define CSPRNG_ADDR_STATUS CSPRNG_ADDR_BASE + 0x11
+#define CSPRNG_ADDR_STATUS 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 0x20
+#define CSPRNG_ADDR_NROUNDS 0x40
+#define CSPRNG_ADDR_NBLOCKS_LO 0x41
+#define CSPRNG_ADDR_NBLOCKS_HI 0x42
// current name and version values
#define TRNG_NAME0 "trng"
@@ -275,44 +253,47 @@ in order to map it into a 16-bit address space.
#define ROSC_ENTROPY_NAME1 " ent"
#define ROSC_ENTROPY_VERSION "0.10"
+#define MIXER_NAME0 "rngm"
+#define MIXER_NAME1 "ixer"
+#define MIXER_VERSION "0.50"
+
#define CSPRNG_NAME0 "cspr"
#define CSPRNG_NAME1 "ng "
#define CSPRNG_VERSION "0.50"
// -----------------------------------------------------------------
-// CIPHERS segment.
+// Cipher cores
// -----------------------------------------------------------------
-// aes core.
-#define AES_ADDR_BASE SEGMENT_OFFSET_CIPHERS + (0 * CORE_SIZE)
-#define AES_ADDR_NAME0 AES_ADDR_BASE + ADDR_NAME0
-#define AES_ADDR_NAME1 AES_ADDR_BASE + ADDR_NAME1
-#define AES_ADDR_VERSION AES_ADDR_BASE + ADDR_VERSION
-#define AES_ADDR_CTRL AES_ADDR_BASE + ADDR_CTRL
-#define AES_ADDR_STATUS AES_ADDR_BASE + ADDR_STATUS
-
-#define AES_ADDR_CONFIG AES_ADDR_BASE + 0x0a
+// AES core
+#define AES_ADDR_NAME0 ADDR_NAME0
+#define AES_ADDR_NAME1 ADDR_NAME1
+#define AES_ADDR_VERSION ADDR_VERSION
+#define AES_ADDR_CTRL ADDR_CTRL
+#define AES_ADDR_STATUS ADDR_STATUS
+
+#define AES_ADDR_CONFIG 0x0a
#define AES_CONFIG_ENCDEC 1
#define AES_CONFIG_KEYLEN 2
-#define AES_ADDR_KEY0 AES_ADDR_BASE + 0x10
-#define AES_ADDR_KEY1 AES_ADDR_BASE + 0x11
-#define AES_ADDR_KEY2 AES_ADDR_BASE + 0x12
-#define AES_ADDR_KEY3 AES_ADDR_BASE + 0x13
-#define AES_ADDR_KEY4 AES_ADDR_BASE + 0x14
-#define AES_ADDR_KEY5 AES_ADDR_BASE + 0x15
-#define AES_ADDR_KEY6 AES_ADDR_BASE + 0x16
-#define AES_ADDR_KEY7 AES_ADDR_BASE + 0x17
-
-#define AES_ADDR_BLOCK0 AES_ADDR_BASE + 0x20
-#define AES_ADDR_BLOCK1 AES_ADDR_BASE + 0x21
-#define AES_ADDR_BLOCK2 AES_ADDR_BASE + 0x22
-#define AES_ADDR_BLOCK3 AES_ADDR_BASE + 0x23
-
-#define AES_ADDR_RESULT0 AES_ADDR_BASE + 0x30
-#define AES_ADDR_RESULT1 AES_ADDR_BASE + 0x31
-#define AES_ADDR_RESULT2 AES_ADDR_BASE + 0x32
-#define AES_ADDR_RESULT3 AES_ADDR_BASE + 0x33
+#define AES_ADDR_KEY0 0x10
+#define AES_ADDR_KEY1 0x11
+#define AES_ADDR_KEY2 0x12
+#define AES_ADDR_KEY3 0x13
+#define AES_ADDR_KEY4 0x14
+#define AES_ADDR_KEY5 0x15
+#define AES_ADDR_KEY6 0x16
+#define AES_ADDR_KEY7 0x17
+
+#define AES_ADDR_BLOCK0 0x20
+#define AES_ADDR_BLOCK1 0x21
+#define AES_ADDR_BLOCK2 0x22
+#define AES_ADDR_BLOCK3 0x23
+
+#define AES_ADDR_RESULT0 0x30
+#define AES_ADDR_RESULT1 0x31
+#define AES_ADDR_RESULT2 0x32
+#define AES_ADDR_RESULT3 0x33
// current name and version values
#define AES_CORE_NAME0 "aes "
@@ -321,63 +302,62 @@ in order to map it into a 16-bit address space.
// Chacha core
-#define CHACHA_ADDR_BASE SEGMENT_OFFSET_CIPHERS + (1 * CORE_SIZE)
-#define CHACHA_ADDR_NAME0 CHACHA_ADDR_BASE + ADDR_NAME0
-#define CHACHA_ADDR_NAME1 CHACHA_ADDR_BASE + ADDR_NAME1
-#define CHACHA_ADDR_VERSION CHACHA_ADDR_BASE + ADDR_VERSION
-#define CHACHA_ADDR_CTRL CHACHA_ADDR_BASE + ADDR_CTRL
-#define CHACHA_ADDR_STATUS CHACHA_ADDR_BASE + ADDR_STATUS
-
-#define CHACHA_ADDR_KEYLEN CHACHA_ADDR_BASE + 0x0a
+#define CHACHA_ADDR_NAME0 ADDR_NAME0
+#define CHACHA_ADDR_NAME1 ADDR_NAME1
+#define CHACHA_ADDR_VERSION ADDR_VERSION
+#define CHACHA_ADDR_CTRL ADDR_CTRL
+#define CHACHA_ADDR_STATUS ADDR_STATUS
+
+#define CHACHA_ADDR_KEYLEN 0x0a
#define CHACHA_KEYLEN 1
-#define CHACHA_ADDR_ROUNDS CHACHA_ADDR_BASE + 0x0b
-
-#define CHACHA_ADDR_KEY0 CHACHA_ADDR_BASE + 0x10
-#define CHACHA_ADDR_KEY1 CHACHA_ADDR_BASE + 0x11
-#define CHACHA_ADDR_KEY2 CHACHA_ADDR_BASE + 0x12
-#define CHACHA_ADDR_KEY3 CHACHA_ADDR_BASE + 0x13
-#define CHACHA_ADDR_KEY4 CHACHA_ADDR_BASE + 0x14
-#define CHACHA_ADDR_KEY5 CHACHA_ADDR_BASE + 0x15
-#define CHACHA_ADDR_KEY6 CHACHA_ADDR_BASE + 0x16
-#define CHACHA_ADDR_KEY7 CHACHA_ADDR_BASE + 0x17
-
-#define CHACHA_ADDR_IV0 CHACHA_ADDR_BASE + 0x20
-#define CHACHA_ADDR_IV1 CHACHA_ADDR_BASE + 0x21
-
-#define CHACHA_ADDR_DATA_IN0 CHACHA_ADDR_BASE + 0x40
-#define CHACHA_ADDR_DATA_IN1 CHACHA_ADDR_BASE + 0x41
-#define CHACHA_ADDR_DATA_IN2 CHACHA_ADDR_BASE + 0x42
-#define CHACHA_ADDR_DATA_IN3 CHACHA_ADDR_BASE + 0x43
-#define CHACHA_ADDR_DATA_IN4 CHACHA_ADDR_BASE + 0x44
-#define CHACHA_ADDR_DATA_IN5 CHACHA_ADDR_BASE + 0x45
-#define CHACHA_ADDR_DATA_IN6 CHACHA_ADDR_BASE + 0x46
-#define CHACHA_ADDR_DATA_IN7 CHACHA_ADDR_BASE + 0x47
-#define CHACHA_ADDR_DATA_IN8 CHACHA_ADDR_BASE + 0x48
-#define CHACHA_ADDR_DATA_IN9 CHACHA_ADDR_BASE + 0x49
-#define CHACHA_ADDR_DATA_IN10 CHACHA_ADDR_BASE + 0x4a
-#define CHACHA_ADDR_DATA_IN11 CHACHA_ADDR_BASE + 0x4b
-#define CHACHA_ADDR_DATA_IN12 CHACHA_ADDR_BASE + 0x4c
-#define CHACHA_ADDR_DATA_IN13 CHACHA_ADDR_BASE + 0x4d
-#define CHACHA_ADDR_DATA_IN14 CHACHA_ADDR_BASE + 0x4e
-#define CHACHA_ADDR_DATA_IN15 CHACHA_ADDR_BASE + 0x4f
-
-#define CHACHA_ADDR_DATA_OUT0 CHACHA_ADDR_BASE + 0x80
-#define CHACHA_ADDR_DATA_OUT1 CHACHA_ADDR_BASE + 0x81
-#define CHACHA_ADDR_DATA_OUT2 CHACHA_ADDR_BASE + 0x82
-#define CHACHA_ADDR_DATA_OUT3 CHACHA_ADDR_BASE + 0x83
-#define CHACHA_ADDR_DATA_OUT4 CHACHA_ADDR_BASE + 0x84
-#define CHACHA_ADDR_DATA_OUT5 CHACHA_ADDR_BASE + 0x85
-#define CHACHA_ADDR_DATA_OUT6 CHACHA_ADDR_BASE + 0x86
-#define CHACHA_ADDR_DATA_OUT7 CHACHA_ADDR_BASE + 0x87
-#define CHACHA_ADDR_DATA_OUT8 CHACHA_ADDR_BASE + 0x88
-#define CHACHA_ADDR_DATA_OUT9 CHACHA_ADDR_BASE + 0x89
-#define CHACHA_ADDR_DATA_OUT10 CHACHA_ADDR_BASE + 0x8a
-#define CHACHA_ADDR_DATA_OUT11 CHACHA_ADDR_BASE + 0x8b
-#define CHACHA_ADDR_DATA_OUT12 CHACHA_ADDR_BASE + 0x8c
-#define CHACHA_ADDR_DATA_OUT13 CHACHA_ADDR_BASE + 0x8d
-#define CHACHA_ADDR_DATA_OUT14 CHACHA_ADDR_BASE + 0x8e
-#define CHACHA_ADDR_DATA_OUT15 CHACHA_ADDR_BASE + 0x8f
+#define CHACHA_ADDR_ROUNDS 0x0b
+
+#define CHACHA_ADDR_KEY0 0x10
+#define CHACHA_ADDR_KEY1 0x11
+#define CHACHA_ADDR_KEY2 0x12
+#define CHACHA_ADDR_KEY3 0x13
+#define CHACHA_ADDR_KEY4 0x14
+#define CHACHA_ADDR_KEY5 0x15
+#define CHACHA_ADDR_KEY6 0x16
+#define CHACHA_ADDR_KEY7 0x17
+
+#define CHACHA_ADDR_IV0 0x20
+#define CHACHA_ADDR_IV1 0x21
+
+#define CHACHA_ADDR_DATA_IN0 0x40
+#define CHACHA_ADDR_DATA_IN1 0x41
+#define CHACHA_ADDR_DATA_IN2 0x42
+#define CHACHA_ADDR_DATA_IN3 0x43
+#define CHACHA_ADDR_DATA_IN4 0x44
+#define CHACHA_ADDR_DATA_IN5 0x45
+#define CHACHA_ADDR_DATA_IN6 0x46
+#define CHACHA_ADDR_DATA_IN7 0x47
+#define CHACHA_ADDR_DATA_IN8 0x48
+#define CHACHA_ADDR_DATA_IN9 0x49
+#define CHACHA_ADDR_DATA_IN10 0x4a
+#define CHACHA_ADDR_DATA_IN11 0x4b
+#define CHACHA_ADDR_DATA_IN12 0x4c
+#define CHACHA_ADDR_DATA_IN13 0x4d
+#define CHACHA_ADDR_DATA_IN14 0x4e
+#define CHACHA_ADDR_DATA_IN15 0x4f
+
+#define CHACHA_ADDR_DATA_OUT0 0x80
+#define CHACHA_ADDR_DATA_OUT1 0x81
+#define CHACHA_ADDR_DATA_OUT2 0x82
+#define CHACHA_ADDR_DATA_OUT3 0x83
+#define CHACHA_ADDR_DATA_OUT4 0x84
+#define CHACHA_ADDR_DATA_OUT5 0x85
+#define CHACHA_ADDR_DATA_OUT6 0x86
+#define CHACHA_ADDR_DATA_OUT7 0x87
+#define CHACHA_ADDR_DATA_OUT8 0x88
+#define CHACHA_ADDR_DATA_OUT9 0x89
+#define CHACHA_ADDR_DATA_OUT10 0x8a
+#define CHACHA_ADDR_DATA_OUT11 0x8b
+#define CHACHA_ADDR_DATA_OUT12 0x8c
+#define CHACHA_ADDR_DATA_OUT13 0x8d
+#define CHACHA_ADDR_DATA_OUT14 0x8e
+#define CHACHA_ADDR_DATA_OUT15 0x8f
// current name and version values
#define CHACHA_NAME0 "chac"
@@ -386,36 +366,35 @@ in order to map it into a 16-bit address space.
// -----------------------------------------------------------------
-// MATH segment.
+// Math cores
// -----------------------------------------------------------------
-// Modexp core.
-#define MODEXP_ADDR_BASE SEGMENT_OFFSET_MATH + (0x00 * CORE_SIZE)
-#define MODEXP_ADDR_NAME0 MODEXP_ADDR_BASE + ADDR_NAME0
-#define MODEXP_ADDR_NAME1 MODEXP_ADDR_BASE + ADDR_NAME1
-#define MODEXP_ADDR_VERSION MODEXP_ADDR_BASE + ADDR_VERSION
-#define MODEXP_ADDR_CTRL MODEXP_ADDR_BASE + ADDR_CTRL
+// Modular exponentiation core
+#define MODEXP_ADDR_NAME0 ADDR_NAME0
+#define MODEXP_ADDR_NAME1 ADDR_NAME1
+#define MODEXP_ADDR_VERSION ADDR_VERSION
+#define MODEXP_ADDR_CTRL ADDR_CTRL
#define MODEXP_CTRL_INIT_BIT 1
#define MODEXP_CTRL_NEXT_BIT 2
-#define MODEXP_ADDR_STATUS MODEXP_ADDR_BASE + ADDR_STATUS
+#define MODEXP_ADDR_STATUS ADDR_STATUS
-#define MODEXP_ADDR_DELAY MODEXP_ADDR_BASE + 0x13
+#define MODEXP_ADDR_DELAY 0x13
#define MODEXP_STATUS_READY 1
-#define MODEXP_MODULUS_LENGTH MODEXP_ADDR_BASE + 0x20
-#define MODEXP_EXPONENT_LENGTH MODEXP_ADDR_BASE + 0x21
-#define MODEXP_LENGTH MODEXP_ADDR_BASE + 0x22
+#define MODEXP_MODULUS_LENGTH 0x20
+#define MODEXP_EXPONENT_LENGTH 0x21
+#define MODEXP_LENGTH 0x22
-#define MODEXP_MODULUS_PTR_RST MODEXP_ADDR_BASE + 0x30
-#define MODEXP_MODULUS_DATA MODEXP_ADDR_BASE + 0x31
+#define MODEXP_MODULUS_PTR_RST 0x30
+#define MODEXP_MODULUS_DATA 0x31
-#define MODEXP_EXPONENT_PTR_RST MODEXP_ADDR_BASE + 0x40
-#define MODEXP_EXPONENT_DATA MODEXP_ADDR_BASE + 0x41
+#define MODEXP_EXPONENT_PTR_RST 0x40
+#define MODEXP_EXPONENT_DATA 0x41
-#define MODEXP_MESSAGE_PTR_RST MODEXP_ADDR_BASE + 0x50
-#define MODEXP_MESSAGE_DATA MODEXP_ADDR_BASE + 0x51
+#define MODEXP_MESSAGE_PTR_RST 0x50
+#define MODEXP_MESSAGE_DATA 0x51
-#define MODEXP_RESULT_PTR_RST MODEXP_ADDR_BASE + 0x60
-#define MODEXP_RESULT_DATA MODEXP_ADDR_BASE + 0x61
+#define MODEXP_RESULT_PTR_RST 0x60
+#define MODEXP_RESULT_DATA 0x61
#define MODEXP_NAME0 "mode"
#define MODEXP_NAME1 "xp "
@@ -425,6 +404,16 @@ in order to map it into a 16-bit address space.
//------------------------------------------------------------------
// Test case public functions
//------------------------------------------------------------------
+struct core_info {
+ char name[8];
+ char version[4];
+ off_t base;
+ struct core_info *next;
+};
+struct core_info *tc_core_first(char *name);
+struct core_info *tc_core_next(struct core_info *node, char *name);
+off_t tc_core_base(char *name);
+
void tc_set_debug(int onoff);
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);
diff --git a/sw/hash.c b/sw/hash.c
index 8b3bac2..d875225 100644
--- a/sw/hash.c
+++ b/sw/hash.c
@@ -64,23 +64,24 @@ int verbose = 0;
struct ctrl {
char *name;
+ off_t base_addr;
off_t block_addr;
int block_len;
off_t digest_addr;
int digest_len;
int mode;
} ctrl[] = {
- { "sha-1", SHA1_ADDR_BLOCK, SHA1_BLOCK_LEN,
+ { "sha-1", 0, SHA1_ADDR_BLOCK, SHA1_BLOCK_LEN,
SHA1_ADDR_DIGEST, SHA1_DIGEST_LEN, 0 },
- { "sha-256", SHA256_ADDR_BLOCK, SHA256_BLOCK_LEN,
+ { "sha-256", 0, SHA256_ADDR_BLOCK, SHA256_BLOCK_LEN,
SHA256_ADDR_DIGEST, SHA256_DIGEST_LEN, 0 },
- { "sha-512/224", SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
+ { "sha-512/224", 0, SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
SHA512_ADDR_DIGEST, SHA512_224_DIGEST_LEN, MODE_SHA_512_224 },
- { "sha-512/256", SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
+ { "sha-512/256", 0, SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
SHA512_ADDR_DIGEST, SHA512_256_DIGEST_LEN, MODE_SHA_512_256 },
- { "sha-384", SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
+ { "sha-384", 0, SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
SHA512_ADDR_DIGEST, SHA384_DIGEST_LEN, MODE_SHA_384 },
- { "sha-512", SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
+ { "sha-512", 0, SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
SHA512_ADDR_DIGEST, SHA512_DIGEST_LEN, MODE_SHA_512 },
{ NULL, 0, 0, 0 }
};
@@ -99,24 +100,63 @@ struct ctrl *find_algo(char *algo)
return NULL;
}
+/* ---------------- startup code ---------------- */
+
+static int patch(char *name, off_t base_addr) {
+ struct ctrl *ctrl;
+
+ ctrl = find_algo(name);
+ if (ctrl == NULL)
+ return -1;
+
+ ctrl->base_addr = base_addr;
+ return 0;
+}
+
+static int inited = 0;
+
+static int init(void)
+{
+ struct core_info *core;
+
+ if (inited)
+ return 0;
+
+ for (core = tc_core_first("sha"); core; core = tc_core_next(core, "sha")) {
+ if (strncmp(core->name, SHA1_NAME0 SHA1_NAME1, 8) == 0)
+ patch("sha-1", core->base);
+ else if (strncmp(core->name, SHA256_NAME0 SHA256_NAME1, 8) == 0)
+ patch("sha-256", core->base);
+ else if (strncmp(core->name, SHA512_NAME0 SHA512_NAME1, 8) == 0) {
+ patch("sha-512/224", core->base);
+ patch("sha-512/256", core->base);
+ patch("sha-384", core->base);
+ patch("sha-512", core->base);
+ }
+ }
+
+ inited = 1;
+ return 0;
+}
+
/* ---------------- hash ---------------- */
-static int transmit(off_t offset, uint8_t *block, int blen, int mode, int first)
+static int transmit(off_t base, uint8_t *block, int blen, int mode, int first)
{
- off_t base = offset & ~(0x1ff);
uint8_t ctrl_cmd[4] = { 0 };
+ int limit = 10;
- if (tc_write(offset, block, blen) != 0)
+ if (tc_write(base + ADDR_BLOCK, block, blen) != 0)
return 1;
ctrl_cmd[3] = (first ? CTRL_INIT : CTRL_NEXT) | mode;
return
tc_write(base + ADDR_CTRL, ctrl_cmd, 4) ||
- tc_wait_ready(base + ADDR_STATUS);
+ tc_wait(base + ADDR_STATUS, STATUS_READY, &limit);
}
-static int pad_transmit(off_t offset, uint8_t *block, uint8_t flen, uint8_t blen,
+static int pad_transmit(off_t base, uint8_t *block, uint8_t flen, uint8_t blen,
uint8_t mode, long long tlen, int first)
{
assert(flen < blen);
@@ -125,7 +165,7 @@ static int pad_transmit(off_t offset, uint8_t *block, uint8_t flen, uint8_t blen
memset(block + flen, 0, blen - flen);
if (blen - flen < ((blen == 64) ? 8 : 16)) {
- if (transmit(offset, block, blen, mode, first) != 0)
+ if (transmit(base, block, blen, mode, first) != 0)
return 1;
first = 0;
memset(block, 0, blen);
@@ -137,7 +177,7 @@ static int pad_transmit(off_t offset, uint8_t *block, uint8_t flen, uint8_t blen
((uint32_t *)block)[blen/4 - 2] = htonl((tlen >> 32) & 0xffff);
((uint32_t *)block)[blen/4 - 1] = htonl(tlen & 0xffff);
- return transmit(offset, block, blen, mode, first);
+ return transmit(base, block, blen, mode, first);
}
/* return number of digest bytes read */
@@ -146,18 +186,26 @@ static int hash(char *algo, char *file, uint8_t *digest)
uint8_t block[SHA512_BLOCK_LEN];
struct ctrl *ctrl;
int in_fd = 0; /* stdin */
- off_t baddr, daddr;
+ off_t base, daddr;
int blen, dlen, mode;
int nblk, nread, first;
int ret = -1;
struct timeval start, stop, difftime;
+ if (init() != 0)
+ return -1;
+
ctrl = find_algo(algo);
if (ctrl == NULL)
return -1;
- baddr = ctrl->block_addr;
+ base = ctrl->base_addr;
+ if (base == 0) {
+ fprintf(stderr, "core for algorithm \"%s\" not installed\n", algo);
+ return -1;
+ }
+
blen = ctrl->block_len;
- daddr = ctrl->digest_addr;
+ daddr = ctrl->base_addr + ctrl->digest_addr;
dlen = ctrl->digest_len;
mode = ctrl->mode;
@@ -185,14 +233,14 @@ static int hash(char *algo, char *file, uint8_t *digest)
}
else if (nread < blen) {
/* partial read = last block */
- if (pad_transmit(baddr, block, nread, blen, mode,
+ if (pad_transmit(base, block, nread, blen, mode,
(nblk * blen + nread) * 8, first) != 0)
goto out;
break;
}
else {
/* full block read */
- if (transmit(baddr, block, blen, mode, first) != 0)
+ if (transmit(base, block, blen, mode, first) != 0)
goto out;
}
}
diff --git a/sw/hash_tester.c b/sw/hash_tester.c
index 7e4f2c8..d3a2964 100644
--- a/sw/hash_tester.c
+++ b/sw/hash_tester.c
@@ -225,6 +225,27 @@ const uint8_t SHA512_DOUBLE_DIGEST[] =
0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 };
+
+/* ---------------- startup code ---------------- */
+
+static off_t board_addr_base = 0;
+static off_t sha1_addr_base, sha256_addr_base, sha512_addr_base;
+
+static int init(void)
+{
+ static int inited = 0;
+
+ if (inited)
+ return 0;
+
+ sha1_addr_base = tc_core_base("sha1");
+ sha256_addr_base = tc_core_base("sha2-256");
+ sha512_addr_base = tc_core_base("sha2-512");
+
+ inited = 1;
+ return 0;
+}
+
/* ---------------- sanity test case ---------------- */
int TC0()
@@ -234,6 +255,9 @@ int TC0()
uint8_t board_version[4] = NOVENA_BOARD_VERSION;
uint8_t t[4];
+ if (init() != 0)
+ return -1;
+
if (!quiet)
printf("TC0: Reading board type, version, and dummy reg from global registers.\n");
@@ -241,14 +265,14 @@ int TC0()
* to make sure that we can actually write something into EIM
*/
(void)time((time_t *)t);
- if (tc_write(BOARD_ADDR_DUMMY, t, 4) != 0)
+ if (tc_write(board_addr_base + BOARD_ADDR_DUMMY, t, 4) != 0)
return 1;
return
- tc_expected(BOARD_ADDR_NAME0, board_name0, 4) ||
- tc_expected(BOARD_ADDR_NAME1, board_name1, 4) ||
- tc_expected(BOARD_ADDR_VERSION, board_version, 4) ||
- tc_expected(BOARD_ADDR_DUMMY, t, 4);
+ tc_expected(board_addr_base + BOARD_ADDR_NAME0, board_name0, 4) ||
+ tc_expected(board_addr_base + BOARD_ADDR_NAME1, board_name1, 4) ||
+ tc_expected(board_addr_base + BOARD_ADDR_VERSION, board_version, 4) ||
+ tc_expected(board_addr_base + BOARD_ADDR_DUMMY, t, 4);
}
/* ---------------- SHA-1 test cases ---------------- */
@@ -260,13 +284,20 @@ int TC1(void)
uint8_t name1[4] = SHA1_NAME1;
uint8_t version[4] = SHA1_VERSION;
+ if (init() != 0)
+ return -1;
+ if ((sha1_addr_base == 0) && !quiet) {
+ printf("TC1: SHA-1 not present\n");
+ return 0;
+ }
+
if (!quiet)
printf("TC1: Reading name and version words from SHA-1 core.\n");
return
- tc_expected(SHA1_ADDR_NAME0, name0, 4) ||
- tc_expected(SHA1_ADDR_NAME1, name1, 4) ||
- tc_expected(SHA1_ADDR_VERSION, version, 4);
+ tc_expected(sha1_addr_base + SHA1_ADDR_NAME0, name0, 4) ||
+ tc_expected(sha1_addr_base + SHA1_ADDR_NAME1, name1, 4) ||
+ tc_expected(sha1_addr_base + SHA1_ADDR_VERSION, version, 4);
}
/* TC2: SHA-1 Single block message test as specified by NIST. */
@@ -276,16 +307,23 @@ int TC2(void)
const uint8_t *expected = SHA1_SINGLE_DIGEST;
int ret;
+ if (init() != 0)
+ return -1;
+ if ((sha1_addr_base == 0) && !quiet) {
+ printf("TC2: SHA-1 not present\n");
+ return 0;
+ }
+
if (!quiet)
printf("TC2: Single block message test for SHA-1.\n");
/* Write block to SHA-1. */
- tc_write(SHA1_ADDR_BLOCK, block, SHA1_BLOCK_LEN);
+ tc_write(sha1_addr_base + SHA1_ADDR_BLOCK, block, SHA1_BLOCK_LEN);
/* Start initial block hashing, wait and check status. */
- tc_init(SHA1_ADDR_CTRL);
- tc_wait_valid(SHA1_ADDR_STATUS);
+ tc_init(sha1_addr_base + SHA1_ADDR_CTRL);
+ tc_wait_valid(sha1_addr_base + SHA1_ADDR_STATUS);
/* Extract the digest. */
- ret = tc_expected(SHA1_ADDR_DIGEST, expected, SHA1_DIGEST_LEN);
+ ret = tc_expected(sha1_addr_base + SHA1_ADDR_DIGEST, expected, SHA1_DIGEST_LEN);
return ret;
}
@@ -300,23 +338,30 @@ int TC3(void)
const uint8_t *expected = SHA1_DOUBLE_DIGEST;
int ret;
+ if (init() != 0)
+ return -1;
+ if ((sha1_addr_base == 0) && !quiet) {
+ printf("TC3: SHA-1 not present\n");
+ return 0;
+ }
+
if (!quiet)
printf("TC3: Double block message test for SHA-1.\n");
/* Write first block to SHA-1. */
- tc_write(SHA1_ADDR_BLOCK, block[0], SHA1_BLOCK_LEN);
+ tc_write(sha1_addr_base + SHA1_ADDR_BLOCK, block[0], SHA1_BLOCK_LEN);
/* Start initial block hashing, wait and check status. */
- tc_init(SHA1_ADDR_CTRL);
- tc_wait_valid(SHA1_ADDR_STATUS);
+ tc_init(sha1_addr_base + SHA1_ADDR_CTRL);
+ tc_wait_valid(sha1_addr_base + SHA1_ADDR_STATUS);
/* Extract the first digest. */
- tc_expected(SHA1_ADDR_DIGEST, block0_expected, SHA1_DIGEST_LEN);
+ tc_expected(sha1_addr_base + SHA1_ADDR_DIGEST, block0_expected, SHA1_DIGEST_LEN);
/* Write second block to SHA-1. */
- tc_write(SHA1_ADDR_BLOCK, block[1], SHA1_BLOCK_LEN);
+ tc_write(sha1_addr_base + SHA1_ADDR_BLOCK, block[1], SHA1_BLOCK_LEN);
/* Start next block hashing, wait and check status. */
- tc_next(SHA1_ADDR_CTRL);
- tc_wait_valid(SHA1_ADDR_STATUS);
+ tc_next(sha1_addr_base + SHA1_ADDR_CTRL);
+ tc_wait_valid(sha1_addr_base + SHA1_ADDR_STATUS);
/* Extract the second digest. */
- ret = tc_expected(SHA1_ADDR_DIGEST, expected, SHA1_DIGEST_LEN);
+ ret = tc_expected(sha1_addr_base + SHA1_ADDR_DIGEST, expected, SHA1_DIGEST_LEN);
return ret;
}
@@ -329,13 +374,20 @@ int TC4(void)
uint8_t name1[4] = SHA256_NAME1;
uint8_t version[4] = SHA256_VERSION;
+ if (init() != 0)
+ return -1;
+ if ((sha256_addr_base == 0) && !quiet) {
+ printf("TC4: SHA-256 not present\n");
+ return 0;
+ }
+
if (!quiet)
printf("TC4: Reading name and version words from SHA-256 core.\n");
return
- tc_expected(SHA256_ADDR_NAME0, name0, 4) ||
- tc_expected(SHA256_ADDR_NAME1, name1, 4) ||
- tc_expected(SHA256_ADDR_VERSION, version, 4);
+ tc_expected(sha256_addr_base + SHA256_ADDR_NAME0, name0, 4) ||
+ tc_expected(sha256_addr_base + SHA256_ADDR_NAME1, name1, 4) ||
+ tc_expected(sha256_addr_base + SHA256_ADDR_VERSION, version, 4);
}
/* TC5: SHA-256 Single block message test as specified by NIST. */
@@ -344,17 +396,24 @@ int TC5()
const uint8_t *block = NIST_512_SINGLE;
const uint8_t *expected = SHA256_SINGLE_DIGEST;
+ if (init() != 0)
+ return -1;
+ if ((sha256_addr_base == 0) && !quiet) {
+ printf("TC5: SHA-256 not present\n");
+ return 0;
+ }
+
if (!quiet)
printf("TC5: Single block message test for SHA-256.\n");
return
/* Write block to SHA-256. */
- tc_write(SHA256_ADDR_BLOCK, block, SHA256_BLOCK_LEN) ||
+ tc_write(sha256_addr_base + SHA256_ADDR_BLOCK, block, SHA256_BLOCK_LEN) ||
/* Start initial block hashing, wait and check status. */
- tc_init(SHA256_ADDR_CTRL) ||
- tc_wait_valid(SHA256_ADDR_STATUS) ||
+ tc_init(sha256_addr_base + SHA256_ADDR_CTRL) ||
+ tc_wait_valid(sha256_addr_base + SHA256_ADDR_STATUS) ||
/* Extract the digest. */
- tc_expected(SHA256_ADDR_DIGEST, expected, SHA256_DIGEST_LEN);
+ tc_expected(sha256_addr_base + SHA256_ADDR_DIGEST, expected, SHA256_DIGEST_LEN);
}
/* TC6: SHA-256 Double block message test as specified by NIST. */
@@ -368,24 +427,31 @@ int TC6()
0xCC, 0x4B, 0x32, 0xC1, 0xF2, 0x0E, 0x53, 0x3A };
const uint8_t *expected = SHA256_DOUBLE_DIGEST;
+ if (init() != 0)
+ return -1;
+ if ((sha256_addr_base == 0) && !quiet) {
+ printf("TC6: SHA-256 not present\n");
+ return 0;
+ }
+
if (!quiet)
printf("TC6: Double block message test for SHA-256.\n");
return
/* Write first block to SHA-256. */
- tc_write(SHA256_ADDR_BLOCK, block[0], SHA256_BLOCK_LEN) ||
+ tc_write(sha256_addr_base + SHA256_ADDR_BLOCK, block[0], SHA256_BLOCK_LEN) ||
/* Start initial block hashing, wait and check status. */
- tc_init(SHA256_ADDR_CTRL) ||
- tc_wait_valid(SHA256_ADDR_STATUS) ||
+ tc_init(sha256_addr_base + SHA256_ADDR_CTRL) ||
+ tc_wait_valid(sha256_addr_base + SHA256_ADDR_STATUS) ||
/* Extract the first digest. */
- tc_expected(SHA256_ADDR_DIGEST, block0_expected, SHA256_DIGEST_LEN) ||
+ tc_expected(sha256_addr_base + SHA256_ADDR_DIGEST, block0_expected, SHA256_DIGEST_LEN) ||
/* Write second block to SHA-256. */
- tc_write(SHA256_ADDR_BLOCK, block[1], SHA256_BLOCK_LEN) ||
+ tc_write(sha256_addr_base + SHA256_ADDR_BLOCK, block[1], SHA256_BLOCK_LEN) ||
/* Start next block hashing, wait and check status. */
- tc_next(SHA256_ADDR_CTRL) ||
- tc_wait_valid(SHA256_ADDR_STATUS) ||
+ tc_next(sha256_addr_base + SHA256_ADDR_CTRL) ||
+ tc_wait_valid(sha256_addr_base + SHA256_ADDR_STATUS) ||
/* Extract the second digest. */
- tc_expected(SHA256_ADDR_DIGEST, expected, SHA256_DIGEST_LEN);
+ tc_expected(sha256_addr_base + SHA256_ADDR_DIGEST, expected, SHA256_DIGEST_LEN);
}
/* TC7: SHA-256 Huge message test. */
@@ -410,31 +476,38 @@ int TC7()
int i, n = 1000;
+ if (init() != 0)
+ return -1;
+ if ((sha256_addr_base == 0) && !quiet) {
+ printf("TC7: SHA-256 not present\n");
+ return 0;
+ }
+
if (!quiet)
printf("TC7: Message with %d blocks test for SHA-256.\n", n);
/* Write block data to SHA-256. */
- if (tc_write(SHA256_ADDR_BLOCK, block, SHA256_BLOCK_LEN))
+ if (tc_write(sha256_addr_base + SHA256_ADDR_BLOCK, block, SHA256_BLOCK_LEN))
return 1;
/* Start initial block hashing, wait and check status. */
- if (tc_init(SHA256_ADDR_CTRL) ||
- tc_wait_ready(SHA256_ADDR_STATUS))
+ if (tc_init(sha256_addr_base + SHA256_ADDR_CTRL) ||
+ tc_wait_ready(sha256_addr_base + SHA256_ADDR_STATUS))
return 1;
/* First block done. Do the rest. */
for (i = 1; i < n; ++i) {
/* Start next block hashing, wait and check status. */
- if (tc_next(SHA256_ADDR_CTRL) ||
- tc_wait_ready(SHA256_ADDR_STATUS))
+ if (tc_next(sha256_addr_base + SHA256_ADDR_CTRL) ||
+ tc_wait_ready(sha256_addr_base + SHA256_ADDR_STATUS))
return 1;
}
/* XXX valid is probably set at the same time as ready */
- if (tc_wait_valid(SHA256_ADDR_STATUS))
+ if (tc_wait_valid(sha256_addr_base + SHA256_ADDR_STATUS))
return 1;
/* Extract the final digest. */
- return tc_expected(SHA256_ADDR_DIGEST, expected, SHA256_DIGEST_LEN);
+ return tc_expected(sha256_addr_base + SHA256_ADDR_DIGEST, expected, SHA256_DIGEST_LEN);
}
/* ---------------- SHA-512 test cases ---------------- */
@@ -446,13 +519,20 @@ int TC8()
uint8_t name1[4] = SHA512_NAME1;
uint8_t version[4] = SHA512_VERSION;
+ if (init() != 0)
+ return -1;
+ if ((sha512_addr_base == 0) && !quiet) {
+ printf("TC8: SHA-512 not present\n");
+ return 0;
+ }
+
if (!quiet)
printf("TC8: Reading name and version words from SHA-512 core.\n");
return
- tc_expected(SHA512_ADDR_NAME0, name0, 4) ||
- tc_expected(SHA512_ADDR_NAME1, name1, 4) ||
- tc_expected(SHA512_ADDR_VERSION, version, 4);
+ tc_expected(sha512_addr_base + SHA512_ADDR_NAME0, name0, 4) ||
+ tc_expected(sha512_addr_base + SHA512_ADDR_NAME1, name1, 4) ||
+ tc_expected(sha512_addr_base + SHA512_ADDR_VERSION, version, 4);
}
/* TC9: SHA-512 Single block message test as specified by NIST.
@@ -464,16 +544,23 @@ int tc9(int mode, const uint8_t *expected, int digest_len)
return
/* Write block to SHA-512. */
- tc_write(SHA512_ADDR_BLOCK, block, SHA512_BLOCK_LEN) ||
+ tc_write(sha512_addr_base + SHA512_ADDR_BLOCK, block, SHA512_BLOCK_LEN) ||
/* Start initial block hashing, wait and check status. */
- tc_write(SHA512_ADDR_CTRL, init, 4) ||
- tc_wait_valid(SHA512_ADDR_STATUS) ||
+ tc_write(sha512_addr_base + SHA512_ADDR_CTRL, init, 4) ||
+ tc_wait_valid(sha512_addr_base + SHA512_ADDR_STATUS) ||
/* Extract the digest. */
- tc_expected(SHA512_ADDR_DIGEST, expected, digest_len);
+ tc_expected(sha512_addr_base + SHA512_ADDR_DIGEST, expected, digest_len);
}
int TC9()
{
+ if (init() != 0)
+ return -1;
+ if ((sha512_addr_base == 0) && !quiet) {
+ printf("TC9: SHA-512 not present\n");
+ return 0;
+ }
+
if (!quiet)
printf("TC9-1: Single block message test for SHA-512/224.\n");
if (tc9(MODE_SHA_512_224, SHA512_224_SINGLE_DIGEST, SHA512_224_DIGEST_LEN) != 0)
@@ -507,21 +594,28 @@ int tc10(int mode, const uint8_t *expected, int digest_len)
return
/* Write first block to SHA-512. */
- tc_write(SHA512_ADDR_BLOCK, block[0], SHA512_BLOCK_LEN) ||
+ tc_write(sha512_addr_base + SHA512_ADDR_BLOCK, block[0], SHA512_BLOCK_LEN) ||
/* Start initial block hashing, wait and check status. */
- tc_write(SHA512_ADDR_CTRL, init, 4) ||
- tc_wait_ready(SHA512_ADDR_STATUS) ||
+ tc_write(sha512_addr_base + SHA512_ADDR_CTRL, init, 4) ||
+ tc_wait_ready(sha512_addr_base + SHA512_ADDR_STATUS) ||
/* Write second block to SHA-512. */
- tc_write(SHA512_ADDR_BLOCK, block[1], SHA512_BLOCK_LEN) ||
+ tc_write(sha512_addr_base + SHA512_ADDR_BLOCK, block[1], SHA512_BLOCK_LEN) ||
/* Start next block hashing, wait and check status. */
- tc_write(SHA512_ADDR_CTRL, next, 4) ||
- tc_wait_valid(SHA512_ADDR_STATUS) ||
+ tc_write(sha512_addr_base + SHA512_ADDR_CTRL, next, 4) ||
+ tc_wait_valid(sha512_addr_base + SHA512_ADDR_STATUS) ||
/* Extract the digest. */
- tc_expected(SHA512_ADDR_DIGEST, expected, digest_len);
+ tc_expected(sha512_addr_base + SHA512_ADDR_DIGEST, expected, digest_len);
}
int TC10()
{
+ if (init() != 0)
+ return -1;
+ if ((sha512_addr_base == 0) && !quiet) {
+ printf("TC10: SHA-512 not present\n");
+ return 0;
+ }
+
if (!quiet)
printf("TC10-1: Double block message test for SHA-512/224.\n");
if (tc10(MODE_SHA_512_224, SHA512_224_DOUBLE_DIGEST, SHA512_224_DIGEST_LEN) != 0)
diff --git a/sw/modexp_tester.c b/sw/modexp_tester.c
index 2288ad5..021c0a9 100644
--- a/sw/modexp_tester.c
+++ b/sw/modexp_tester.c
@@ -99,19 +99,16 @@ static uint32_t tc_r32(const off_t addr)
// Check that we can read from the modexp core by trying to
// read out the name and version.
//------------------------------------------------------------------
+static off_t modexp_addr_base;
+
static void check_modexp_access(void)
{
- uint8_t name0[4], name1[4], version[4];
-
- printf("Trying to read the modexp core name\n");
-
- check(tc_read(MODEXP_ADDR_NAME0, name0, sizeof(name0)));
- check(tc_read(MODEXP_ADDR_NAME1, name1, sizeof(name1)));
- check(tc_read(MODEXP_ADDR_VERSION, version, sizeof(version)));
- printf("%4.4s%4.4s %4.4s\n\n", name0, name1, version);
+ modexp_addr_base = tc_core_base("modexp");
+ assert(modexp_addr_base != 0);
}
+#if 0
//------------------------------------------------------------------
// check_modulus_mem()
//
@@ -124,22 +121,22 @@ static void check_modulus_mem(void)
printf("Testing modulus mem access.\n");
- tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_MODULUS_PTR_RST, 0x00000000);
// Write test data to modulus mempory.
for (i = 0 ; i < 64; i = i + 1) {
j = ((i * 4 + 3) << 24) + ((i * 4 + 2) << 16) +
((i * 4 + 1) << 8) + i * 4;
- tc_w32(MODEXP_MODULUS_DATA, j);
+ tc_w32(modexp_addr_base + MODEXP_MODULUS_DATA, j);
}
- tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_MODULUS_PTR_RST, 0x00000000);
// Read out test data from modulus mempory.
for (i = 0 ; i < 64 ; i = i + 4) {
printf("modulus mem: 0x%08x 0x%08x 0x%08x 0x%08x\n",
- tc_r32(MODEXP_MODULUS_DATA),
- tc_r32(MODEXP_MODULUS_DATA),
- tc_r32(MODEXP_MODULUS_DATA),
- tc_r32(MODEXP_MODULUS_DATA));
+ tc_r32(modexp_addr_base + MODEXP_MODULUS_DATA),
+ tc_r32(modexp_addr_base + MODEXP_MODULUS_DATA),
+ tc_r32(modexp_addr_base + MODEXP_MODULUS_DATA),
+ tc_r32(modexp_addr_base + MODEXP_MODULUS_DATA));
}
}
@@ -156,22 +153,22 @@ static void check_exponent_mem(void)
printf("Testing exponent mem access.\n");
- tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_EXPONENT_PTR_RST, 0x00000000);
// Write test data to exponent memory.
for (i = 0 ; i < 64; i = i + 1) {
j = ((i * 4 + 3) << 24) + ((i * 4 + 2) << 16) +
((i * 4 + 1) << 8) + i * 4;
- tc_w32(MODEXP_EXPONENT_DATA, j);
+ tc_w32(modexp_addr_base + MODEXP_EXPONENT_DATA, j);
}
- tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_EXPONENT_PTR_RST, 0x00000000);
// Read out test data from exponent memory.
for (i = 0 ; i < 64 ; i = i + 4) {
printf("exponent mem: 0x%08x 0x%08x 0x%08x 0x%08x\n",
- tc_r32(MODEXP_EXPONENT_DATA),
- tc_r32(MODEXP_EXPONENT_DATA),
- tc_r32(MODEXP_EXPONENT_DATA),
- tc_r32(MODEXP_EXPONENT_DATA));
+ tc_r32(modexp_addr_base + MODEXP_EXPONENT_DATA),
+ tc_r32(modexp_addr_base + MODEXP_EXPONENT_DATA),
+ tc_r32(modexp_addr_base + MODEXP_EXPONENT_DATA),
+ tc_r32(modexp_addr_base + MODEXP_EXPONENT_DATA));
}
}
@@ -189,22 +186,22 @@ static void check_message_mem(void)
printf("Testing message mem access.\n");
- tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_MESSAGE_PTR_RST, 0x00000000);
// Write test data to message memory.
for (i = 0 ; i < 64; i = i + 1) {
j = ((i * 4 + 3) << 24) + ((i * 4 + 2) << 16) +
((i * 4 + 1) << 8) + i * 4;
- tc_w32(MODEXP_MESSAGE_DATA, j);
+ tc_w32(modexp_addr_base + MODEXP_MESSAGE_DATA, j);
}
- tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_MESSAGE_PTR_RST, 0x00000000);
// Read out test data from messsage memory.
for (i = 0 ; i < 64 ; i = i + 4) {
printf("message mem: 0x%08x 0x%08x 0x%08x 0x%08x\n",
- tc_r32(MODEXP_MESSAGE_DATA),
- tc_r32(MODEXP_MESSAGE_DATA),
- tc_r32(MODEXP_MESSAGE_DATA),
- tc_r32(MODEXP_MESSAGE_DATA));
+ tc_r32(modexp_addr_base + MODEXP_MESSAGE_DATA),
+ tc_r32(modexp_addr_base + MODEXP_MESSAGE_DATA),
+ tc_r32(modexp_addr_base + MODEXP_MESSAGE_DATA),
+ tc_r32(modexp_addr_base + MODEXP_MESSAGE_DATA));
}
}
@@ -217,19 +214,19 @@ static void check_message_mem(void)
static void clear_mems()
{
uint32_t i;
- tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000);
- tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000);
- tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_MESSAGE_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_EXPONENT_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_MODULUS_PTR_RST, 0x00000000);
for (i = 0 ; i < 256 ; i++) {
- tc_w32(MODEXP_MESSAGE_DATA, 0x00000000);
- tc_w32(MODEXP_EXPONENT_DATA, 0x00000000);
- tc_w32(MODEXP_MODULUS_DATA, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_MESSAGE_DATA, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_EXPONENT_DATA, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_MODULUS_DATA, 0x00000000);
}
- tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000);
- tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000);
- tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_MESSAGE_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_EXPONENT_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_MODULUS_PTR_RST, 0x00000000);
}
@@ -240,35 +237,36 @@ static void clear_mems()
//------------------------------------------------------------------
static void dump_mems()
{
- tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_MESSAGE_PTR_RST, 0x00000000);
printf("First words in messagee mem:\n");
printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
- tc_r32(MODEXP_MESSAGE_DATA), tc_r32(MODEXP_MESSAGE_DATA),
- tc_r32(MODEXP_MESSAGE_DATA), tc_r32(MODEXP_MESSAGE_DATA));
+ tc_r32(modexp_addr_base + MODEXP_MESSAGE_DATA), tc_r32(modexp_addr_base + MODEXP_MESSAGE_DATA),
+ tc_r32(modexp_addr_base + MODEXP_MESSAGE_DATA), tc_r32(modexp_addr_base + MODEXP_MESSAGE_DATA));
- tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_EXPONENT_PTR_RST, 0x00000000);
printf("First words in exponent mem:\n");
printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
- tc_r32(MODEXP_EXPONENT_DATA), tc_r32(MODEXP_EXPONENT_DATA),
- tc_r32(MODEXP_EXPONENT_DATA), tc_r32(MODEXP_EXPONENT_DATA));
+ tc_r32(modexp_addr_base + MODEXP_EXPONENT_DATA), tc_r32(modexp_addr_base + MODEXP_EXPONENT_DATA),
+ tc_r32(modexp_addr_base + MODEXP_EXPONENT_DATA), tc_r32(modexp_addr_base + MODEXP_EXPONENT_DATA));
- tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_MODULUS_PTR_RST, 0x00000000);
printf("First words in modulus mem:\n");
printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
- tc_r32(MODEXP_MODULUS_DATA), tc_r32(MODEXP_MODULUS_DATA),
- tc_r32(MODEXP_MODULUS_DATA), tc_r32(MODEXP_MODULUS_DATA));
+ tc_r32(modexp_addr_base + MODEXP_MODULUS_DATA), tc_r32(modexp_addr_base + MODEXP_MODULUS_DATA),
+ tc_r32(modexp_addr_base + MODEXP_MODULUS_DATA), tc_r32(modexp_addr_base + MODEXP_MODULUS_DATA));
- tc_w32(MODEXP_RESULT_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_RESULT_PTR_RST, 0x00000000);
printf("First words in result mem:\n");
printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
- tc_r32(MODEXP_RESULT_DATA), tc_r32(MODEXP_RESULT_DATA),
- tc_r32(MODEXP_RESULT_DATA), tc_r32(MODEXP_RESULT_DATA));
+ tc_r32(modexp_addr_base + MODEXP_RESULT_DATA), tc_r32(modexp_addr_base + MODEXP_RESULT_DATA),
+ tc_r32(modexp_addr_base + MODEXP_RESULT_DATA), tc_r32(modexp_addr_base + MODEXP_RESULT_DATA));
- tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000);
- tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000);
- tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000);
- tc_w32(MODEXP_RESULT_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_MESSAGE_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_EXPONENT_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_MODULUS_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_RESULT_PTR_RST, 0x00000000);
}
+#endif /* #if 0 */
//------------------------------------------------------------------
@@ -282,28 +280,28 @@ uint8_t testrunner(uint32_t exp_len, uint32_t *exponent,
uint32_t result;
uint8_t correct;
- tc_w32(MODEXP_EXPONENT_LENGTH, exp_len);
- tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_EXPONENT_LENGTH, exp_len);
+ tc_w32(modexp_addr_base + MODEXP_EXPONENT_PTR_RST, 0x00000000);
for (i = 0 ; i < mod_len ; i++) {
- tc_w32(MODEXP_EXPONENT_DATA, exponent[i]);
+ tc_w32(modexp_addr_base + MODEXP_EXPONENT_DATA, exponent[i]);
}
- tc_w32(MODEXP_MODULUS_LENGTH, mod_len);
- tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000);
- tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_MODULUS_LENGTH, mod_len);
+ tc_w32(modexp_addr_base + MODEXP_MESSAGE_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_MODULUS_PTR_RST, 0x00000000);
for (i = 0 ; i < mod_len ; i++) {
- tc_w32(MODEXP_MESSAGE_DATA, message[i]);
- tc_w32(MODEXP_MODULUS_DATA, modulus[i]);
+ tc_w32(modexp_addr_base + MODEXP_MESSAGE_DATA, message[i]);
+ tc_w32(modexp_addr_base + MODEXP_MODULUS_DATA, modulus[i]);
}
- tc_w32(MODEXP_ADDR_CTRL, 0x00000001);
- check(tc_wait_ready(MODEXP_ADDR_STATUS));
+ tc_w32(modexp_addr_base + MODEXP_ADDR_CTRL, 0x00000001);
+ check(tc_wait_ready(modexp_addr_base + MODEXP_ADDR_STATUS));
correct = 1;
- tc_w32(MODEXP_RESULT_PTR_RST, 0x00000000);
+ tc_w32(modexp_addr_base + MODEXP_RESULT_PTR_RST, 0x00000000);
for (i = 0 ; i < mod_len ; i++) {
- result = tc_r32(MODEXP_RESULT_DATA);
+ result = tc_r32(modexp_addr_base + MODEXP_RESULT_DATA);
if (result != expected[i]) {
printf("Error. Expected 0x%08x, got 0x%08x\n", expected[i], result);
correct = 0;
@@ -514,7 +512,7 @@ static void tc7()
//------------------------------------------------------------------
// tc8()
//
-// Testcase with 1024 bit operands.
+// Testcase with 2048 bit operands.
//------------------------------------------------------------------
static void tc8()
{
@@ -591,7 +589,7 @@ static void tc8()
0xd5535329 };
uint8_t result;
- printf("Running TC8: 1024 bit operands...\n");
+ printf("Running TC8: 2048 bit operands.s\n");
result = testrunner(65, exponent, 65, modulus, message, expected);
@@ -602,112 +600,94 @@ static void tc8()
}
-void rob_dec_1024(void)
-{
- uint32_t exponent[] = {0x00000000, 0x3ff26c9e, 0x32685b93, 0x66570228, 0xf0603c4e,
- 0x04a717c1, 0x8038b116, 0xeb48325e, 0xcada992a,
- 0x920bb241, 0x5aee4afe, 0xe2a37e87, 0xb35b9519,
- 0xb335775d, 0x989553e9, 0x1326f46e, 0x2cdf6b7b,
- 0x84aabfa9, 0xef24c600, 0xb56872ad, 0x5edb9041,
- 0xe8ecd7f8, 0x535133fb, 0xdefc92c7, 0x42384226,
- 0x7d40e5f5, 0xc91bd745, 0x9578e460, 0xfc858374,
- 0x3172bed3, 0x73b6957c, 0xc0d6a68e, 0x33156a61};
-
-
- uint32_t modulus[] = {0x00000000, 0xd075ec0a, 0x95048ef8, 0xcaa69073, 0x8d9d58e9,
- 0x1764b437, 0x50b58cad, 0x8a6e3199, 0x135f80ee,
- 0x84eb2bde, 0x58d38ee3, 0x5825e91e, 0xafdeb1ba,
- 0xa15a160b, 0x0057c47c, 0xc7765e31, 0x868a3e15,
- 0x5ee57cef, 0xb008c4dd, 0x6a0a89ee, 0x98a4ee9c,
- 0x971a07de, 0x61e5b0d3, 0xcf70e1cd, 0xc6a0de5b,
- 0x451f2fb9, 0xdb995196, 0x9f2f884b, 0x4b09749a,
- 0xe6c4ddbe, 0x7ee61f79, 0x265c6adf, 0xb16b3015};
-
-
- uint32_t message[] = {0x00000000, 0x0001ffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0x00303130,
- 0x0d060960, 0x86480165, 0x03040201, 0x05000420,
- 0x8e36fc9a, 0xa31724c3, 0x2416263c, 0x0366a175,
- 0xfabbb92b, 0x741ca649, 0x6107074d, 0x0343b597};
-
-
- uint32_t expected[] = {0x00000000, 0x06339a64, 0x367db02a, 0xf41158cc, 0x95e76049,
- 0x4519c165, 0x111184be, 0xe41d8ee2, 0x2ae5f5d1,
- 0x1da7f962, 0xac93ac88, 0x915eee13, 0xa3350c22,
- 0xf0dfa62e, 0xfdfc2b62, 0x29f26e27, 0xbebdc84e,
- 0x4746df79, 0x7b387ad2, 0x13423c9f, 0x98e8a146,
- 0xff486b6c, 0x1a85414e, 0x73117121, 0xb700e547,
- 0xab4e07b2, 0x21b988b8, 0x24dd77c2, 0x046b0a20,
- 0xcddb986a, 0xac75c2f2, 0xb044ed59, 0xea565879};
-
- uint8_t result;
-
- printf("=== Running 1024 bit decipher/sign test from Robs RSA code. ===\n");
-
- result = testrunner(33, exponent, 33, modulus, message, expected);
-
- if (result)
- printf("Rob 1024 dec/sign test OK\n");
- else
- printf("Rob 1024 dec/sign test NOT OK\n");
-
-}
-
-
-void rob_enc_1024(void)
+//------------------------------------------------------------------
+// tc9()
+//
+// Testcase with 2048 bit operands.
+//------------------------------------------------------------------
+static void tc9()
{
- uint32_t exponent[] = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00010001};
-
-
- uint32_t modulus[] = {0x00000000, 0xd075ec0a, 0x95048ef8, 0xcaa69073, 0x8d9d58e9,
- 0x1764b437, 0x50b58cad, 0x8a6e3199, 0x135f80ee,
- 0x84eb2bde, 0x58d38ee3, 0x5825e91e, 0xafdeb1ba,
- 0xa15a160b, 0x0057c47c, 0xc7765e31, 0x868a3e15,
- 0x5ee57cef, 0xb008c4dd, 0x6a0a89ee, 0x98a4ee9c,
- 0x971a07de, 0x61e5b0d3, 0xcf70e1cd, 0xc6a0de5b,
- 0x451f2fb9, 0xdb995196, 0x9f2f884b, 0x4b09749a,
- 0xe6c4ddbe, 0x7ee61f79, 0x265c6adf, 0xb16b3015};
-
-
- uint32_t message[] = {0x00000000, 0x0001ffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0x00303130,
- 0x0d060960, 0x86480165, 0x03040201, 0x05000420,
- 0x8e36fc9a, 0xa31724c3, 0x2416263c, 0x0366a175,
- 0xfabbb92b, 0x741ca649, 0x6107074d, 0x0343b597};
-
-
- uint32_t expected[] = {0x00000000, 0x06339a64, 0x367db02a, 0xf41158cc, 0x95e76049,
- 0x4519c165, 0x111184be, 0xe41d8ee2, 0x2ae5f5d1,
- 0x1da7f962, 0xac93ac88, 0x915eee13, 0xa3350c22,
- 0xf0dfa62e, 0xfdfc2b62, 0x29f26e27, 0xbebdc84e,
- 0x4746df79, 0x7b387ad2, 0x13423c9f, 0x98e8a146,
- 0xff486b6c, 0x1a85414e, 0x73117121, 0xb700e547,
- 0xab4e07b2, 0x21b988b8, 0x24dd77c2, 0x046b0a20,
- 0xcddb986a, 0xac75c2f2, 0xb044ed59, 0xea565879};
+ uint32_t message[] = {0x21558179, 0x3e2914b1, 0xefe95957, 0x965fdead,
+ 0xe766d8fc, 0x136eadf4, 0xa6106a2a, 0x88b2df7e,
+ 0xe0b0eaae, 0x2c17946a, 0x6f5b5563, 0x228052ae,
+ 0x7fc40d80, 0xf81354db, 0xfceecd1a, 0xa5e4c97d,
+ 0x433ecfcd, 0xc20d1e4d, 0x2a748fe3, 0x1d9e63f0,
+ 0xdc6c25d6, 0xdae5c8be, 0x1d8c5431, 0xb1d7d270,
+ 0xed5b2566, 0x1463b0fd, 0xa9e26cf7, 0x3dd6fbd7,
+ 0x1347c8f7, 0x76c2cc37, 0xf382b786, 0x1d5ac517,
+ 0x26b96692, 0x2c1fe6f8, 0x5852dbf8, 0x4bcabda2,
+ 0xbedb2f5f, 0xbfe58158, 0x8cd5d15f, 0xac7c7f4c,
+ 0xf8ba47d2, 0x86c6571d, 0x06a4760b, 0xa6afa0e1,
+ 0x7a819f62, 0x5cdbfe15, 0x9b2d10b5, 0xf508b1fd,
+ 0xb3f0462a, 0x92f45a64, 0x69b6ec58, 0xbfad8fab,
+ 0x6799260f, 0x27415db5, 0xf6ac7832, 0xe547826d,
+ 0x6a9806a5, 0x36c62a88, 0x98bee14d, 0x9b8c2648,
+ 0xabdbbd3d, 0xaf59eea1, 0x164eacb5, 0x3a18e427};
+
+
+ uint32_t exponent[] = {0x2519837b, 0xe73a9031, 0xe241606d, 0x21e70fa2,
+ 0x7881f254, 0x4e60831d, 0x266f408e, 0x4a83e6ed,
+ 0xa7741995, 0x32b477ba, 0x91bdf5d0, 0x4acd7a06,
+ 0x51e344b9, 0xdf376e4e, 0x8494e625, 0xa0cc9697,
+ 0x817a0c93, 0x3b68cefb, 0x46de14c1, 0x52229965,
+ 0x329645bd, 0xf4176adc, 0x29a8bc50, 0x44900fec,
+ 0x1558d492, 0xf838a8e7, 0xea207abd, 0xcd21a28c,
+ 0x91e6b02f, 0x2a490ea8, 0x5d99663b, 0x87c92fb6,
+ 0x0a185325, 0x5256a7a3, 0x496b7288, 0x6688b6c8,
+ 0x650e1776, 0x54cd429f, 0x90ea3b18, 0x0b72ae61,
+ 0xcc8651b3, 0xa488742d, 0x93c401ef, 0x5a2220ff,
+ 0xaee1f257, 0xf9d1e29a, 0xd47151fe, 0x4978342b,
+ 0x0927048a, 0x404b0689, 0xdc9df8cc, 0xfba9845f,
+ 0xeb8a39b0, 0xd3f24ae2, 0x5ea9ca0a, 0x0c064f94,
+ 0x35368ae2, 0xeab6c035, 0x9baa39c6, 0x2ef6259d,
+ 0xa2577555, 0x514c7d98, 0x0890d44f, 0xf416fbdd};
+
+
+ uint32_t modulus[] = {0x2c5337a9, 0x3f2e1ca6, 0x91de65ea, 0xc3f9a3c2,
+ 0xdc9099e0, 0x64ebe412, 0xf4583fae, 0x1fc8e8dd,
+ 0x92dcbbfb, 0x9159239e, 0xdbbec456, 0x8735a660,
+ 0x8248dbbc, 0x76f01415, 0x3cb8a897, 0x7cc09280,
+ 0x6cc6db51, 0x9c2544da, 0x316564ce, 0x4b6d9b3b,
+ 0x3e0e123f, 0x942a4a3c, 0x1f128873, 0x5ad14862,
+ 0xdde8e6dd, 0x73da31fb, 0x1a8a2046, 0xc3ff18c6,
+ 0x24e31d54, 0x7d8a1796, 0x88ab346c, 0x262bb321,
+ 0x2cada5dc, 0x1fb2284c, 0x042375fd, 0xba10d309,
+ 0xcda978ec, 0x229ee156, 0x8470728a, 0xa58017fd,
+ 0x65727801, 0x1ea396a6, 0xbd9a4bc1, 0x8e97c08f,
+ 0xd7529796, 0x2c8339e9, 0xc5340a83, 0x6f7d1f9c,
+ 0xd6014fec, 0xdffa2265, 0xfa9906a9, 0xafbd424a,
+ 0x631994ae, 0x73a9b3f1, 0x2284f999, 0x6f8c87f6,
+ 0x93136a66, 0x47c81e45, 0xd35f0e41, 0x238d6960,
+ 0x96cf337d, 0x8865e4cc, 0x15039c40, 0x65ee7211};
+
+
+ uint32_t expected[] = {0x24665860, 0x4b150493, 0xc0834602, 0xc0b99ab5,
+ 0xbe649545, 0xa7d8b1ca, 0x55c1b98a, 0x1dce374b,
+ 0x65750415, 0x573dfed7, 0x95df9943, 0x58a4aea0,
+ 0x5fb40a92, 0x1408d9c2, 0xb5e23fc9, 0x225eb60b,
+ 0x41d33a41, 0xbf958f7f, 0x619f5ac1, 0x207647f3,
+ 0x223e56f8, 0x26afd4ae, 0x6a297840, 0x830947db,
+ 0xbc5af940, 0x4c97ebb1, 0xca38b220, 0x04c9a26d,
+ 0x49a16b72, 0x0882c658, 0x2dbc50e0, 0x67e2d057,
+ 0x4b8ef356, 0x4ba5eac3, 0x17237d9f, 0x27c111a8,
+ 0xc1b1944e, 0xe91fd6b6, 0xa78d9747, 0x61e946d3,
+ 0x0078fe23, 0x7770a088, 0x6d5762af, 0x435ac5f9,
+ 0x36cde9d5, 0xc313804d, 0xa4623760, 0xb1c37572,
+ 0x2b22486d, 0x8af131e3, 0x3e5fc3ea, 0x0d9c9ba0,
+ 0x218bcc8f, 0x8bcdfea2, 0xcf55a599, 0x57b9fcbc,
+ 0x5c087f62, 0xec130a15, 0x7e8bd1f5, 0x60eaaa51,
+ 0x020dd89b, 0x890cc6ea, 0x042d0054, 0x74055863};
uint8_t result;
- printf("=== Running 1024 bit enc/verify test from Robs RSA code. ===\n");
+ printf("Running TC9: 2048 bit operands.s\n");
- result = testrunner(33, exponent, 33, modulus, expected, message);
+ result = testrunner(64, exponent, 64, modulus, message, expected);
if (result)
- printf("Rob 1024 enc/verify test OK\n");
+ printf("TC9: OK\n");
else
- printf("Rob 1024 enc/verify test NOT OK\n");
+ printf("TC9: NOT OK\n");
}
@@ -717,22 +697,21 @@ void rob_enc_1024(void)
int main(void)
{
check_modexp_access();
- // tc_set_debug(1);
+// tc_set_debug(1);
// check_modulus_mem();
// check_exponent_mem();
// check_message_mem();
-// tc1();
-// tc2();
-// tc3();
-// tc4();
-// tc5();
-// tc6();
-// tc7();
-// tc8();
- rob_dec_1024();
- rob_enc_1024();
+ tc1();
+ tc2();
+ tc3();
+ tc4();
+ tc5();
+ tc6();
+ tc7();
+ tc8();
+ tc9();
return 0;
}
diff --git a/sw/tc_eim.c b/sw/tc_eim.c
index 8ef4f06..87e90d1 100644
--- a/sw/tc_eim.c
+++ b/sw/tc_eim.c
@@ -45,12 +45,13 @@
#include "cryptech.h"
static int debug = 0;
-static int inited = 0;
/* ---------------- EIM low-level code ---------------- */
static int init(void)
{
+ static int inited = 0;
+
if (inited)
return 0;
@@ -84,11 +85,11 @@ void tc_set_debug(int onoff)
debug = onoff;
}
-static void dump(char *label, const uint8_t *buf, size_t len)
+static void dump(char *label, off_t addr, const uint8_t *buf, size_t len)
{
if (debug) {
int i;
- printf("%s [", label);
+ printf("%s %04x [", label, (unsigned int)addr);
for (i = 0; i < len; ++i)
printf(" %02x", buf[i]);
printf(" ]\n");
@@ -100,10 +101,9 @@ int tc_write(off_t offset, const uint8_t *buf, size_t len)
if (init() != 0)
return -1;
- dump("write ", buf, len);
+ dump("write ", offset, buf, len);
- offset = eim_offset(offset);
- for (; len > 0; offset += 4, buf += 4, len -= 4) {
+ for (offset = eim_offset(offset); len > 0; offset += 4, buf += 4, len -= 4) {
uint32_t val;
val = htonl(*(uint32_t *)buf);
eim_write_32(offset, &val);
@@ -114,20 +114,20 @@ 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)
{
+ off_t off;
uint8_t *rbuf = buf;
int rlen = len;
if (init() != 0)
return -1;
- offset = eim_offset(offset);
- for (; rlen > 0; offset += 4, rbuf += 4, rlen -= 4) {
+ for (off = eim_offset(offset); rlen > 0; off += 4, rbuf += 4, rlen -= 4) {
uint32_t val;
- eim_read_32(offset, &val);
+ eim_read_32(off, &val);
*(uint32_t *)rbuf = ntohl(val);
}
- dump("read ", buf, len);
+ dump("read ", offset, buf, len);
return 0;
}
@@ -142,7 +142,7 @@ int tc_expected(off_t offset, const uint8_t *expected, size_t len)
perror("malloc");
return 1;
}
- dump("expect", expected, len);
+ dump("expect", offset, expected, len);
if (tc_read(offset, buf, len) != 0)
goto errout;
diff --git a/sw/trng_extractor.c b/sw/trng_extractor.c
index e25ebf0..c0ff227 100644
--- a/sw/trng_extractor.c
+++ b/sw/trng_extractor.c
@@ -53,31 +53,18 @@ char *usage =
-v verbose operation\n\
";
-/* check availability of avalanche entropy core by reading core name and version */
-static int avalanche_check(void)
-{
- return
- tc_expected(ENTROPY1_ADDR_NAME0, (const uint8_t *)AVALANCHE_ENTROPY_NAME0, 4) ||
- tc_expected(ENTROPY1_ADDR_NAME1, (const uint8_t *)AVALANCHE_ENTROPY_NAME1, 4);
-}
+/* ---------------- startup code ---------------- */
-/* check availability of rosc core by reading the core name and version */
-static int rosc_check(void)
-{
- return
- tc_expected(ENTROPY2_ADDR_NAME0, (const uint8_t *)ROSC_ENTROPY_NAME0, 4) ||
- tc_expected(ENTROPY2_ADDR_NAME1, (const uint8_t *)ROSC_ENTROPY_NAME1, 4);
-}
+static off_t entropy1_addr_base, entropy2_addr_base, csprng_addr_base;
-/* check availability of csprng core by reading the core name and version */
-static int csprng_check(void)
+static void init(void)
{
- return
- tc_expected(CSPRNG_ADDR_NAME0, (const uint8_t *)CSPRNG_NAME0, 4) ||
- tc_expected(CSPRNG_ADDR_NAME1, (const uint8_t *)CSPRNG_NAME1, 4);
+ entropy1_addr_base = tc_core_base("extnoise");
+ entropy2_addr_base = tc_core_base("rosc ent");
+ csprng_addr_base = tc_core_base("csprng");
}
-/* extract one data sample */
+/* ---------------- 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) {
@@ -93,18 +80,20 @@ static int extract(off_t status_addr, off_t data_addr, uint32_t *data)
return 0;
}
-/* main */
+/* ---------------- main ---------------- */
int main(int argc, char *argv[])
{
int opt;
unsigned long num_words = 1, i;
char *endptr;
- off_t status_addr = CSPRNG_ADDR_STATUS;
- off_t data_addr = CSPRNG_ADDR_RANDOM;
+ off_t status_addr = 0;
+ off_t data_addr = 0;
FILE *output = stdout;
uint32_t data;
int verbose = 0;
+ init();
+
/* parse command line */
while ((opt = getopt(argc, argv, "h?varcn:o:")) != -1) {
switch (opt) {
@@ -113,16 +102,16 @@ int main(int argc, char *argv[])
printf(usage, argv[0]);
return EXIT_SUCCESS;
case 'a':
- status_addr = ENTROPY1_ADDR_STATUS;
- data_addr = ENTROPY1_ADDR_ENTROPY;
+ status_addr = entropy1_addr_base + ENTROPY1_ADDR_STATUS;
+ data_addr = entropy1_addr_base + ENTROPY1_ADDR_ENTROPY;
break;
case 'r':
- status_addr = ENTROPY2_ADDR_STATUS;
- data_addr = ENTROPY2_ADDR_ENTROPY;
+ status_addr = entropy2_addr_base + ENTROPY2_ADDR_STATUS;
+ data_addr = entropy2_addr_base + ENTROPY2_ADDR_ENTROPY;
break;
case 'c':
- status_addr = CSPRNG_ADDR_STATUS;
- data_addr = CSPRNG_ADDR_RANDOM;
+ status_addr = csprng_addr_base + CSPRNG_ADDR_STATUS;
+ data_addr = csprng_addr_base + CSPRNG_ADDR_RANDOM;
break;
case 'v':
verbose = 1;
@@ -171,15 +160,10 @@ int main(int argc, char *argv[])
goto errout;
}
- // Check that we can talk to the trng.
- if (verbose)
- printf("Checking that we can access the TRNG...\n");
- if (avalanche_check() || rosc_check() || csprng_check()) {
- fprintf(stderr, "Can't properly access the trng.\n");
- return EXIT_FAILURE;
+ if (status_addr == 0) {
+ status_addr = csprng_addr_base + CSPRNG_ADDR_STATUS;
+ data_addr = csprng_addr_base + CSPRNG_ADDR_RANDOM;
}
- if (verbose)
- printf("TRNG access ok..\n");
/* get the data */
for (i = 0; i < num_words; ++i) {
diff --git a/sw/trng_tester.c b/sw/trng_tester.c
index 715a20c..6243544 100644
--- a/sw/trng_tester.c
+++ b/sw/trng_tester.c
@@ -57,6 +57,27 @@ int repeat = 0;
int num_words = 10;
int wait_stats = 0;
+/* ---------------- startup code ---------------- */
+
+static off_t board_addr_base = 0;
+static off_t trng_addr_base, entropy1_addr_base, entropy2_addr_base, csprng_addr_base;
+
+static int init(void)
+{
+ static int inited = 0;
+
+ if (inited)
+ return 0;
+
+ trng_addr_base = tc_core_base("trng");
+ entropy1_addr_base = tc_core_base("extnoise");
+ entropy2_addr_base = tc_core_base("rosc ent");
+ csprng_addr_base = tc_core_base("csprng");
+
+ inited = 1;
+ return 0;
+}
+
/* ---------------- sanity test case ---------------- */
int TC0()
@@ -66,6 +87,9 @@ int TC0()
uint8_t version[4] = NOVENA_BOARD_VERSION;
uint8_t t[4];
+ if (init() != 0)
+ return -1;
+
if (!quiet)
printf("TC0: Reading board type, version, and dummy reg from global registers.\n");
@@ -73,14 +97,14 @@ int TC0()
* to make sure that we can actually write something into EIM
*/
(void)time((time_t *)t);
- if (tc_write(BOARD_ADDR_DUMMY, t, 4) != 0)
+ if (tc_write(board_addr_base + BOARD_ADDR_DUMMY, t, 4) != 0)
return 1;
return
- tc_expected(BOARD_ADDR_NAME0, name0, 4) ||
- tc_expected(BOARD_ADDR_NAME1, name1, 4) ||
- tc_expected(BOARD_ADDR_VERSION, version, 4) ||
- tc_expected(BOARD_ADDR_DUMMY, t, 4);
+ tc_expected(board_addr_base + BOARD_ADDR_NAME0, name0, 4) ||
+ tc_expected(board_addr_base + BOARD_ADDR_NAME1, name1, 4) ||
+ tc_expected(board_addr_base + BOARD_ADDR_VERSION, version, 4) ||
+ tc_expected(board_addr_base + BOARD_ADDR_DUMMY, t, 4);
}
/* ---------------- trng test cases ---------------- */
@@ -92,13 +116,20 @@ int TC1(void)
uint8_t name1[4] = TRNG_NAME1;
uint8_t version[4] = TRNG_VERSION;
+ if (init() != 0)
+ return -1;
+ if ((trng_addr_base == 0) && !quiet) {
+ printf("TC1: TRNG not present\n");
+ return 0;
+ }
+
if (!quiet)
printf("TC1: Reading name and version words from trng core.\n");
return
- tc_expected(TRNG_ADDR_NAME0, name0, 4) ||
- tc_expected(TRNG_ADDR_NAME1, name1, 4) ||
- tc_expected(TRNG_ADDR_VERSION, version, 4);
+ tc_expected(trng_addr_base + TRNG_ADDR_NAME0, name0, 4) ||
+ tc_expected(trng_addr_base + TRNG_ADDR_NAME1, name1, 4) ||
+ tc_expected(trng_addr_base + TRNG_ADDR_VERSION, version, 4);
}
/* XXX test cases for setting blinkenlights? */
@@ -113,13 +144,20 @@ int TC2(void)
uint8_t name1[4] = AVALANCHE_ENTROPY_NAME1;
uint8_t version[4] = AVALANCHE_ENTROPY_VERSION;
+ if (init() != 0)
+ return -1;
+ if ((entropy1_addr_base == 0) && !quiet) {
+ printf("TC2: AVALANCHE_ENTROPY not present\n");
+ return 0;
+ }
+
if (!quiet)
printf("TC2: Reading name and version words from avalanche_entropy core.\n");
return
- tc_expected(ENTROPY1_ADDR_NAME0, name0, 4) ||
- tc_expected(ENTROPY1_ADDR_NAME1, name1, 4) ||
- tc_expected(ENTROPY1_ADDR_VERSION, version, 4);
+ tc_expected(entropy1_addr_base + ENTROPY1_ADDR_NAME0, name0, 4) ||
+ tc_expected(entropy1_addr_base + ENTROPY1_ADDR_NAME1, name1, 4) ||
+ tc_expected(entropy1_addr_base + ENTROPY1_ADDR_VERSION, version, 4);
}
/* XXX clear 'enable' control bit, see if we read the same value */
@@ -130,16 +168,23 @@ int TC3(void)
int i, n;
uint32_t entropy;
+ if (init() != 0)
+ return -1;
+ if ((entropy1_addr_base == 0) && !quiet) {
+ printf("TC3: AVALANCHE_ENTROPY not present\n");
+ return 0;
+ }
+
if (!quiet)
printf("TC3: Read random data from avalanche_entropy.\n");
for (i = 0; i < num_words; ++i) {
/* check status */
n = 0;
- if (tc_wait(ENTROPY1_ADDR_STATUS, ENTROPY1_STATUS_VALID, &n) != 0)
+ if (tc_wait(entropy1_addr_base + ENTROPY1_ADDR_STATUS, ENTROPY1_STATUS_VALID, &n) != 0)
return 1;
/* read entropy data */
- if (tc_read(ENTROPY1_ADDR_ENTROPY, (uint8_t *)&entropy, 4) != 0)
+ if (tc_read(entropy1_addr_base + ENTROPY1_ADDR_ENTROPY, (uint8_t *)&entropy, 4) != 0)
return 1;
/* display entropy data */
if (!debug) {
@@ -162,13 +207,20 @@ int TC4(void)
uint8_t name1[4] = ROSC_ENTROPY_NAME1;
uint8_t version[4] = ROSC_ENTROPY_VERSION;
+ if (init() != 0)
+ return -1;
+ if ((entropy2_addr_base == 0) && !quiet) {
+ printf("TC4: ROSC_ENTROPY not present\n");
+ return 0;
+ }
+
if (!quiet)
printf("TC4: Reading name and version words from rosc_entropy core.\n");
return
- tc_expected(ENTROPY2_ADDR_NAME0, name0, 4) ||
- tc_expected(ENTROPY2_ADDR_NAME1, name1, 4) ||
- tc_expected(ENTROPY2_ADDR_VERSION, version, 4);
+ tc_expected(entropy2_addr_base + ENTROPY2_ADDR_NAME0, name0, 4) ||
+ tc_expected(entropy2_addr_base + ENTROPY2_ADDR_NAME1, name1, 4) ||
+ tc_expected(entropy2_addr_base + ENTROPY2_ADDR_VERSION, version, 4);
}
/* XXX clear 'enable' control bit, see if we read the same value */
@@ -179,16 +231,23 @@ int TC5(void)
int i, n;
uint32_t entropy;
+ if (init() != 0)
+ return -1;
+ if ((entropy2_addr_base == 0) && !quiet) {
+ printf("TC5: ROSC_ENTROPY not present\n");
+ return 0;
+ }
+
if (!quiet)
printf("TC5: Read random data from rosc_entropy.\n");
for (i = 0; i < num_words; ++i) {
/* check status */
n = 0;
- if (tc_wait(ENTROPY2_ADDR_STATUS, ENTROPY2_STATUS_VALID, &n) != 0)
+ if (tc_wait(entropy2_addr_base + ENTROPY2_ADDR_STATUS, ENTROPY2_STATUS_VALID, &n) != 0)
return 1;
/* read entropy data */
- if (tc_read(ENTROPY2_ADDR_ENTROPY, (uint8_t *)&entropy, 4) != 0)
+ if (tc_read(entropy2_addr_base + ENTROPY2_ADDR_ENTROPY, (uint8_t *)&entropy, 4) != 0)
return 1;
/* display entropy data */
if (!debug) {
@@ -211,13 +270,20 @@ int TC6(void)
uint8_t name1[4] = CSPRNG_NAME1;
uint8_t version[4] = CSPRNG_VERSION;
+ if (init() != 0)
+ return -1;
+ if ((csprng_addr_base == 0) && !quiet) {
+ printf("TC6: CSPRNG not present\n");
+ return 0;
+ }
+
if (!quiet)
printf("TC6: Reading name and version words from trng_csprng core.\n");
return
- tc_expected(CSPRNG_ADDR_NAME0, name0, 4) ||
- tc_expected(CSPRNG_ADDR_NAME1, name1, 4) ||
- tc_expected(CSPRNG_ADDR_VERSION, version, 4);
+ tc_expected(csprng_addr_base + CSPRNG_ADDR_NAME0, name0, 4) ||
+ tc_expected(csprng_addr_base + CSPRNG_ADDR_NAME1, name1, 4) ||
+ tc_expected(csprng_addr_base + CSPRNG_ADDR_VERSION, version, 4);
}
/* XXX clear 'enable' control bit, see if we read the same value */
@@ -229,16 +295,23 @@ int TC7(void)
int i, n;
uint32_t random;
+ if (init() != 0)
+ return -1;
+ if ((csprng_addr_base == 0) && !quiet) {
+ printf("TC7: CSPRNG not present\n");
+ return 0;
+ }
+
if (!quiet)
printf("TC7: Read random data from trng_csprng.\n");
for (i = 0; i < num_words; ++i) {
/* check status */
n = 0;
- if (tc_wait(CSPRNG_ADDR_STATUS, CSPRNG_STATUS_VALID, &n) != 0)
+ if (tc_wait(csprng_addr_base + CSPRNG_ADDR_STATUS, CSPRNG_STATUS_VALID, &n) != 0)
return 1;
/* read random data */
- if (tc_read(CSPRNG_ADDR_RANDOM, (uint8_t *)&random, 4) != 0)
+ if (tc_read(csprng_addr_base + CSPRNG_ADDR_RANDOM, (uint8_t *)&random, 4) != 0)
return 1;
/* display random data */
if (!debug) {