From f141a79d805acbab07876d9f007e8809603718b5 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Wed, 10 Jun 2015 12:30:58 -0400 Subject: generate core_selector, probe FPGA for cores at software startup --- config/config.cfg | 19 +++ config/config.py | 212 +++++++++++++++++++++++++++ config/core_selector.v | 250 ++++++++++++++++++++++++++++++++ eim/build/Makefile | 7 +- sw/Makefile | 2 +- sw/Makefile.i2c | 2 +- sw/aes_tester.c | 102 +++++++------ sw/capability.c | 145 +++++++++++++++++++ sw/cryptech.h | 381 ++++++++++++++++++++++++------------------------- sw/hash.c | 84 ++++++++--- sw/hash_tester.c | 206 ++++++++++++++++++-------- sw/modexp_tester.c | 333 ++++++++++++++++++++---------------------- sw/tc_eim.c | 22 +-- sw/trng_extractor.c | 58 +++----- sw/trng_tester.c | 119 ++++++++++++--- 15 files changed, 1363 insertions(+), 579 deletions(-) create mode 100644 config/config.cfg create mode 100755 config/config.py create mode 100644 config/core_selector.v create mode 100644 sw/capability.c 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 +#include +#include +#include + +#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) { -- cgit v1.2.3