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 From 026fc461d9791bc360036f1269d0f6d61c45d179 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Wed, 23 Sep 2015 16:31:28 -0400 Subject: Trailing whitespace cleanup. --- common/rtl/lint-dummy.v | 14 +-- common/rtl/novena_regs.v | 4 +- config/config.py | 4 +- eim/build/xilinx.mk | 16 ++-- eim/rtl/novena_eim.v | 4 +- i2c/build/xilinx.mk | 16 ++-- i2c/rtl/novena_i2c.v | 14 +-- sw/capability.c | 6 +- sw/configure-fpga.sh | 6 +- sw/modexps6_tester.c | 224 +++++++++++++++++++++++------------------------ sw/novena-eim.c | 16 ++-- sw/tc_eim.c | 6 +- sw/tc_i2c.c | 6 +- 13 files changed, 168 insertions(+), 168 deletions(-) diff --git a/common/rtl/lint-dummy.v b/common/rtl/lint-dummy.v index 9d4d2d3..5cf4b61 100644 --- a/common/rtl/lint-dummy.v +++ b/common/rtl/lint-dummy.v @@ -69,7 +69,7 @@ module FD (Q, C, D); input C, D; endmodule -module DSP48A1 (BCOUT, CARRYOUT, CARRYOUTF, M, P, PCOUT, A, B, C, CARRYIN, CEA, CEB, CEC, CECARRYIN, CED, CEM, CEOPMODE, CEP, CLK, D, OPMODE, PCIN, RSTA, RSTB, RSTC, RSTCARRYIN, RSTD, RSTM, RSTOPMODE, RSTP); +module DSP48A1 (BCOUT, CARRYOUT, CARRYOUTF, M, P, PCOUT, A, B, C, CARRYIN, CEA, CEB, CEC, CECARRYIN, CED, CEM, CEOPMODE, CEP, CLK, D, OPMODE, PCIN, RSTA, RSTB, RSTC, RSTCARRYIN, RSTD, RSTM, RSTOPMODE, RSTP); parameter integer A0REG = 0; parameter integer A1REG = 1; parameter integer B0REG = 0; @@ -83,11 +83,11 @@ module DSP48A1 (BCOUT, CARRYOUT, CARRYOUTF, M, P, PCOUT, A, B, C, CARRYIN, CEA, parameter integer OPMODEREG = 1; parameter integer PREG = 1; parameter RSTTYPE = "SYNC"; - output [17:0] BCOUT; - output CARRYOUT; - output CARRYOUTF; - output [35:0] M; - output [47:0] P; + output [17:0] BCOUT; + output CARRYOUT; + output CARRYOUTF; + output [35:0] M; + output [47:0] P; output [47:0] PCOUT; input [17:0] A; input [17:0] B; @@ -110,7 +110,7 @@ module DSP48A1 (BCOUT, CARRYOUT, CARRYOUTF, M, P, PCOUT, A, B, C, CARRYIN, CEA, input RSTC; input RSTCARRYIN; input RSTD; - input RSTM; + input RSTM; input RSTOPMODE; input RSTP; endmodule diff --git a/common/rtl/novena_regs.v b/common/rtl/novena_regs.v index eb89092..6b52a80 100644 --- a/common/rtl/novena_regs.v +++ b/common/rtl/novena_regs.v @@ -86,13 +86,13 @@ module board_regs wire [31 : 0] core_name0 = CORE_NAME0; wire [31 : 0] core_name1 = CORE_NAME1; wire [31 : 0] core_version = CORE_VERSION; - + //---------------------------------------------------------------- // Concurrent connectivity for ports etc. //---------------------------------------------------------------- assign read_data = tmp_read_data; assign error = write_error | read_error; - + //---------------------------------------------------------------- // storage registers for mapping memory to core interface //---------------------------------------------------------------- diff --git a/config/config.py b/config/config.py index 86c8615..bdbda1a 100755 --- a/config/config.py +++ b/config/config.py @@ -79,7 +79,7 @@ def createInstance(core): s4 = "" s5 = "addr_core_reg" s6 = "" - + return "\ //----------------------------------------------------------------\n\ // {1}\n\ @@ -126,7 +126,7 @@ def createModule(cores): cores[j] += '_' + str(i) i += 1 j += 1 - + addrs = "" insts = "" muxs = "" diff --git a/eim/build/xilinx.mk b/eim/build/xilinx.mk index 8a81ef9..7a8d9d4 100644 --- a/eim/build/xilinx.mk +++ b/eim/build/xilinx.mk @@ -1,6 +1,6 @@ # The top level module should define the variables below then include # this file. The files listed should be in the same directory as the -# Makefile. +# Makefile. # # variable description # ---------- ------------- @@ -11,7 +11,7 @@ # vfiles all local .v files # xilinx_cores all local .xco files # vendor vendor of FPGA (xilinx, altera, etc.) -# family FPGA device family (spartan3e) +# family FPGA device family (spartan3e) # part FPGA part name (xc4vfx12-10-sf363) # flashsize size of flash for mcs file (16384) # optfile (optional) xst extra opttions file to put in .scr @@ -40,7 +40,7 @@ xil_env ?= . $(isedir)/settings32.sh flashsize ?= 8192 ucf ?= $(project).ucf -libmks = $(patsubst %,$(libdir)/%/module.mk,$(libs)) +libmks = $(patsubst %,$(libdir)/%/module.mk,$(libs)) mkfiles = $(libmks) xilinx.mk include $(libmks) @@ -110,9 +110,9 @@ $(project)_par.ncd: $(project).ncd :; \ else \ $(MAKE) etwr; \ - fi -junk += $(project)_par.ncd $(project)_par.par $(project)_par.pad -junk += $(project)_par_pad.csv $(project)_par_pad.txt + fi +junk += $(project)_par.ncd $(project)_par.par $(project)_par.pad +junk += $(project)_par_pad.csv $(project)_par_pad.txt junk += $(project)_par.grf $(project)_par.ptwx junk += $(project)_par.unroutes $(project)_par.xpi @@ -126,7 +126,7 @@ $(project).ncd: $(project).ngd $(xil_env); \ map $(intstyle) $(map_opts) $$smartguide $< junk += $(project).ncd $(project).pcf $(project).ngm $(project).mrp $(project).map -junk += smartguide.ncd $(project).psr +junk += smartguide.ncd $(project).psr junk += $(project)_summary.xml $(project)_usage.xml $(project).ngd: $(project).ngc $(ucf) @@ -135,7 +135,7 @@ junk += $(project).ngd $(project).bld $(project).ngc: $(vfiles) $(local_corengcs) $(project).scr $(project).prj $(xil_env); xst $(intstyle) -ifn $(project).scr -junk += xlnx_auto* $(top_module).lso $(project).srp +junk += xlnx_auto* $(top_module).lso $(project).srp junk += netlist.lst xst $(project).ngc $(project).prj: $(vfiles) $(mkfiles) diff --git a/eim/rtl/novena_eim.v b/eim/rtl/novena_eim.v index 1a1b1f6..c774b6c 100644 --- a/eim/rtl/novena_eim.v +++ b/eim/rtl/novena_eim.v @@ -56,7 +56,7 @@ module novena_top input wire eim_bclk, // EIM burst clock. Started by the CPU. input wire eim_cs0_n, // Chip select (active low). inout wire [15 : 0] eim_da, // Bidirectional address and data port. - input wire [18: 16] eim_a, // MSB part of address port. + input wire [18: 16] eim_a, // MSB part of address port. input wire eim_lba_n, // Latch address signal (active low). input wire eim_wr_n, // write enable signal (active low). input wire eim_oe_n, // output enable signal (active low). @@ -158,7 +158,7 @@ module novena_top .noise(ct_noise), .debug(ct_led) - ); + ); //---------------------------------------------------------------- diff --git a/i2c/build/xilinx.mk b/i2c/build/xilinx.mk index f35cc98..cace9c1 100644 --- a/i2c/build/xilinx.mk +++ b/i2c/build/xilinx.mk @@ -1,6 +1,6 @@ # The top level module should define the variables below then include # this file. The files listed should be in the same directory as the -# Makefile. +# Makefile. # # variable description # ---------- ------------- @@ -11,7 +11,7 @@ # vfiles all local .v files # xilinx_cores all local .xco files # vendor vendor of FPGA (xilinx, altera, etc.) -# family FPGA device family (spartan3e) +# family FPGA device family (spartan3e) # part FPGA part name (xc4vfx12-10-sf363) # flashsize size of flash for mcs file (16384) # optfile (optional) xst extra opttions file to put in .scr @@ -38,7 +38,7 @@ xil_env ?= . $(isedir)/settings32.sh flashsize ?= 8192 ucf ?= $(project).ucf -libmks = $(patsubst %,$(libdir)/%/module.mk,$(libs)) +libmks = $(patsubst %,$(libdir)/%/module.mk,$(libs)) mkfiles = $(libmks) xilinx.mk include $(libmks) @@ -108,9 +108,9 @@ $(project)_par.ncd: $(project).ncd :; \ else \ $(MAKE) etwr; \ - fi -junk += $(project)_par.ncd $(project)_par.par $(project)_par.pad -junk += $(project)_par_pad.csv $(project)_par_pad.txt + fi +junk += $(project)_par.ncd $(project)_par.par $(project)_par.pad +junk += $(project)_par_pad.csv $(project)_par_pad.txt junk += $(project)_par.grf $(project)_par.ptwx junk += $(project)_par.unroutes $(project)_par.xpi @@ -124,7 +124,7 @@ $(project).ncd: $(project).ngd $(xil_env); \ map $(intstyle) $(map_opts) $$smartguide $< junk += $(project).ncd $(project).pcf $(project).ngm $(project).mrp $(project).map -junk += smartguide.ncd $(project).psr +junk += smartguide.ncd $(project).psr junk += $(project)_summary.xml $(project)_usage.xml $(project).ngd: $(project).ngc $(ucf) @@ -133,7 +133,7 @@ junk += $(project).ngd $(project).bld $(project).ngc: $(vfiles) $(local_corengcs) $(project).scr $(project).prj $(xil_env); xst $(intstyle) -ifn $(project).scr -junk += xlnx_auto* $(top_module).lso $(project).srp +junk += xlnx_auto* $(top_module).lso $(project).srp junk += netlist.lst xst $(project).ngc $(project).prj: $(vfiles) $(mkfiles) diff --git a/i2c/rtl/novena_i2c.v b/i2c/rtl/novena_i2c.v index d1833b2..f6230a0 100644 --- a/i2c/rtl/novena_i2c.v +++ b/i2c/rtl/novena_i2c.v @@ -53,7 +53,7 @@ module novena_top // I2C interface input wire i2c_scl, inout wire i2c_sda, - + // Novena utility ports output wire apoptosis_pin, // Hold low to not restart after config. output wire led_pin // LED on edge close to the FPGA. @@ -94,7 +94,7 @@ module novena_top wire sda_pd; wire sda_int; - + wire clk = sys_clk; wire reset_n = ~sys_rst; @@ -139,7 +139,7 @@ module novena_top .rxd_syn(i2c_rxd_syn), .rxd_data(i2c_rxd_data), .rxd_ack(i2c_rxd_ack), - + // Internal transmit interface. .txd_syn(i2c_txd_syn), .txd_data(i2c_txd_data), @@ -150,15 +150,15 @@ module novena_top ( .clk(clk), .reset_n(reset_n), - + .rx_syn(i2c_rxd_syn), .rx_data(i2c_rxd_data), .rx_ack(i2c_rxd_ack), - + .tx_syn(i2c_txd_syn), .tx_data(i2c_txd_data), .tx_ack(i2c_txd_ack), - + // Interface to the core being tested. .core_reset_n(coretest_reset_n), .core_cs(coretest_cs), @@ -195,7 +195,7 @@ module novena_top .noise(ct_noise), .debug(ct_led) - ); + ); //---------------------------------------------------------------- diff --git a/sw/capability.c b/sw/capability.c index 9b29c98..051b23a 100644 --- a/sw/capability.c +++ b/sw/capability.c @@ -1,11 +1,11 @@ -/* +/* * 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: diff --git a/sw/configure-fpga.sh b/sw/configure-fpga.sh index 7ebfb6b..c355066 100644 --- a/sw/configure-fpga.sh +++ b/sw/configure-fpga.sh @@ -4,10 +4,10 @@ echo "Setting export of reset pin" echo 135 > /sys/class/gpio/export echo "setting reset pin to out" echo out > /sys/class/gpio/gpio135/direction -echo "flipping reset" +echo "flipping reset" echo 0 > /sys/class/gpio/gpio135/value echo 1 > /sys/class/gpio/gpio135/value -echo "configuring FPGA" +echo "configuring FPGA" dd if=${bitfile} of=/dev/spidev2.0 bs=128 -echo "turning on clock to FPGA" +echo "turning on clock to FPGA" devmem3 0x020c8160 w 0x00000D2B diff --git a/sw/modexps6_tester.c b/sw/modexps6_tester.c index a9e3b74..b76a6b3 100644 --- a/sw/modexps6_tester.c +++ b/sw/modexps6_tester.c @@ -23,10 +23,10 @@ int repeat = 0; int tc_width(off_t offset, uint32_t length) { length = htonl(length); // ! - + uint8_t width[4]; memcpy(width, &length, 4); - + return tc_write(offset, width, sizeof(width)); } @@ -79,7 +79,7 @@ int TC0(void) int TC1(void) { int ret; - + if (!quiet) printf("TC1: Sign 1024-bit message (fast & unsafe public mode).\n"); @@ -93,37 +93,37 @@ int TC1(void) /*uint8_t mode_slow_secure[] = {0, 0, 0, 0};*/ uint8_t mode_fast_unsafe[] = {0, 0, 0, 1}; tc_write(MODEXPS6_ADDR_MODE, mode_fast_unsafe, sizeof(mode_fast_unsafe)); - + /* Set new modulus size */ tc_width(MODEXPS6_ADDR_MODULUS_WIDTH, sizeof(modulus) * 8); // number of bits - + /* Write new modulus */ tc_write(MODEXPS6_ADDR_MODULUS, modulus, sizeof(modulus)); - + /* Pre-calculate speed-up coefficient */ tc_init(MODEXPS6_ADDR_CTRL); /* Wait while core is calculating */ tc_wait_ready(MODEXPS6_ADDR_STATUS); - + /* Write new message */ tc_write(MODEXPS6_ADDR_MESSAGE, message, sizeof(message)); - + /* Set new exponent length */ tc_width(MODEXPS6_ADDR_EXPONENT_WIDTH, sizeof(exponent) * 8); // number of bits - + /* Write new exponent */ tc_write(MODEXPS6_ADDR_EXPONENT, exponent, sizeof(exponent)); - + /* Start calculation */ tc_next(MODEXPS6_ADDR_CTRL); - + /* Wait while core is calculating */ - tc_wait_valid(MODEXPS6_ADDR_STATUS); - + tc_wait_valid(MODEXPS6_ADDR_STATUS); + /* Compare actual result with expected value */ ret = tc_expected(MODEXPS6_ADDR_RESULT, result, sizeof(result)); - + return ret; } @@ -131,7 +131,7 @@ int TC1(void) int TC2(void) { int ret; - + if (!quiet) printf("TC2: Sign 1024-bit message (slow & secure private mode).\n"); @@ -145,37 +145,37 @@ int TC2(void) uint8_t mode_slow_secure[] = {0, 0, 0, 0}; /*uint8_t mode_fast_unsafe[] = {0, 0, 0, 1};*/ tc_write(MODEXPS6_ADDR_MODE, mode_slow_secure, sizeof(mode_slow_secure)); - + /* Set new modulus size */ tc_width(MODEXPS6_ADDR_MODULUS_WIDTH, sizeof(modulus) * 8); // number of bits - + /* Write new modulus */ tc_write(MODEXPS6_ADDR_MODULUS, modulus, sizeof(modulus)); - + /* Pre-calculate speed-up coefficient */ tc_init(MODEXPS6_ADDR_CTRL); /* Wait while core is calculating */ tc_wait_ready(MODEXPS6_ADDR_STATUS); - + /* Write new message */ tc_write(MODEXPS6_ADDR_MESSAGE, message, sizeof(message)); - + /* Set new exponent length */ tc_width(MODEXPS6_ADDR_EXPONENT_WIDTH, sizeof(exponent) * 8); // number of bits - + /* Write new exponent */ tc_write(MODEXPS6_ADDR_EXPONENT, exponent, sizeof(exponent)); - + /* Start calculation */ tc_next(MODEXPS6_ADDR_CTRL); - + /* Wait while core is calculating */ - tc_wait_valid(MODEXPS6_ADDR_STATUS); - + tc_wait_valid(MODEXPS6_ADDR_STATUS); + /* Compare actual result with expected value */ ret = tc_expected(MODEXPS6_ADDR_RESULT, result, sizeof(result)); - + return ret; } @@ -183,7 +183,7 @@ int TC2(void) int TC3(void) { int ret; - + if (!quiet) printf("TC3: Sign 2048-bit message (fast & unsafe public mode).\n"); @@ -197,37 +197,37 @@ int TC3(void) /*uint8_t mode_slow_secure[] = {0, 0, 0, 0};*/ uint8_t mode_fast_unsafe[] = {0, 0, 0, 1}; tc_write(MODEXPS6_ADDR_MODE, mode_fast_unsafe, sizeof(mode_fast_unsafe)); - + /* Set new modulus size */ tc_width(MODEXPS6_ADDR_MODULUS_WIDTH, sizeof(modulus) * 8); // number of bits - + /* Write new modulus */ tc_write(MODEXPS6_ADDR_MODULUS, modulus, sizeof(modulus)); - + /* Pre-calculate speed-up coefficient */ tc_init(MODEXPS6_ADDR_CTRL); /* Wait while core is calculating */ tc_wait_ready(MODEXPS6_ADDR_STATUS); - + /* Write new message */ tc_write(MODEXPS6_ADDR_MESSAGE, message, sizeof(message)); - + /* Set new exponent length */ tc_width(MODEXPS6_ADDR_EXPONENT_WIDTH, sizeof(exponent) * 8); // number of bits - + /* Write new exponent */ tc_write(MODEXPS6_ADDR_EXPONENT, exponent, sizeof(exponent)); - + /* Start calculation */ tc_next(MODEXPS6_ADDR_CTRL); - + /* Wait while core is calculating */ - tc_wait_valid(MODEXPS6_ADDR_STATUS); - + tc_wait_valid(MODEXPS6_ADDR_STATUS); + /* Compare actual result with expected value */ ret = tc_expected(MODEXPS6_ADDR_RESULT, result, sizeof(result)); - + return ret; } @@ -235,7 +235,7 @@ int TC3(void) int TC4(void) { int ret; - + if (!quiet) printf("TC4: Sign 2048-bit message (slow & secure private mode).\n"); @@ -249,37 +249,37 @@ int TC4(void) uint8_t mode_slow_secure[] = {0, 0, 0, 0}; /*uint8_t mode_fast_unsafe[] = {0, 0, 0, 1};*/ tc_write(MODEXPS6_ADDR_MODE, mode_slow_secure, sizeof(mode_slow_secure)); - + /* Set new modulus size */ tc_width(MODEXPS6_ADDR_MODULUS_WIDTH, sizeof(modulus) * 8); // number of bits - + /* Write new modulus */ tc_write(MODEXPS6_ADDR_MODULUS, modulus, sizeof(modulus)); - + /* Pre-calculate speed-up coefficient */ tc_init(MODEXPS6_ADDR_CTRL); /* Wait while core is calculating */ tc_wait_ready(MODEXPS6_ADDR_STATUS); - + /* Write new message */ tc_write(MODEXPS6_ADDR_MESSAGE, message, sizeof(message)); - + /* Set new exponent length */ tc_width(MODEXPS6_ADDR_EXPONENT_WIDTH, sizeof(exponent) * 8); // number of bits - + /* Write new exponent */ tc_write(MODEXPS6_ADDR_EXPONENT, exponent, sizeof(exponent)); - + /* Start calculation */ tc_next(MODEXPS6_ADDR_CTRL); - + /* Wait while core is calculating */ - tc_wait_valid(MODEXPS6_ADDR_STATUS); - + tc_wait_valid(MODEXPS6_ADDR_STATUS); + /* Compare actual result with expected value */ ret = tc_expected(MODEXPS6_ADDR_RESULT, result, sizeof(result)); - + return ret; } @@ -287,7 +287,7 @@ int TC4(void) int TC5(void) { int ret; - + if (!quiet) printf("TC5: Sign 4096-bit message (fast & unsafe public mode).\n"); @@ -301,37 +301,37 @@ int TC5(void) /*uint8_t mode_slow_secure[] = {0, 0, 0, 0};*/ uint8_t mode_fast_unsafe[] = {0, 0, 0, 1}; tc_write(MODEXPS6_ADDR_MODE, mode_fast_unsafe, sizeof(mode_fast_unsafe)); - + /* Set new modulus size */ tc_width(MODEXPS6_ADDR_MODULUS_WIDTH, sizeof(modulus) * 8); // number of bits - + /* Write new modulus */ tc_write(MODEXPS6_ADDR_MODULUS, modulus, sizeof(modulus)); - + /* Pre-calculate speed-up coefficient */ tc_init(MODEXPS6_ADDR_CTRL); /* Wait while core is calculating */ tc_wait_ready(MODEXPS6_ADDR_STATUS); - + /* Write new message */ tc_write(MODEXPS6_ADDR_MESSAGE, message, sizeof(message)); - + /* Set new exponent length */ tc_width(MODEXPS6_ADDR_EXPONENT_WIDTH, sizeof(exponent) * 8); // number of bits - + /* Write new exponent */ tc_write(MODEXPS6_ADDR_EXPONENT, exponent, sizeof(exponent)); - + /* Start calculation */ tc_next(MODEXPS6_ADDR_CTRL); - + /* Wait while core is calculating */ - tc_wait_valid(MODEXPS6_ADDR_STATUS); - + tc_wait_valid(MODEXPS6_ADDR_STATUS); + /* Compare actual result with expected value */ ret = tc_expected(MODEXPS6_ADDR_RESULT, result, sizeof(result)); - + return ret; } @@ -339,7 +339,7 @@ int TC5(void) int TC6(void) { int ret; - + if (!quiet) printf("TC6: Sign 4096-bit message (slow & secure private mode).\n"); @@ -353,37 +353,37 @@ int TC6(void) uint8_t mode_slow_secure[] = {0, 0, 0, 0}; /*uint8_t mode_fast_unsafe[] = {0, 0, 0, 1};*/ tc_write(MODEXPS6_ADDR_MODE, mode_slow_secure, sizeof(mode_slow_secure)); - + /* Set new modulus size */ tc_width(MODEXPS6_ADDR_MODULUS_WIDTH, sizeof(modulus) * 8); // number of bits - + /* Write new modulus */ tc_write(MODEXPS6_ADDR_MODULUS, modulus, sizeof(modulus)); - + /* Pre-calculate speed-up coefficient */ tc_init(MODEXPS6_ADDR_CTRL); /* Wait while core is calculating */ tc_wait_ready(MODEXPS6_ADDR_STATUS); - + /* Write new message */ tc_write(MODEXPS6_ADDR_MESSAGE, message, sizeof(message)); - + /* Set new exponent length */ tc_width(MODEXPS6_ADDR_EXPONENT_WIDTH, sizeof(exponent) * 8); // number of bits - + /* Write new exponent */ tc_write(MODEXPS6_ADDR_EXPONENT, exponent, sizeof(exponent)); - + /* Start calculation */ tc_next(MODEXPS6_ADDR_CTRL); - + /* Wait while core is calculating */ - tc_wait_valid(MODEXPS6_ADDR_STATUS); - + tc_wait_valid(MODEXPS6_ADDR_STATUS); + /* Compare actual result with expected value */ ret = tc_expected(MODEXPS6_ADDR_RESULT, result, sizeof(result)); - + return ret; } @@ -391,7 +391,7 @@ int TC6(void) int TC7(void) { int ret; - + if (!quiet) printf("TC7: Sign several 1024-bit messages (without pre-calculation every time).\n"); @@ -406,40 +406,40 @@ int TC7(void) clone_reversed(result_1, s_1024_1); clone_reversed(result_2, s_1024_2); clone_reversed(result_3, s_1024_3); - + /* Set fast mode */ /*uint8_t mode_slow_secure[] = {0, 0, 0, 0};*/ uint8_t mode_fast_unsafe[] = {0, 0, 0, 1}; tc_write(MODEXPS6_ADDR_MODE, mode_fast_unsafe, sizeof(mode_fast_unsafe)); - + /* Set new modulus size */ tc_width(MODEXPS6_ADDR_MODULUS_WIDTH, sizeof(modulus) * 8); // number of bits - + /* Write new modulus */ tc_write(MODEXPS6_ADDR_MODULUS, modulus, sizeof(modulus)); - + /* Pre-calculate speed-up coefficient */ tc_init(MODEXPS6_ADDR_CTRL); /* Wait while core is calculating */ tc_wait_ready(MODEXPS6_ADDR_STATUS); - + /* Set new exponent length */ tc_width(MODEXPS6_ADDR_EXPONENT_WIDTH, sizeof(exponent) * 8); // number of bits /* Write new exponent */ - tc_write(MODEXPS6_ADDR_EXPONENT, exponent, sizeof(exponent)); - + tc_write(MODEXPS6_ADDR_EXPONENT, exponent, sizeof(exponent)); + { /* Write new message #0 */ tc_write(MODEXPS6_ADDR_MESSAGE, message_0, sizeof(message_0)); - + /* Start calculation */ tc_next(MODEXPS6_ADDR_CTRL); - + /* Wait while core is calculating */ - tc_wait_valid(MODEXPS6_ADDR_STATUS); - + tc_wait_valid(MODEXPS6_ADDR_STATUS); + /* Compare actual result with expected value */ ret = tc_expected(MODEXPS6_ADDR_RESULT, result_0, sizeof(result_0)); if (ret) return 1; @@ -447,13 +447,13 @@ int TC7(void) { /* Write new message #1 */ tc_write(MODEXPS6_ADDR_MESSAGE, message_1, sizeof(message_1)); - + /* Start calculation */ tc_next(MODEXPS6_ADDR_CTRL); - + /* Wait while core is calculating */ - tc_wait_valid(MODEXPS6_ADDR_STATUS); - + tc_wait_valid(MODEXPS6_ADDR_STATUS); + /* Compare actual result with expected value */ ret = tc_expected(MODEXPS6_ADDR_RESULT, result_1, sizeof(result_1)); if (ret) return 1; @@ -461,13 +461,13 @@ int TC7(void) { /* Write new message #2 */ tc_write(MODEXPS6_ADDR_MESSAGE, message_2, sizeof(message_2)); - + /* Start calculation */ tc_next(MODEXPS6_ADDR_CTRL); - + /* Wait while core is calculating */ - tc_wait_valid(MODEXPS6_ADDR_STATUS); - + tc_wait_valid(MODEXPS6_ADDR_STATUS); + /* Compare actual result with expected value */ ret = tc_expected(MODEXPS6_ADDR_RESULT, result_2, sizeof(result_2)); if (ret) return 1; @@ -475,18 +475,18 @@ int TC7(void) { /* Write new message #3 */ tc_write(MODEXPS6_ADDR_MESSAGE, message_3, sizeof(message_3)); - + /* Start calculation */ tc_next(MODEXPS6_ADDR_CTRL); - + /* Wait while core is calculating */ - tc_wait_valid(MODEXPS6_ADDR_STATUS); - + tc_wait_valid(MODEXPS6_ADDR_STATUS); + /* Compare actual result with expected value */ ret = tc_expected(MODEXPS6_ADDR_RESULT, result_3, sizeof(result_3)); if (ret) return 1; } - + return 0; } @@ -494,7 +494,7 @@ int TC7(void) int TC8(void) { int ret; - + if (!quiet) printf("TC8: Verify 4096-bit message (fast mode using public exponent).\n"); @@ -503,46 +503,46 @@ int TC8(void) clone_reversed(message, s_4096); clone_reversed(exponent, e_4096); clone_reversed(result, m_4096); - + /* Set fast mode */ /*uint8_t mode_slow_secure[] = {0, 0, 0, 0};*/ uint8_t mode_fast_unsafe[] = {0, 0, 0, 1}; tc_write(MODEXPS6_ADDR_MODE, mode_fast_unsafe, sizeof(mode_fast_unsafe)); - + /* Set new modulus size */ tc_width(MODEXPS6_ADDR_MODULUS_WIDTH, sizeof(modulus) * 8); // number of bits - + /* Write new modulus */ tc_write(MODEXPS6_ADDR_MODULUS, modulus, sizeof(modulus)); - + /* Pre-calculate speed-up coefficient */ tc_init(MODEXPS6_ADDR_CTRL); /* Wait while core is calculating */ tc_wait_ready(MODEXPS6_ADDR_STATUS); - + /* Write new message */ tc_write(MODEXPS6_ADDR_MESSAGE, message, sizeof(message)); - + /* Set new exponent length */ #if 1 tc_width(MODEXPS6_ADDR_EXPONENT_WIDTH, 18); // number of bits #else tc_width(MODEXPS6_ADDR_EXPONENT_WIDTH, 24); // number of bits #endif - + /* Write new exponent */ tc_write(MODEXPS6_ADDR_EXPONENT, exponent, sizeof(exponent)); - + /* Start calculation */ tc_next(MODEXPS6_ADDR_CTRL); - + /* Wait while core is calculating */ - tc_wait_valid(MODEXPS6_ADDR_STATUS); - + tc_wait_valid(MODEXPS6_ADDR_STATUS); + /* Compare actual result with expected value */ ret = tc_expected(MODEXPS6_ADDR_RESULT, result, sizeof(result)); - + return ret; } diff --git a/sw/novena-eim.c b/sw/novena-eim.c index 85bfac0..424fcd7 100644 --- a/sw/novena-eim.c +++ b/sw/novena-eim.c @@ -1,12 +1,12 @@ -/* +/* * novena-eim.c * ------------ * This module contains the userland magic to set up and use the EIM bus. * - * + * * Author: Pavel Shatov * Copyright (c) 2014-2015, NORDUnet A/S All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: @@ -118,9 +118,9 @@ enum IMX6DQ_REGISTER_OFFSET IOMUXC_SW_PAD_CTL_PAD_EIM_AD15 = 0x020E0464, IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT_B = 0x020E0468, IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK = 0x020E046C, - + CCM_CCGR6 = 0x020C4080, - + EIM_CS0GCR1 = 0x021B8000, EIM_CS0GCR2 = 0x021B8004, EIM_CS0RCR1 = 0x021B8008, @@ -166,17 +166,17 @@ struct CCM_CCGR6 unsigned int cg1_usdhc1 : 2; unsigned int cg2_usdhc2 : 2; unsigned int cg3_usdhc3 : 2; - + unsigned int cg3_usdhc4 : 2; unsigned int cg5_eim_slow : 2; unsigned int cg6_vdoaxiclk : 2; unsigned int cg7_vpu : 2; - + unsigned int cg8_reserved : 2; unsigned int cg9_reserved : 2; unsigned int cg10_reserved : 2; unsigned int cg11_reserved : 2; - + unsigned int cg12_reserved : 2; unsigned int cg13_reserved : 2; unsigned int cg14_reserved : 2; diff --git a/sw/tc_eim.c b/sw/tc_eim.c index 87e90d1..76972cd 100644 --- a/sw/tc_eim.c +++ b/sw/tc_eim.c @@ -1,11 +1,11 @@ -/* +/* * tc_eim.c * -------- * This module contains common code to talk to the FPGA over the EIM bus. - * + * * Author: Paul Selkirk * Copyright (c) 2014-2015, NORDUnet A/S All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: diff --git a/sw/tc_i2c.c b/sw/tc_i2c.c index bcc6be9..c49c5a8 100644 --- a/sw/tc_i2c.c +++ b/sw/tc_i2c.c @@ -1,11 +1,11 @@ -/* +/* * tc_i2c.c * -------- * This module contains common code to talk to the FPGA over the I2C bus. - * + * * Author: Paul Selkirk * Copyright (c) 2014-2015, NORDUnet A/S All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: -- cgit v1.2.3 From 6f5bf9065d49b7829ddd76b502e4034c745cdec2 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Wed, 23 Sep 2015 21:12:29 -0400 Subject: MODEXPS6_ADDR_BASE goes away under the new scheme. --- sw/cryptech.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/sw/cryptech.h b/sw/cryptech.h index 8a7361f..5426359 100644 --- a/sw/cryptech.h +++ b/sw/cryptech.h @@ -402,30 +402,30 @@ in order to map it into a 16-bit address space. // Experimental ModexpS6 core. // XXX AT THE SAME CORE PREFIX - YOU CAN'T HAVE BOTH AT THE SAME TIME -#define MODEXPS6_ADDR_BASE SEGMENT_OFFSET_MATH + (0x00 * CORE_SIZE) -#define MODEXPS6_ADDR_NAME0 MODEXPS6_ADDR_BASE + ADDR_NAME0 -#define MODEXPS6_ADDR_NAME1 MODEXPS6_ADDR_BASE + ADDR_NAME1 -#define MODEXPS6_ADDR_VERSION MODEXPS6_ADDR_BASE + ADDR_VERSION -#define MODEXPS6_ADDR_CTRL MODEXPS6_ADDR_BASE + ADDR_CTRL +// Well, under the old scheme, anyway, remains to be seen with the new scheme +#define MODEXPS6_ADDR_NAME0 ADDR_NAME0 +#define MODEXPS6_ADDR_NAME1 ADDR_NAME1 +#define MODEXPS6_ADDR_VERSION ADDR_VERSION +#define MODEXPS6_ADDR_CTRL ADDR_CTRL #define MODEXPS6_CTRL_INIT_BIT 1 #define MODEXPS6_CTRL_NEXT_BIT 2 -#define MODEXPS6_ADDR_STATUS MODEXPS6_ADDR_BASE + ADDR_STATUS +#define MODEXPS6_ADDR_STATUS ADDR_STATUS /* 4096-bit operands are stored as 128 words of 32 bits */ #define MODEXPS6_OPERAND_SIZE 4096/32 -#define MODEXPS6_ADDR_REGISTERS MODEXPS6_ADDR_BASE + 0*MODEXPS6_OPERAND_SIZE -#define MODEXPS6_ADDR_OPERANDS MODEXPS6_ADDR_BASE + 4*MODEXPS6_OPERAND_SIZE +#define MODEXPS6_ADDR_REGISTERS 0 * MODEXPS6_OPERAND_SIZE +#define MODEXPS6_ADDR_OPERANDS 4 * MODEXPS6_OPERAND_SIZE #define MODEXPS6_ADDR_MODE MODEXPS6_ADDR_REGISTERS + 0x10 #define MODEXPS6_ADDR_MODULUS_WIDTH MODEXPS6_ADDR_REGISTERS + 0x11 #define MODEXPS6_ADDR_EXPONENT_WIDTH MODEXPS6_ADDR_REGISTERS + 0x12 /* addresses of block memories for operands */ -#define MODEXPS6_ADDR_MODULUS MODEXPS6_ADDR_OPERANDS + 0*MODEXPS6_OPERAND_SIZE -#define MODEXPS6_ADDR_MESSAGE MODEXPS6_ADDR_OPERANDS + 1*MODEXPS6_OPERAND_SIZE -#define MODEXPS6_ADDR_EXPONENT MODEXPS6_ADDR_OPERANDS + 2*MODEXPS6_OPERAND_SIZE -#define MODEXPS6_ADDR_RESULT MODEXPS6_ADDR_OPERANDS + 3*MODEXPS6_OPERAND_SIZE +#define MODEXPS6_ADDR_MODULUS MODEXPS6_ADDR_OPERANDS + 0 * MODEXPS6_OPERAND_SIZE +#define MODEXPS6_ADDR_MESSAGE MODEXPS6_ADDR_OPERANDS + 1 * MODEXPS6_OPERAND_SIZE +#define MODEXPS6_ADDR_EXPONENT MODEXPS6_ADDR_OPERANDS + 2 * MODEXPS6_OPERAND_SIZE +#define MODEXPS6_ADDR_RESULT MODEXPS6_ADDR_OPERANDS + 3 * MODEXPS6_OPERAND_SIZE #define MODEXPS6_NAME0 "mode" #define MODEXPS6_NAME1 "xps6" -- cgit v1.2.3 From a8730df1d75d06193335c65b9c9e92c3573ff93d Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Thu, 24 Sep 2015 22:23:30 -0400 Subject: Convert to something a bit more object-oriented, to simplify adding additional methods for things like .h and .mk files. --- config/config.py | 437 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 239 insertions(+), 198 deletions(-) diff --git a/config/config.py b/config/config.py index bdbda1a..29179e4 100755 --- a/config/config.py +++ b/config/config.py @@ -4,209 +4,250 @@ 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 +import ConfigParser +def main(): 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) + parser.add_argument("--cores", help = "comma-delimited list of cores") + parser.add_argument("-c", "--config", default = "config.cfg", help = "config file") + parser.add_argument("-s", "--section", help = "config file section") + parser.add_argument("-o", "--outfile", default = "core_selector.v", help = "output file") 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): + cores = args.cores + + if not cores: try: - j = cores.index(a, j) - except ValueError: - break - cores[j] += '_' + str(i) - i += 1 - j += 1 - - addrs = "" - insts = "" - muxs = "" - corenum = 0 + cfg = ConfigParser.RawConfigParser() + with open(args.config, "r") as f: + cfg.readfp(f) + section = args.section or cfg.get("default", "default") + cores = cfg.get(section, "cores") + except (IOError, ConfigParser.MissingSectionHeaderError,ConfigParser.NoSectionError, configparser.NoOptionError) as e: + exit(str(e)) + + cores = re.split(r",\s*", cores) + + cores = [Core.new(core) for core in ["board_regs", "comm_regs"] + cores] + core_number = 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)) + core_number = core.assign_core_number(core_number) + + with open(args.outfile, "w") as f: + f.write(createModule_template.format( + addrs = "".join(core.createAddr() for core in cores), + insts = "".join(core.createInstance() for core in cores), + muxes = "".join(core.createMux() for core in cores))) + + +class Core(object): + + _instance_count = {} + special_class = {} + + def __init__(self, name): + self.name = name + self.core_number = None + self.instance_number = self._instance_count.get(name, 0) + self._instance_count[name] = self.instance_number + 1 + + @classmethod + def new(cls, name): + return cls.special_class.get(name, cls)(name) + + def assign_core_number(self, n): + self.core_number = n + return n + 1 + + @property + def instance_name(self): + if self._instance_count[self.name] > 1: + return "{}_{}".format(self.name, self.instance_number) + else: + return self.name + + @property + def upper_instance_name(self): + return self.instance_name.upper() + + @property + def createInstance_template(self): + return createInstance_template_generic + + def createInstance(self): + return self.createInstance_template.format(core = self) + + def createAddr(self): + return createAddr_template.format(core = self) + + def createMux(self): + return createMux_template.format(core = self, core0 = self) + + +class SubCore(Core): + + def __init__(self, name, parent): + super(SubCore, self).__init__(name) + self.parent = parent + + def createMux(self): + return createMux_template.format(core = self, core0 = self.parent) + + +class TRNGCore(Core): + + def __init__(self, name): + super(TRNGCore, self).__init__(name) + self.subcores = tuple(SubCore(name, self) for name in ("avalanche_entropy", "rosc_entropy", "trng_mixer", "trng_csprng")) + + def assign_core_number(self, n): + n = super(TRNGCore, self).assign_core_number(n) + for subcore in self.subcores: + n = subcore.assign_core_number(n) + return n + + @property + def createInstance_template(self): + return createInstance_template_TRNG + + def createAddr(self): + return super(TRNGCore, self).createAddr() + "".join(subcore.createAddr() for subcore in self.subcores) + + def createMux(self): + return super(TRNGCore, self).createMux() + "".join(subcore.createMux() for subcore in self.subcores) + +Core.special_class["trng"] = TRNGCore + + +createAddr_template = """\ + localparam CORE_ADDR_{core.upper_instance_name:21s} = 9'h{core.core_number:02x}; +""" + +createInstance_template_generic = """\ + //---------------------------------------------------------------- + // {core.upper_instance_name} + //---------------------------------------------------------------- + wire enable_{core.instance_name} = (addr_core_num == CORE_ADDR_{core.upper_instance_name}); + wire [31: 0] read_data_{core.instance_name}; + wire error_{core.instance_name}; + + {core.name} {core.instance_name}_inst + ( + .clk(sys_clk), + .reset_n(~sys_rst), + + .cs(enable_{core.instance_name} & (sys_eim_rd | sys_eim_wr)), + .we(sys_eim_wr), + + .address(addr_core_reg), + .write_data(sys_write_data), + .read_data(read_data_{core.instance_name}) + ); + + +""" + +createInstance_template_TRNG = """\ + //---------------------------------------------------------------- + // {core.upper_instance_name} + //---------------------------------------------------------------- + wire enable_{core.instance_name} = (addr_core_num >= CORE_ADDR_TRNG) && (addr_core_num <= CORE_ADDR_TRNG_CSPRNG); + wire [31: 0] read_data_{core.instance_name}; + wire error_{core.instance_name}; + wire [3:0] trng_prefix = addr_core_num[3:0] - CORE_ADDR_TRNG; + + {core.name} {core.instance_name}_inst + ( + .clk(sys_clk), + .reset_n(~sys_rst), + + .cs(enable_{core.instance_name} & (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_{core.instance_name}), + + .avalanche_noise(noise), + .debug(debug) + ); + + +""" + +createMux_template = """\ + CORE_ADDR_{core.upper_instance_name}: + begin + sys_read_data_mux = read_data_{core0.instance_name}; + sys_error_mux = error_{core0.instance_name}; + end +""" + +createModule_template = """\ +// 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 + //---------------------------------------------------------------- +{addrs} + +{insts} + //---------------------------------------------------------------- + // 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) +{muxes} + default: + begin + sys_read_data_mux = {{32{{1'b0}}}}; + sys_error_mux = 1; + end + endcase + + +endmodule + + +//====================================================================== +// EOF core_selector.v +//====================================================================== +""" # main -cmdParse() -if not cores: - cores = configParse(section) -createModule(cores) + + +if __name__ == "__main__": + main() -- cgit v1.2.3 From 0ddd4002f9cf59e72a6f2ec1645c2b4569b3ebc3 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Thu, 24 Sep 2015 23:16:50 -0400 Subject: Git rid of commas in config language, add some comments. --- config/config.cfg | 6 +-- config/config.py | 117 +++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 83 insertions(+), 40 deletions(-) diff --git a/config/config.cfg b/config/config.cfg index 360988e..65659f7 100644 --- a/config/config.cfg +++ b/config/config.cfg @@ -4,7 +4,7 @@ default = rsa [hash-only] -cores = sha1, sha256, sha512 +cores = sha1 sha256 sha512 [trng-only] cores = trng @@ -13,7 +13,7 @@ cores = trng cores = modexp [rsa] -cores = sha256, aes, trng, modexp +cores = sha256 aes trng modexp [multi-test] -cores = sha256, aes, aes, chacha, aes +cores = sha256 aes aes chacha aes diff --git a/config/config.py b/config/config.py index 29179e4..74a9007 100755 --- a/config/config.py +++ b/config/config.py @@ -1,48 +1,67 @@ #!/usr/bin/env python -# -# Generate core_selector.v for a set of cores - -import argparse -import re -import ConfigParser +""" +Generate core_selector.v for a set of cores. +""" def main(): - parser = argparse.ArgumentParser() - parser.add_argument("--cores", help = "comma-delimited list of cores") - parser.add_argument("-c", "--config", default = "config.cfg", help = "config file") + """ + Parse arguments and config file, generate core list, generate output. + """ + + from argparse import ArgumentParser, FileType, ArgumentDefaultsHelpFormatter + from ConfigParser import RawConfigParser + from sys import exit + + parser = ArgumentParser(description = __doc__, formatter_class = ArgumentDefaultsHelpFormatter) + parser.add_argument("-c", "--config", help = "config file", default = "config.cfg", type = FileType("r")) + parser.add_argument("-d", "--debug", help = "enable debugging", action = "store_true") + parser.add_argument("-o", "--outfile", help = "output file", default = "core_selector.v", type = FileType("w")) parser.add_argument("-s", "--section", help = "config file section") - parser.add_argument("-o", "--outfile", default = "core_selector.v", help = "output file") + parser.add_argument("core", help = "name(s) of core(s)", nargs = "*") args = parser.parse_args() - cores = args.cores - - if not cores: - try: - cfg = ConfigParser.RawConfigParser() - with open(args.config, "r") as f: - cfg.readfp(f) + try: + if args.core: + cores = args.core + else: + cfg = RawConfigParser() + cfg.readfp(args.config) section = args.section or cfg.get("default", "default") - cores = cfg.get(section, "cores") - except (IOError, ConfigParser.MissingSectionHeaderError,ConfigParser.NoSectionError, configparser.NoOptionError) as e: - exit(str(e)) + cores = cfg.get(section, "cores").split() - cores = re.split(r",\s*", cores) + cores.insert(0, "board_regs") + cores.insert(1, "comm_regs") - cores = [Core.new(core) for core in ["board_regs", "comm_regs"] + cores] - core_number = 0 - for core in cores: - core_number = core.assign_core_number(core_number) + cores = [Core.new(core) for core in cores] + core_number = 0 + for core in cores: + core_number = core.assign_core_number(core_number) - with open(args.outfile, "w") as f: - f.write(createModule_template.format( + args.outfile.write(createModule_template.format( addrs = "".join(core.createAddr() for core in cores), insts = "".join(core.createInstance() for core in cores), muxes = "".join(core.createMux() for core in cores))) + except Exception, e: + if args.debug: + raise + exit(str(e)) + class Core(object): + """ + Data and methods for a generic core. We can use this directly for + most cores, a few are weird and require subclassing to override + particular methods. + """ + + # Class variable tracking how many times a particular core has + # been instantiated. This controls instance numbering. _instance_count = {} + + # Map from core name to subclass for the special case cores. + special_class = {} def __init__(self, name): @@ -70,12 +89,8 @@ class Core(object): def upper_instance_name(self): return self.instance_name.upper() - @property - def createInstance_template(self): - return createInstance_template_generic - def createInstance(self): - return self.createInstance_template.format(core = self) + return createInstance_template_generic.format(core = self) def createAddr(self): return createAddr_template.format(core = self) @@ -85,6 +100,9 @@ class Core(object): class SubCore(Core): + """" + Override mux handling for TRNG's sub-cores. + """ def __init__(self, name, parent): super(SubCore, self).__init__(name) @@ -95,6 +113,12 @@ class SubCore(Core): class TRNGCore(Core): + """ + The TRNG core has an internal mux and a collection of sub-cores. + Mostly this means that our method calls have to iterate over all + of the subcores after handling the base TRNG core, but we also use + a different instance template in the hope that it is easier to read. + """ def __init__(self, name): super(TRNGCore, self).__init__(name) @@ -106,9 +130,8 @@ class TRNGCore(Core): n = subcore.assign_core_number(n) return n - @property - def createInstance_template(self): - return createInstance_template_TRNG + def createInstance(self): + return createInstance_template_TRNG.format(core = self) def createAddr(self): return super(TRNGCore, self).createAddr() + "".join(subcore.createAddr() for subcore in self.subcores) @@ -116,13 +139,26 @@ class TRNGCore(Core): def createMux(self): return super(TRNGCore, self).createMux() + "".join(subcore.createMux() for subcore in self.subcores) +# Hook TRNGCore in as the handler for "trng" core instances. + Core.special_class["trng"] = TRNGCore +# Add other special cases here as needed. + + +# Templates (format strings), here instead of inline in the functions +# that use them, both because some of these are shared between +# multiple functions and because it's easier to read these (and get +# the indentation right) when the're separate. + +# Template used by .createAddr() methods. createAddr_template = """\ localparam CORE_ADDR_{core.upper_instance_name:21s} = 9'h{core.core_number:02x}; """ +# Template used by Core.createInstance(). + createInstance_template_generic = """\ //---------------------------------------------------------------- // {core.upper_instance_name} @@ -147,6 +183,10 @@ createInstance_template_generic = """\ """ +# Template used by TRNGCore.createInstance(); this is different enough +# from the generic template that it's (probably) clearer to have this +# separate. + createInstance_template_TRNG = """\ //---------------------------------------------------------------- // {core.upper_instance_name} @@ -175,6 +215,8 @@ createInstance_template_TRNG = """\ """ +# Template for .createMux() methods. + createMux_template = """\ CORE_ADDR_{core.upper_instance_name}: begin @@ -183,6 +225,8 @@ createMux_template = """\ end """ +# Top-level (createModule) template. + createModule_template = """\ // NOTE: This file is generated; do not edit by hand. @@ -246,8 +290,7 @@ endmodule //====================================================================== """ -# main - +# Run main program. if __name__ == "__main__": main() -- cgit v1.2.3 From fbaa09c3192dcbe21da694b1a35eead58f10e761 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Fri, 25 Sep 2015 14:10:47 -0400 Subject: Configure makefile vfiles list too. --- config/config.cfg | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++- config/config.py | 38 +++++++++++++++++------ eim/build/Makefile | 88 ++++++++++++++++------------------------------------ 3 files changed, 145 insertions(+), 72 deletions(-) diff --git a/config/config.cfg b/config/config.cfg index 65659f7..8749b55 100644 --- a/config/config.cfg +++ b/config/config.cfg @@ -1,7 +1,19 @@ # Config file for the Cryptech Novena FPGA framework. +# +# At present, there are three kinds of variables in this file. +# +# default-section: Name of the configuration to build if the user +# doesn't specify one. Only meaningful in the default section. +# +# cores: A list of cores to build. Use with the --section option. +# +# vfiles: A list of Verilog files to include in the vfiles list when +# including a particular core. All (optional) cores must have a +# vfiles option, so that the configuration program knows what to put +# into core_vfiles.mk. [default] -default = rsa +default-section = rsa [hash-only] cores = sha1 sha256 sha512 @@ -17,3 +29,80 @@ cores = sha256 aes trng modexp [multi-test] cores = sha256 aes aes chacha aes + +[sha1] +vfiles = + hash/sha1/src/rtl/sha1.v + hash/sha1/src/rtl/sha1_core.v + hash/sha1/src/rtl/sha1_w_mem.v + +[sha256] +vfiles = + hash/sha256/src/rtl/sha256.v + hash/sha256/src/rtl/sha256_core.v + hash/sha256/src/rtl/sha256_k_constants.v + hash/sha256/src/rtl/sha256_w_mem.v + +[sha512] +vfiles = + hash/sha512/src/rtl/sha512.v + hash/sha512/src/rtl/sha512_core.v + hash/sha512/src/rtl/sha512_h_constants.v + hash/sha512/src/rtl/sha512_k_constants.v + hash/sha512/src/rtl/sha512_w_mem.v + +[trng] +vfiles = + rng/avalanche_entropy/src/rtl/avalanche_entropy.v + rng/avalanche_entropy/src/rtl/avalanche_entropy_core.v + rng/rosc_entropy/src/rtl/rosc.v + rng/rosc_entropy/src/rtl/rosc_entropy.v + rng/rosc_entropy/src/rtl/rosc_entropy_core.v + rng/trng/src/rtl/trng.v + rng/trng/src/rtl/trng_csprng.v + rng/trng/src/rtl/trng_csprng_fifo.v + rng/trng/src/rtl/trng_mixer.v + +[aes] +vfiles = + cipher/aes/src/rtl/aes.v + cipher/aes/src/rtl/aes_core.v + cipher/aes/src/rtl/aes_decipher_block.v + cipher/aes/src/rtl/aes_encipher_block.v + cipher/aes/src/rtl/aes_inv_sbox.v + cipher/aes/src/rtl/aes_key_mem.v + cipher/aes/src/rtl/aes_sbox.v + +[chacha] +vfiles = + cipher/chacha/src/rtl/chacha.v + cipher/chacha/src/rtl/chacha_core.v + cipher/chacha/src/rtl/chacha_qr.v + +[modexps6] +vfiles = + math/modexps6/src/rtl/modexps6_adder64_carry32.v + math/modexps6/src/rtl/modexps6_buffer_core.v + math/modexps6/src/rtl/modexps6_buffer_user.v + math/modexps6/src/rtl/modexps6_modinv32.v + math/modexps6/src/rtl/modexps6_montgomery_coeff.v + math/modexps6/src/rtl/modexps6_montgomery_multiplier.v + math/modexps6/src/rtl/modexps6_top.v + math/modexps6/src/rtl/modexps6_wrapper.v + math/modexps6/src/rtl/ram_1rw_1ro_readfirst.v + math/modexps6/src/rtl/ipcore/multiplier_s6.v + math/modexps6/src/rtl/ipcore/subtractor_s6.v + +[modexp] +vfiles = + math/modexp/src/rtl/adder32.v + math/modexp/src/rtl/blockmem1r1w.v + math/modexp/src/rtl/blockmem2r1wptr.v + math/modexp/src/rtl/blockmem2r1w.v + math/modexp/src/rtl/blockmem2rptr1w.v + math/modexp/src/rtl/modexp.v + math/modexp/src/rtl/modexp_core.v + math/modexp/src/rtl/montprod.v + math/modexp/src/rtl/residue.v + math/modexp/src/rtl/shl32.v + math/modexp/src/rtl/shr32.v diff --git a/config/config.py b/config/config.py index 74a9007..6a5e532 100755 --- a/config/config.py +++ b/config/config.py @@ -13,34 +13,41 @@ def main(): from sys import exit parser = ArgumentParser(description = __doc__, formatter_class = ArgumentDefaultsHelpFormatter) - parser.add_argument("-c", "--config", help = "config file", default = "config.cfg", type = FileType("r")) parser.add_argument("-d", "--debug", help = "enable debugging", action = "store_true") - parser.add_argument("-o", "--outfile", help = "output file", default = "core_selector.v", type = FileType("w")) parser.add_argument("-s", "--section", help = "config file section") + parser.add_argument("-c", "--config", help = "configuration file", default = "config.cfg", type = FileType("r")) + parser.add_argument("--verilog", help = "verilog output file", default = "core_selector.v", type = FileType("w")) + parser.add_argument("--makefile", help = "output makefile", default = "core_vfiles.mk", type = FileType("w")) parser.add_argument("core", help = "name(s) of core(s)", nargs = "*") args = parser.parse_args() try: + cfg = RawConfigParser() + cfg.readfp(args.config) + if args.core: cores = args.core else: - cfg = RawConfigParser() - cfg.readfp(args.config) - section = args.section or cfg.get("default", "default") + section = args.section or cfg.get("default", "default-section") cores = cfg.get(section, "cores").split() cores.insert(0, "board_regs") cores.insert(1, "comm_regs") - cores = [Core.new(core) for core in cores] + cores = tuple(Core.new(core) for core in cores) core_number = 0 for core in cores: core_number = core.assign_core_number(core_number) + for core in cores[2:]: + core.add_vfiles(cfg) - args.outfile.write(createModule_template.format( - addrs = "".join(core.createAddr() for core in cores), + args.verilog.write(createModule_template.format( + addrs = "".join(core.createAddr() for core in cores), insts = "".join(core.createInstance() for core in cores), - muxes = "".join(core.createMux() for core in cores))) + muxes = "".join(core.createMux() for core in cores))) + + args.makefile.write(listVfiles_template.format( + vfiles = "".join(core.listVfiles() for core in cores))) except Exception, e: if args.debug: @@ -67,6 +74,7 @@ class Core(object): def __init__(self, name): self.name = name self.core_number = None + self.vfiles = () self.instance_number = self._instance_count.get(name, 0) self._instance_count[name] = self.instance_number + 1 @@ -78,6 +86,10 @@ class Core(object): self.core_number = n return n + 1 + def add_vfiles(self, cfg): + if self.instance_number == 0: + self.vfiles = cfg.get(self.name, "vfiles").split() + @property def instance_name(self): if self._instance_count[self.name] > 1: @@ -98,6 +110,8 @@ class Core(object): def createMux(self): return createMux_template.format(core = self, core0 = self) + def listVfiles(self): + return "".join(" \\\n\t$(core_tree)/" + vfile for vfile in self.vfiles) class SubCore(Core): """" @@ -290,6 +304,12 @@ endmodule //====================================================================== """ +# Template for makefile snippet listing Verilog source files. + +listVfiles_template = """\ +vfiles +={vfiles} +""" + # Run main program. if __name__ == "__main__": diff --git a/eim/build/Makefile b/eim/build/Makefile index badda45..baefa7f 100644 --- a/eim/build/Makefile +++ b/eim/build/Makefile @@ -1,67 +1,31 @@ -project = novena_eim -vendor = xilinx -family = spartan6 -part = xc6slx45csg324-3 -top_module = novena_top -isedir = /opt/Xilinx/14.7/ISE_DS -xil_env = . $(isedir)/settings64.sh -ucf = ../ucf/novena_eim.ucf +core_tree := $(abspath ../../../..) + +word_size := $(shell python -c 'from struct import pack; print len(pack("L", 0)) * 8') + +project = novena_eim +vendor = xilinx +family = spartan6 +part = xc6slx45csg324-3 +top_module = novena_top +isedir = /opt/Xilinx/14.7/ISE_DS +xil_env = . $(isedir)/settings$(word_size).sh +ucf = ../ucf/novena_eim.ucf vfiles = \ - ../rtl/novena_eim.v \ - ../../common/rtl/novena_regs.v \ - ../../common/rtl/novena_clkmgr.v \ - ../../common/rtl/ipcore/clkmgr_dcm.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 \ - ../../../../comm/eim/src/rtl/eim_da_phy.v \ - ../../../../comm/eim/src/rtl/eim_indicator.v \ - ../../../../comm/eim/src/rtl/eim_regs.v \ - ../../../../comm/eim/src/rtl/eim.v \ - ../../../../hash/sha1/src/rtl/sha1.v \ - ../../../../hash/sha1/src/rtl/sha1_core.v \ - ../../../../hash/sha1/src/rtl/sha1_w_mem.v \ - ../../../../hash/sha256/src/rtl/sha256.v \ - ../../../../hash/sha256/src/rtl/sha256_core.v \ - ../../../../hash/sha256/src/rtl/sha256_k_constants.v \ - ../../../../hash/sha256/src/rtl/sha256_w_mem.v \ - ../../../../hash/sha512/src/rtl/sha512.v \ - ../../../../hash/sha512/src/rtl/sha512_core.v \ - ../../../../hash/sha512/src/rtl/sha512_h_constants.v \ - ../../../../hash/sha512/src/rtl/sha512_k_constants.v \ - ../../../../hash/sha512/src/rtl/sha512_w_mem.v \ - ../../../../rng/avalanche_entropy/src/rtl/avalanche_entropy.v \ - ../../../../rng/avalanche_entropy/src/rtl/avalanche_entropy_core.v \ - ../../../../rng/rosc_entropy/src/rtl/rosc.v \ - ../../../../rng/rosc_entropy/src/rtl/rosc_entropy.v \ - ../../../../rng/rosc_entropy/src/rtl/rosc_entropy_core.v \ - ../../../../rng/trng/src/rtl/trng.v \ - ../../../../rng/trng/src/rtl/trng_csprng.v \ - ../../../../rng/trng/src/rtl/trng_csprng_fifo.v \ - ../../../../rng/trng/src/rtl/trng_mixer.v \ - ../../../../cipher/aes/src/rtl/aes.v \ - ../../../../cipher/aes/src/rtl/aes_core.v \ - ../../../../cipher/aes/src/rtl/aes_decipher_block.v \ - ../../../../cipher/aes/src/rtl/aes_encipher_block.v \ - ../../../../cipher/aes/src/rtl/aes_inv_sbox.v \ - ../../../../cipher/aes/src/rtl/aes_key_mem.v \ - ../../../../cipher/aes/src/rtl/aes_sbox.v \ - ../../../../cipher/chacha/src/rtl/chacha.v \ - ../../../../cipher/chacha/src/rtl/chacha_core.v \ - ../../../../cipher/chacha/src/rtl/chacha_qr.v \ - ../../../../math/modexps6/src/rtl/modexps6_adder64_carry32.v \ - ../../../../math/modexps6/src/rtl/modexps6_buffer_core.v \ - ../../../../math/modexps6/src/rtl/modexps6_buffer_user.v \ - ../../../../math/modexps6/src/rtl/modexps6_modinv32.v \ - ../../../../math/modexps6/src/rtl/modexps6_montgomery_coeff.v \ - ../../../../math/modexps6/src/rtl/modexps6_montgomery_multiplier.v \ - ../../../../math/modexps6/src/rtl/modexps6_top.v \ - ../../../../math/modexps6/src/rtl/modexps6_wrapper.v \ - ../../../../math/modexps6/src/rtl/ram_1rw_1ro_readfirst.v \ - ../../../../math/modexps6/src/rtl/ipcore/multiplier_s6.v \ - ../../../../math/modexps6/src/rtl/ipcore/subtractor_s6.v + $(core_tree)/platform/novena/eim/rtl/novena_eim.v \ + $(core_tree)/platform/novena/common/rtl/novena_regs.v \ + $(core_tree)/platform/novena/common/rtl/novena_clkmgr.v \ + $(core_tree)/platform/novena/common/rtl/ipcore/clkmgr_dcm.v \ + $(core_tree)/platform/novena/config/core_selector.v \ + $(core_tree)/comm/eim/src/rtl/cdc_bus_pulse.v \ + $(core_tree)/comm/eim/src/rtl/eim_arbiter_cdc.v \ + $(core_tree)/comm/eim/src/rtl/eim_arbiter.v \ + $(core_tree)/comm/eim/src/rtl/eim_da_phy.v \ + $(core_tree)/comm/eim/src/rtl/eim_indicator.v \ + $(core_tree)/comm/eim/src/rtl/eim_regs.v \ + $(core_tree)/comm/eim/src/rtl/eim.v + +include $(core_tree)/platform/novena/config/core_vfiles.mk include xilinx.mk -- cgit v1.2.3 From 44626ff57b30a5db18766022430199c7eec8cbd6 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Fri, 25 Sep 2015 18:18:30 -0400 Subject: Track filename changes to modexp core that took place ages ago. --- config/config.cfg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/config.cfg b/config/config.cfg index 8749b55..5f3cf21 100644 --- a/config/config.cfg +++ b/config/config.cfg @@ -95,7 +95,7 @@ vfiles = [modexp] vfiles = - math/modexp/src/rtl/adder32.v + math/modexp/src/rtl/adder.v math/modexp/src/rtl/blockmem1r1w.v math/modexp/src/rtl/blockmem2r1wptr.v math/modexp/src/rtl/blockmem2r1w.v @@ -104,5 +104,5 @@ vfiles = math/modexp/src/rtl/modexp_core.v math/modexp/src/rtl/montprod.v math/modexp/src/rtl/residue.v - math/modexp/src/rtl/shl32.v - math/modexp/src/rtl/shr32.v + math/modexp/src/rtl/shl.v + math/modexp/src/rtl/shr.v -- cgit v1.2.3 From 9c67b22956ad8f49e71a4caef20eb246feb81ce1 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Fri, 25 Sep 2015 18:18:54 -0400 Subject: Incomplete attempt to track changes to core_selector architecture. The board_regs and comm_regs cores handle reset differently, but there's also this sys_ena wire which appeared out of the ether one day and is not yet in this movie. This version does NOT synthesize (nor did the previous ones, but now we know it...). --- config/config.py | 53 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/config/config.py b/config/config.py index 6a5e532..65c540f 100755 --- a/config/config.py +++ b/config/config.py @@ -126,6 +126,16 @@ class SubCore(Core): return createMux_template.format(core = self, core0 = self.parent) +class BoardCore(Core): + """ + Board-level cores have a slightly different API, which we handle + with a different template. + """ + + def createInstance(self): + return createInstance_template_board.format(core = self) + + class TRNGCore(Core): """ The TRNG core has an internal mux and a collection of sub-cores. @@ -153,11 +163,12 @@ class TRNGCore(Core): def createMux(self): return super(TRNGCore, self).createMux() + "".join(subcore.createMux() for subcore in self.subcores) -# Hook TRNGCore in as the handler for "trng" core instances. +# Hook special classes in as handlers for the cores that require them -Core.special_class["trng"] = TRNGCore - -# Add other special cases here as needed. +Core.special_class.update( + board_regs = BoardCore, + comm_regs = BoardCore, + trng = TRNGCore) # Templates (format strings), here instead of inline in the functions @@ -177,7 +188,7 @@ createInstance_template_generic = """\ //---------------------------------------------------------------- // {core.upper_instance_name} //---------------------------------------------------------------- - wire enable_{core.instance_name} = (addr_core_num == CORE_ADDR_{core.upper_instance_name}); + wire enable_{core.instance_name} = sys_ena && (addr_core_num == CORE_ADDR_{core.upper_instance_name}); wire [31: 0] read_data_{core.instance_name}; wire error_{core.instance_name}; @@ -195,11 +206,43 @@ createInstance_template_generic = """\ ); +""" + +# Template used by BoardCore.createInstance(). This has minor +# differences from the generic template, maybe we can merge them, or +# maybe we can do something about the (gratuitous?) differences that +# make this necessary. + +createInstance_template_board = """\ + //---------------------------------------------------------------- + // {core.upper_instance_name} + //---------------------------------------------------------------- + wire enable_{core.instance_name} = sys_ena && (addr_core_num == CORE_ADDR_{core.upper_instance_name}); + wire [31: 0] read_data_{core.instance_name}; + wire error_{core.instance_name}; + + {core.name} {core.instance_name}_inst + ( + .clk(sys_clk), + .rst(sys_rst), + + .cs(enable_{core.instance_name} & (sys_eim_rd | sys_eim_wr)), + .we(sys_eim_wr), + + .address(addr_core_reg), + .write_data(sys_write_data), + .read_data(read_data_{core.instance_name}), + .error(error_{core.instance_name}) + ); + + """ # Template used by TRNGCore.createInstance(); this is different enough # from the generic template that it's (probably) clearer to have this # separate. +# +# Should this also be checking sys_ena? Not obvious to me either way. createInstance_template_TRNG = """\ //---------------------------------------------------------------- -- cgit v1.2.3 From d3a2b477d0411b006b7f16256d0b2765ea765a83 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Fri, 25 Sep 2015 18:45:35 -0400 Subject: Minor cleanup. --- config/config.py | 27 +++++++++++++++------------ eim/build/Makefile | 25 ++++++++++++++++++++----- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/config/config.py b/config/config.py index 65c540f..ddf7d0b 100755 --- a/config/config.py +++ b/config/config.py @@ -111,7 +111,18 @@ class Core(object): return createMux_template.format(core = self, core0 = self) def listVfiles(self): - return "".join(" \\\n\t$(core_tree)/" + vfile for vfile in self.vfiles) + return "".join(" \\\n\t$(CORE_TREE)/" + vfile for vfile in self.vfiles) + + +class BoardCore(Core): + """ + Board-level cores have a slightly different API, which we handle + with a different template, at least for now. + """ + + def createInstance(self): + return createInstance_template_board.format(core = self) + class SubCore(Core): """" @@ -126,16 +137,6 @@ class SubCore(Core): return createMux_template.format(core = self, core0 = self.parent) -class BoardCore(Core): - """ - Board-level cores have a slightly different API, which we handle - with a different template. - """ - - def createInstance(self): - return createInstance_template_board.format(core = self) - - class TRNGCore(Core): """ The TRNG core has an internal mux and a collection of sub-cores. @@ -144,9 +145,11 @@ class TRNGCore(Core): a different instance template in the hope that it is easier to read. """ + subcore_names = ("avalanche_entropy", "rosc_entropy", "trng_mixer", "trng_csprng") + def __init__(self, name): super(TRNGCore, self).__init__(name) - self.subcores = tuple(SubCore(name, self) for name in ("avalanche_entropy", "rosc_entropy", "trng_mixer", "trng_csprng")) + self.subcores = tuple(SubCore(name, self) for name in self.subcore_names) def assign_core_number(self, n): n = super(TRNGCore, self).assign_core_number(n) diff --git a/eim/build/Makefile b/eim/build/Makefile index baefa7f..00d8604 100644 --- a/eim/build/Makefile +++ b/eim/build/Makefile @@ -1,6 +1,13 @@ -core_tree := $(abspath ../../../..) +# Localize all the relative path awfulness in one variable. -word_size := $(shell python -c 'from struct import pack; print len(pack("L", 0)) * 8') +CORE_TREE := $(abspath ../../../..) + +# Figure out what the native word size is on the build host, because +# the XiLinx tools care for some reason. + +WORD_SIZE := $(shell python -c 'from struct import pack; print len(pack("L", 0)) * 8') + +# Parameters to xilinkx.mk. project = novena_eim vendor = xilinx @@ -8,8 +15,10 @@ family = spartan6 part = xc6slx45csg324-3 top_module = novena_top isedir = /opt/Xilinx/14.7/ISE_DS -xil_env = . $(isedir)/settings$(word_size).sh -ucf = ../ucf/novena_eim.ucf +xil_env = . $(isedir)/settings$(WORD_SIZE).sh +ucf = ../ucf/$(project).ucf + +# Verilog files that always go with builds on this platform. vfiles = \ $(core_tree)/platform/novena/eim/rtl/novena_eim.v \ @@ -25,9 +34,15 @@ vfiles = \ $(core_tree)/comm/eim/src/rtl/eim_regs.v \ $(core_tree)/comm/eim/src/rtl/eim.v +# Verilog files selected by the core configuration script. + include $(core_tree)/platform/novena/config/core_vfiles.mk include xilinx.mk +# Fun extras for running verlator as a linter. + +VERILATOR_FLAGS = --lint-only --top-module novena_top -Wall -Wno-fatal -Wno-DECLFILENAME + lint: - verilator --lint-only --top-module novena_top -Wall -Wno-fatal -Wno-DECLFILENAME $(vfiles) ../../common/rtl/lint-dummy.v + verilator ${VERILATOR_FLAGS} $(vfiles) $(core_tree)/platform/novena/common/rtl/lint-dummy.v -- cgit v1.2.3 From f43b493bcc7dfe1d6b49faad6dc32c8948573e29 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Fri, 25 Sep 2015 18:57:21 -0400 Subject: Previous commit was incomplete. --- eim/build/Makefile | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/eim/build/Makefile b/eim/build/Makefile index 00d8604..630faa9 100644 --- a/eim/build/Makefile +++ b/eim/build/Makefile @@ -21,22 +21,22 @@ ucf = ../ucf/$(project).ucf # Verilog files that always go with builds on this platform. vfiles = \ - $(core_tree)/platform/novena/eim/rtl/novena_eim.v \ - $(core_tree)/platform/novena/common/rtl/novena_regs.v \ - $(core_tree)/platform/novena/common/rtl/novena_clkmgr.v \ - $(core_tree)/platform/novena/common/rtl/ipcore/clkmgr_dcm.v \ - $(core_tree)/platform/novena/config/core_selector.v \ - $(core_tree)/comm/eim/src/rtl/cdc_bus_pulse.v \ - $(core_tree)/comm/eim/src/rtl/eim_arbiter_cdc.v \ - $(core_tree)/comm/eim/src/rtl/eim_arbiter.v \ - $(core_tree)/comm/eim/src/rtl/eim_da_phy.v \ - $(core_tree)/comm/eim/src/rtl/eim_indicator.v \ - $(core_tree)/comm/eim/src/rtl/eim_regs.v \ - $(core_tree)/comm/eim/src/rtl/eim.v + $(CORE_TREE)/platform/novena/eim/rtl/novena_eim.v \ + $(CORE_TREE)/platform/novena/common/rtl/novena_regs.v \ + $(CORE_TREE)/platform/novena/common/rtl/novena_clkmgr.v \ + $(CORE_TREE)/platform/novena/common/rtl/ipcore/clkmgr_dcm.v \ + $(CORE_TREE)/platform/novena/config/core_selector.v \ + $(CORE_TREE)/comm/eim/src/rtl/cdc_bus_pulse.v \ + $(CORE_TREE)/comm/eim/src/rtl/eim_arbiter_cdc.v \ + $(CORE_TREE)/comm/eim/src/rtl/eim_arbiter.v \ + $(CORE_TREE)/comm/eim/src/rtl/eim_da_phy.v \ + $(CORE_TREE)/comm/eim/src/rtl/eim_indicator.v \ + $(CORE_TREE)/comm/eim/src/rtl/eim_regs.v \ + $(CORE_TREE)/comm/eim/src/rtl/eim.v # Verilog files selected by the core configuration script. -include $(core_tree)/platform/novena/config/core_vfiles.mk +-include $(CORE_TREE)/platform/novena/config/core_vfiles.mk include xilinx.mk @@ -45,4 +45,4 @@ include xilinx.mk VERILATOR_FLAGS = --lint-only --top-module novena_top -Wall -Wno-fatal -Wno-DECLFILENAME lint: - verilator ${VERILATOR_FLAGS} $(vfiles) $(core_tree)/platform/novena/common/rtl/lint-dummy.v + verilator ${VERILATOR_FLAGS} $(vfiles) $(CORE_TREE)/platform/novena/common/rtl/lint-dummy.v -- cgit v1.2.3 From 19e4044fcf47360dcc5aa68f6eae5a62a6cdb61b Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Sat, 26 Sep 2015 13:21:01 -0400 Subject: Sorted out reset pins (I think). Seems our various core authors have different opinions about whether reset should be high or low, and the core selector code is responsible for making this right. Hmm. Address map may still be wrong, as addressing scheme seems to have changed while the core_select branch was gathering dust. --- config/config.py | 69 ++++++++++++++++++-------------------------------- config/core_selector.v | 4 +-- config/core_vfiles.mk | 34 +++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 47 deletions(-) create mode 100644 config/core_vfiles.mk diff --git a/config/config.py b/config/config.py index ddf7d0b..970b339 100755 --- a/config/config.py +++ b/config/config.py @@ -101,6 +101,10 @@ class Core(object): def upper_instance_name(self): return self.instance_name.upper() + @property + def reset_pin(self): + return ".rst(sys_rst)" + def createInstance(self): return createInstance_template_generic.format(core = self) @@ -114,14 +118,15 @@ class Core(object): return "".join(" \\\n\t$(CORE_TREE)/" + vfile for vfile in self.vfiles) -class BoardCore(Core): +class InvertedResetCore(Core): """ - Board-level cores have a slightly different API, which we handle - with a different template, at least for now. + Core which inverts the reset signal. Seems to vary by author. + No, I don't know why we don't just pick one convention or the other. """ - def createInstance(self): - return createInstance_template_board.format(core = self) + @property + def reset_pin(self): + return ".reset_n(~sys_rst)" class SubCore(Core): @@ -137,7 +142,7 @@ class SubCore(Core): return createMux_template.format(core = self, core0 = self.parent) -class TRNGCore(Core): +class TRNGCore(InvertedResetCore): """ The TRNG core has an internal mux and a collection of sub-cores. Mostly this means that our method calls have to iterate over all @@ -166,12 +171,16 @@ class TRNGCore(Core): def createMux(self): return super(TRNGCore, self).createMux() + "".join(subcore.createMux() for subcore in self.subcores) -# Hook special classes in as handlers for the cores that require them +# Hook special classes in as handlers for the cores that require them. Core.special_class.update( - board_regs = BoardCore, - comm_regs = BoardCore, - trng = TRNGCore) + trng = TRNGCore, + aes = InvertedResetCore, + chacha = InvertedResetCore, + sha1 = InvertedResetCore, + sha256 = InvertedResetCore, + sha512 = InvertedResetCore, + modexp = InvertedResetCore) # Templates (format strings), here instead of inline in the functions @@ -191,14 +200,14 @@ createInstance_template_generic = """\ //---------------------------------------------------------------- // {core.upper_instance_name} //---------------------------------------------------------------- - wire enable_{core.instance_name} = sys_ena && (addr_core_num == CORE_ADDR_{core.upper_instance_name}); + wire enable_{core.instance_name} = (addr_core_num == CORE_ADDR_{core.upper_instance_name}); wire [31: 0] read_data_{core.instance_name}; wire error_{core.instance_name}; {core.name} {core.instance_name}_inst ( .clk(sys_clk), - .reset_n(~sys_rst), + {core.reset_pin}, .cs(enable_{core.instance_name} & (sys_eim_rd | sys_eim_wr)), .we(sys_eim_wr), @@ -209,43 +218,11 @@ createInstance_template_generic = """\ ); -""" - -# Template used by BoardCore.createInstance(). This has minor -# differences from the generic template, maybe we can merge them, or -# maybe we can do something about the (gratuitous?) differences that -# make this necessary. - -createInstance_template_board = """\ - //---------------------------------------------------------------- - // {core.upper_instance_name} - //---------------------------------------------------------------- - wire enable_{core.instance_name} = sys_ena && (addr_core_num == CORE_ADDR_{core.upper_instance_name}); - wire [31: 0] read_data_{core.instance_name}; - wire error_{core.instance_name}; - - {core.name} {core.instance_name}_inst - ( - .clk(sys_clk), - .rst(sys_rst), - - .cs(enable_{core.instance_name} & (sys_eim_rd | sys_eim_wr)), - .we(sys_eim_wr), - - .address(addr_core_reg), - .write_data(sys_write_data), - .read_data(read_data_{core.instance_name}), - .error(error_{core.instance_name}) - ); - - """ # Template used by TRNGCore.createInstance(); this is different enough # from the generic template that it's (probably) clearer to have this # separate. -# -# Should this also be checking sys_ena? Not obvious to me either way. createInstance_template_TRNG = """\ //---------------------------------------------------------------- @@ -259,7 +236,7 @@ createInstance_template_TRNG = """\ {core.name} {core.instance_name}_inst ( .clk(sys_clk), - .reset_n(~sys_rst), + {core.reset_pin}, .cs(enable_{core.instance_name} & (sys_eim_rd | sys_eim_wr)), .we(sys_eim_wr), @@ -353,6 +330,8 @@ endmodule # Template for makefile snippet listing Verilog source files. listVfiles_template = """\ +# NOTE: This file is generated; do not edit by hand. + vfiles +={vfiles} """ diff --git a/config/core_selector.v b/config/core_selector.v index 4debd60..731b494 100644 --- a/config/core_selector.v +++ b/config/core_selector.v @@ -51,7 +51,7 @@ module core_selector board_regs board_regs_inst ( .clk(sys_clk), - .reset_n(~sys_rst), + .rst(sys_rst), .cs(enable_board_regs & (sys_eim_rd | sys_eim_wr)), .we(sys_eim_wr), @@ -72,7 +72,7 @@ module core_selector comm_regs comm_regs_inst ( .clk(sys_clk), - .reset_n(~sys_rst), + .rst(sys_rst), .cs(enable_comm_regs & (sys_eim_rd | sys_eim_wr)), .we(sys_eim_wr), diff --git a/config/core_vfiles.mk b/config/core_vfiles.mk new file mode 100644 index 0000000..bd1c6d4 --- /dev/null +++ b/config/core_vfiles.mk @@ -0,0 +1,34 @@ +# NOTE: This file is generated; do not edit by hand. + +vfiles += \ + $(CORE_TREE)/hash/sha256/src/rtl/sha256.v \ + $(CORE_TREE)/hash/sha256/src/rtl/sha256_core.v \ + $(CORE_TREE)/hash/sha256/src/rtl/sha256_k_constants.v \ + $(CORE_TREE)/hash/sha256/src/rtl/sha256_w_mem.v \ + $(CORE_TREE)/cipher/aes/src/rtl/aes.v \ + $(CORE_TREE)/cipher/aes/src/rtl/aes_core.v \ + $(CORE_TREE)/cipher/aes/src/rtl/aes_decipher_block.v \ + $(CORE_TREE)/cipher/aes/src/rtl/aes_encipher_block.v \ + $(CORE_TREE)/cipher/aes/src/rtl/aes_inv_sbox.v \ + $(CORE_TREE)/cipher/aes/src/rtl/aes_key_mem.v \ + $(CORE_TREE)/cipher/aes/src/rtl/aes_sbox.v \ + $(CORE_TREE)/rng/avalanche_entropy/src/rtl/avalanche_entropy.v \ + $(CORE_TREE)/rng/avalanche_entropy/src/rtl/avalanche_entropy_core.v \ + $(CORE_TREE)/rng/rosc_entropy/src/rtl/rosc.v \ + $(CORE_TREE)/rng/rosc_entropy/src/rtl/rosc_entropy.v \ + $(CORE_TREE)/rng/rosc_entropy/src/rtl/rosc_entropy_core.v \ + $(CORE_TREE)/rng/trng/src/rtl/trng.v \ + $(CORE_TREE)/rng/trng/src/rtl/trng_csprng.v \ + $(CORE_TREE)/rng/trng/src/rtl/trng_csprng_fifo.v \ + $(CORE_TREE)/rng/trng/src/rtl/trng_mixer.v \ + $(CORE_TREE)/math/modexp/src/rtl/adder.v \ + $(CORE_TREE)/math/modexp/src/rtl/blockmem1r1w.v \ + $(CORE_TREE)/math/modexp/src/rtl/blockmem2r1wptr.v \ + $(CORE_TREE)/math/modexp/src/rtl/blockmem2r1w.v \ + $(CORE_TREE)/math/modexp/src/rtl/blockmem2rptr1w.v \ + $(CORE_TREE)/math/modexp/src/rtl/modexp.v \ + $(CORE_TREE)/math/modexp/src/rtl/modexp_core.v \ + $(CORE_TREE)/math/modexp/src/rtl/montprod.v \ + $(CORE_TREE)/math/modexp/src/rtl/residue.v \ + $(CORE_TREE)/math/modexp/src/rtl/shl.v \ + $(CORE_TREE)/math/modexp/src/rtl/shr.v -- cgit v1.2.3 From cf8167215459811f8047f7c6d4f5972d924f6689 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Sun, 27 Sep 2015 13:17:55 -0400 Subject: Comments noting the strange history of the addressing scheme. --- config/config.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/config/config.py b/config/config.py index 970b339..4648f9d 100755 --- a/config/config.py +++ b/config/config.py @@ -3,6 +3,44 @@ Generate core_selector.v for a set of cores. """ +# History of cryptech bus addressing scheme, as best I understand it. +# +# The old old addressing scheme that Joachim and Paul came up with +# was: +# +# 3 bits of segment selector [16:14] +# 6 bits of core selector [13:8] +# 8 bits of register selector [7:0] +# +# modexp6s needed more register bits than that, so Pavel changed +# addressing within the math segment to: +# +# 3 bits of segment selector [16:14] +# 4 bits of core selector [13:10] +# 10 bits of register selector [9:0] +# +# Meanwhile, Paul eliminated segments entirely when writing the +# ancestor of this script, resulting in: +# +# 9 bits of core selector [16:8] +# 8 bits of register selector [7:0] +# +# Taking Pavel's and Paul's changes together, we want: +# +# 7 bits of core selector [16:10] +# 10 bits of register selector [9:0] +# +# Open issue: what effect does all this have on the sub-core muxing +# within trng cores? trng core plus its (currently) four sub-cores +# still takes up more than one new core slot even if trng uses the old +# scheme internally. How many slots should we allocate, and what +# addressing scheme is the trng core expecting to see? + +# Unrelated: Timing delays. Paul added extra registers to slow cores +# other than modexps6 down by one clock cycle, to compensate for the +# one cycle delay that seems to be built into the block memories that +# modexps6 uses. Templates will need to reflect that somehow. + def main(): """ Parse arguments and config file, generate core list, generate output. -- cgit v1.2.3 From 0ef997a7567156ed271f36b64e077bd75c9e1798 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Sun, 27 Sep 2015 18:58:10 -0400 Subject: Wedge modexps6 into the addressing scheme. Adjust timing of other cores. Tweak TRNG templates to support multiple instances, more for consistency than than because we really expect multiple TRNGs. --- config/config.py | 84 +++++++++++++++++++++++++++++++++++++++++++++++--- config/core_selector.v | 44 ++++++++++++++++++++------ 2 files changed, 113 insertions(+), 15 deletions(-) diff --git a/config/config.py b/config/config.py index 4648f9d..bf77a36 100755 --- a/config/config.py +++ b/config/config.py @@ -35,6 +35,11 @@ Generate core_selector.v for a set of cores. # still takes up more than one new core slot even if trng uses the old # scheme internally. How many slots should we allocate, and what # addressing scheme is the trng core expecting to see? +# +# So perhaps a better plan would be to keep Paul's scheme and just +# give modexps6 four core's worth of space, passing a 10 bit composite +# address constructed in much the same way as the trng template +# already does. # Unrelated: Timing delays. Paul added extra registers to slow cores # other than modexps6 down by one clock cycle, to compensate for the @@ -200,6 +205,10 @@ class TRNGCore(InvertedResetCore): n = subcore.assign_core_number(n) return n + @property + def last_subcore_upper_instance_name(self): + return self.subcores[-1].upper_instance_name + def createInstance(self): return createInstance_template_TRNG.format(core = self) @@ -209,6 +218,20 @@ class TRNGCore(InvertedResetCore): def createMux(self): return super(TRNGCore, self).createMux() + "".join(subcore.createMux() for subcore in self.subcores) + +class ModExpS6Core(Core): + + def assign_core_number(self, n): + n = super(ModExpS6Core, self).assign_core_number(n) + return n + 3 + + def createInstance(self): + return createInstance_template_ModExpS6.format(core = self) + + def createMux(self): + return createMux_modexps6_template.format(core = self) + + # Hook special classes in as handlers for the cores that require them. Core.special_class.update( @@ -218,7 +241,8 @@ Core.special_class.update( sha1 = InvertedResetCore, sha256 = InvertedResetCore, sha512 = InvertedResetCore, - modexp = InvertedResetCore) + modexp = InvertedResetCore, + modexps6 = ModExpS6Core) # Templates (format strings), here instead of inline in the functions @@ -255,6 +279,38 @@ createInstance_template_generic = """\ .read_data(read_data_{core.instance_name}) ); + reg [31: 0] read_data_{core.instance_name}_reg; + always @(posedge sys_clk) + read_data_{core.instance_name}_reg <= read_data_{core.instance_name}; + + +""" + +# Template used by ModExpS6Core.createInstance(). This is different +# enough from the base template that it's easier to make this separate. + +createInstance_template_ModExpS6 = """\ + //---------------------------------------------------------------- + // {core.upper_instance_name} + //---------------------------------------------------------------- + wire enable_{core.instance_name} = (addr_core_num >= CORE_ADDR_{core.upper_instance_name}) && (addr_core_num <= CORE_ADDR_{core.upper_instance_name} + 3); + wire [31: 0] read_data_{core.instance_name}; + wire error_{core.instance_name}; + wire [1:0] {core.instance_name}_prefix = addr_core_num[1:0] - CORE_ADDR_{core.upper_instance_name}; + + {core.name} {core.instance_name}_inst + ( + .clk(sys_clk), + {core.reset_pin}, + + .cs(enable_{core.instance_name} & (sys_eim_rd | sys_eim_wr)), + .we(sys_eim_wr), + + .address({{{core.instance_name}_prefix, addr_core_reg}}), + .write_data(sys_write_data), + .read_data(read_data_{core.instance_name}) + ); + """ @@ -266,10 +322,10 @@ createInstance_template_TRNG = """\ //---------------------------------------------------------------- // {core.upper_instance_name} //---------------------------------------------------------------- - wire enable_{core.instance_name} = (addr_core_num >= CORE_ADDR_TRNG) && (addr_core_num <= CORE_ADDR_TRNG_CSPRNG); + wire enable_{core.instance_name} = (addr_core_num >= CORE_ADDR_{core.upper_instance_name}) && (addr_core_num <= CORE_ADDR_{core.last_subcore_upper_instance_name}); wire [31: 0] read_data_{core.instance_name}; wire error_{core.instance_name}; - wire [3:0] trng_prefix = addr_core_num[3:0] - CORE_ADDR_TRNG; + wire [3:0] {core.instance_name}_prefix = addr_core_num[3:0] - CORE_ADDR_{core.upper_instance_name}; {core.name} {core.instance_name}_inst ( @@ -279,7 +335,7 @@ createInstance_template_TRNG = """\ .cs(enable_{core.instance_name} & (sys_eim_rd | sys_eim_wr)), .we(sys_eim_wr), - .address({{trng_prefix, addr_core_reg}}), + .address({{{core.instance_name}_prefix, addr_core_reg}}), .write_data(sys_write_data), .read_data(read_data_{core.instance_name}), @@ -287,6 +343,10 @@ createInstance_template_TRNG = """\ .debug(debug) ); + reg [31: 0] read_data_{core.instance_name}_reg; + always @(posedge sys_clk) + read_data_{core.instance_name}_reg <= read_data_{core.instance_name}; + """ @@ -295,11 +355,25 @@ createInstance_template_TRNG = """\ createMux_template = """\ CORE_ADDR_{core.upper_instance_name}: begin - sys_read_data_mux = read_data_{core0.instance_name}; + sys_read_data_mux = read_data_{core0.instance_name}_reg; sys_error_mux = error_{core0.instance_name}; end """ +# Template for ModExpS6.createMux() method. + +createMux_modexps6_template = """\ + CORE_ADDR_{core.upper_instance_name} + 0, + CORE_ADDR_{core.upper_instance_name} + 1, + CORE_ADDR_{core.upper_instance_name} + 2, + CORE_ADDR_{core.upper_instance_name} + 3: + begin + sys_read_data_mux = read_data_{core.instance_name}; + sys_error_mux = error_{core.instance_name}; + end +""" + + # Top-level (createModule) template. createModule_template = """\ diff --git a/config/core_selector.v b/config/core_selector.v index 731b494..16d1a09 100644 --- a/config/core_selector.v +++ b/config/core_selector.v @@ -61,6 +61,10 @@ module core_selector .read_data(read_data_board_regs) ); + reg [31: 0] read_data_board_regs_reg; + always @(posedge sys_clk) + read_data_board_regs_reg <= read_data_board_regs; + //---------------------------------------------------------------- // COMM_REGS @@ -82,6 +86,10 @@ module core_selector .read_data(read_data_comm_regs) ); + reg [31: 0] read_data_comm_regs_reg; + always @(posedge sys_clk) + read_data_comm_regs_reg <= read_data_comm_regs; + //---------------------------------------------------------------- // SHA256 @@ -103,6 +111,10 @@ module core_selector .read_data(read_data_sha256) ); + reg [31: 0] read_data_sha256_reg; + always @(posedge sys_clk) + read_data_sha256_reg <= read_data_sha256; + //---------------------------------------------------------------- // AES @@ -124,6 +136,10 @@ module core_selector .read_data(read_data_aes) ); + reg [31: 0] read_data_aes_reg; + always @(posedge sys_clk) + read_data_aes_reg <= read_data_aes; + //---------------------------------------------------------------- // TRNG @@ -149,6 +165,10 @@ module core_selector .debug(debug) ); + reg [31: 0] read_data_trng_reg; + always @(posedge sys_clk) + read_data_trng_reg <= read_data_trng; + //---------------------------------------------------------------- // MODEXP @@ -170,6 +190,10 @@ module core_selector .read_data(read_data_modexp) ); + reg [31: 0] read_data_modexp_reg; + always @(posedge sys_clk) + read_data_modexp_reg <= read_data_modexp; + //---------------------------------------------------------------- @@ -185,52 +209,52 @@ module core_selector case (addr_core_num) CORE_ADDR_BOARD_REGS: begin - sys_read_data_mux = read_data_board_regs; + sys_read_data_mux = read_data_board_regs_reg; sys_error_mux = error_board_regs; end CORE_ADDR_COMM_REGS: begin - sys_read_data_mux = read_data_comm_regs; + sys_read_data_mux = read_data_comm_regs_reg; sys_error_mux = error_comm_regs; end CORE_ADDR_SHA256: begin - sys_read_data_mux = read_data_sha256; + sys_read_data_mux = read_data_sha256_reg; sys_error_mux = error_sha256; end CORE_ADDR_AES: begin - sys_read_data_mux = read_data_aes; + sys_read_data_mux = read_data_aes_reg; sys_error_mux = error_aes; end CORE_ADDR_TRNG: begin - sys_read_data_mux = read_data_trng; + sys_read_data_mux = read_data_trng_reg; sys_error_mux = error_trng; end CORE_ADDR_AVALANCHE_ENTROPY: begin - sys_read_data_mux = read_data_trng; + sys_read_data_mux = read_data_trng_reg; sys_error_mux = error_trng; end CORE_ADDR_ROSC_ENTROPY: begin - sys_read_data_mux = read_data_trng; + sys_read_data_mux = read_data_trng_reg; sys_error_mux = error_trng; end CORE_ADDR_TRNG_MIXER: begin - sys_read_data_mux = read_data_trng; + sys_read_data_mux = read_data_trng_reg; sys_error_mux = error_trng; end CORE_ADDR_TRNG_CSPRNG: begin - sys_read_data_mux = read_data_trng; + sys_read_data_mux = read_data_trng_reg; sys_error_mux = error_trng; end CORE_ADDR_MODEXP: begin - sys_read_data_mux = read_data_modexp; + sys_read_data_mux = read_data_modexp_reg; sys_error_mux = error_modexp; end -- cgit v1.2.3 From 54516bb49c631f447dbd443557fbde3285074c8a Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Sun, 27 Sep 2015 19:20:26 -0400 Subject: Add "requires" option. --- config/config.cfg | 8 +++++++- config/config.py | 4 ++++ config/core_vfiles.mk | 8 ++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/config/config.cfg b/config/config.cfg index 5f3cf21..9bb01ae 100644 --- a/config/config.cfg +++ b/config/config.cfg @@ -1,6 +1,6 @@ # Config file for the Cryptech Novena FPGA framework. # -# At present, there are three kinds of variables in this file. +# At present, there are four kinds of variables in this file: # # default-section: Name of the configuration to build if the user # doesn't specify one. Only meaningful in the default section. @@ -11,6 +11,11 @@ # including a particular core. All (optional) cores must have a # vfiles option, so that the configuration program knows what to put # into core_vfiles.mk. +# +# requires: A list of other cores whose vfiles must be loaded to build +# this core. This has no effect on the generated core_selector.v +# file, and has no effect at all if an instance of a core named here +# is already included in the build. [default] default-section = rsa @@ -52,6 +57,7 @@ vfiles = hash/sha512/src/rtl/sha512_w_mem.v [trng] +requires = chacha sha512 vfiles = rng/avalanche_entropy/src/rtl/avalanche_entropy.v rng/avalanche_entropy/src/rtl/avalanche_entropy_core.v diff --git a/config/config.py b/config/config.py index bf77a36..814826f 100755 --- a/config/config.py +++ b/config/config.py @@ -132,6 +132,10 @@ class Core(object): def add_vfiles(self, cfg): if self.instance_number == 0: self.vfiles = cfg.get(self.name, "vfiles").split() + if cfg.has_option(self.name, "requires"): + for required in cfg.get(self.name, "requires").split(): + if required not in self._instance_count: + self.vfiles.extend(cfg.get(required, "vfiles").split()) @property def instance_name(self): diff --git a/config/core_vfiles.mk b/config/core_vfiles.mk index bd1c6d4..8def572 100644 --- a/config/core_vfiles.mk +++ b/config/core_vfiles.mk @@ -21,6 +21,14 @@ vfiles += \ $(CORE_TREE)/rng/trng/src/rtl/trng_csprng.v \ $(CORE_TREE)/rng/trng/src/rtl/trng_csprng_fifo.v \ $(CORE_TREE)/rng/trng/src/rtl/trng_mixer.v \ + $(CORE_TREE)/cipher/chacha/src/rtl/chacha.v \ + $(CORE_TREE)/cipher/chacha/src/rtl/chacha_core.v \ + $(CORE_TREE)/cipher/chacha/src/rtl/chacha_qr.v \ + $(CORE_TREE)/hash/sha512/src/rtl/sha512.v \ + $(CORE_TREE)/hash/sha512/src/rtl/sha512_core.v \ + $(CORE_TREE)/hash/sha512/src/rtl/sha512_h_constants.v \ + $(CORE_TREE)/hash/sha512/src/rtl/sha512_k_constants.v \ + $(CORE_TREE)/hash/sha512/src/rtl/sha512_w_mem.v \ $(CORE_TREE)/math/modexp/src/rtl/adder.v \ $(CORE_TREE)/math/modexp/src/rtl/blockmem1r1w.v \ $(CORE_TREE)/math/modexp/src/rtl/blockmem2r1wptr.v \ -- cgit v1.2.3 From fdd81bb1df1df3cad091ea0076a0e6207f0e8f3d Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Sun, 27 Sep 2015 20:36:19 -0400 Subject: Comments. --- config/config.py | 46 +++++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/config/config.py b/config/config.py index 814826f..0ec1274 100755 --- a/config/config.py +++ b/config/config.py @@ -25,26 +25,36 @@ Generate core_selector.v for a set of cores. # 9 bits of core selector [16:8] # 8 bits of register selector [7:0] # -# Taking Pavel's and Paul's changes together, we want: +# Taking Pavel's and Paul's changes together, we'd get: # # 7 bits of core selector [16:10] # 10 bits of register selector [9:0] # -# Open issue: what effect does all this have on the sub-core muxing -# within trng cores? trng core plus its (currently) four sub-cores -# still takes up more than one new core slot even if trng uses the old -# scheme internally. How many slots should we allocate, and what -# addressing scheme is the trng core expecting to see? -# -# So perhaps a better plan would be to keep Paul's scheme and just -# give modexps6 four core's worth of space, passing a 10 bit composite -# address constructed in much the same way as the trng template -# already does. +# Except that this would waste space for most cores, and make things +# very confusing for the TRNG cores. So, instead, we keep Paul's +# two-level (no segment) scheme and handle modexps6 as a set of four +# consecutive "cores" with a 10-bit composite register selector. + +# The modexps6 core also drags in a one clock cycle delay to other +# cores, to compensate for the extra clock cycle consumed by the block +# memories used in the modexps6 core. -# Unrelated: Timing delays. Paul added extra registers to slow cores -# other than modexps6 down by one clock cycle, to compensate for the -# one cycle delay that seems to be built into the block memories that -# modexps6 uses. Templates will need to reflect that somehow. +# To Do: +# +# - Move reset-high/reset-low to a boolean variable in the config +# file, simplify Core classes accordingly. +# +# - Consider automating the one-clock-cycle delay stuff by adding +# another boolean flag to the config file. Default would be no +# delay, if any included core sets the "I use block memories" flag, +# all other cores would get the delay. Slightly tedious but +# something we can calculate easily enough, and probably an +# improvement over wiring in the delay when nothing needs it. +# +# - Rename script and its config file to something more meaningful. +# +# - Figure out whether this really belongs in the novena repository at +# all, seems more generic than that. def main(): """ @@ -224,6 +234,11 @@ class TRNGCore(InvertedResetCore): class ModExpS6Core(Core): + """ + ModExpS6 core consumes as much space as four ordinary cores, and + uses different templates to handle the differences in timing and + addressing. + """ def assign_core_number(self, n): n = super(ModExpS6Core, self).assign_core_number(n) @@ -237,6 +252,7 @@ class ModExpS6Core(Core): # Hook special classes in as handlers for the cores that require them. +# Moving the reset-high/reset-low logic to the config file should simplify this. Core.special_class.update( trng = TRNGCore, -- cgit v1.2.3 From 6894db11d641b37c26a0184b43dc87eb00bd36a6 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Mon, 28 Sep 2015 07:45:33 -0400 Subject: ModExpS6 top is called modexps6_wrapper, not modexps6, sigh. --- config/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/config.py b/config/config.py index 0ec1274..2a11bd6 100755 --- a/config/config.py +++ b/config/config.py @@ -318,7 +318,7 @@ createInstance_template_ModExpS6 = """\ wire error_{core.instance_name}; wire [1:0] {core.instance_name}_prefix = addr_core_num[1:0] - CORE_ADDR_{core.upper_instance_name}; - {core.name} {core.instance_name}_inst + {core.name}_wrapper {core.instance_name}_inst ( .clk(sys_clk), {core.reset_pin}, -- cgit v1.2.3 From 438a6d8e02afdea04e30f8782d4a701e119b3703 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Mon, 28 Sep 2015 19:17:33 -0400 Subject: Handle reset high/low logic in the config file. Connect error signals. --- config/config.cfg | 1 + config/config.py | 79 ++++++++++++++++++++++++++++---------------------- config/core_selector.v | 16 ++++++---- 3 files changed, 57 insertions(+), 39 deletions(-) diff --git a/config/config.cfg b/config/config.cfg index 9bb01ae..a4120b1 100644 --- a/config/config.cfg +++ b/config/config.cfg @@ -86,6 +86,7 @@ vfiles = cipher/chacha/src/rtl/chacha_qr.v [modexps6] +reset_high = true vfiles = math/modexps6/src/rtl/modexps6_adder64_carry32.v math/modexps6/src/rtl/modexps6_buffer_core.v diff --git a/config/config.py b/config/config.py index 2a11bd6..3ae809b 100755 --- a/config/config.py +++ b/config/config.py @@ -56,14 +56,14 @@ Generate core_selector.v for a set of cores. # - Figure out whether this really belongs in the novena repository at # all, seems more generic than that. + def main(): """ Parse arguments and config file, generate core list, generate output. """ - from argparse import ArgumentParser, FileType, ArgumentDefaultsHelpFormatter - from ConfigParser import RawConfigParser - from sys import exit + from argparse import ArgumentParser, FileType, ArgumentDefaultsHelpFormatter + from sys import exit parser = ArgumentParser(description = __doc__, formatter_class = ArgumentDefaultsHelpFormatter) parser.add_argument("-d", "--debug", help = "enable debugging", action = "store_true") @@ -88,11 +88,16 @@ def main(): cores.insert(1, "comm_regs") cores = tuple(Core.new(core) for core in cores) + core_number = 0 for core in cores: core_number = core.assign_core_number(core_number) - for core in cores[2:]: - core.add_vfiles(cfg) + + cores[0].reset_high = True + cores[1].reset_high = True + + for core in cores: + core.configure(cfg) args.verilog.write(createModule_template.format( addrs = "".join(core.createAddr() for core in cores), @@ -108,6 +113,28 @@ def main(): exit(str(e)) +try: + import ConfigParser as configparser +except ImportError: + import configparser + +class RawConfigParser(configparser.RawConfigParser): + """ + RawConfigParser with a few extensions. + """ + + def getboolean(self, section, option, default = False): + if self.has_option(section, option): + return super(RawConfigParser, self).getboolean(section, option) + else: + return default + + def getvalues(self, section, option): + if self.has_option(section, option): + for value in self.get(section, option).split(): + yield value + + class Core(object): """ Data and methods for a generic core. We can use this directly for @@ -127,7 +154,8 @@ class Core(object): def __init__(self, name): self.name = name self.core_number = None - self.vfiles = () + self.vfiles = [] + self.reset_high = False self.instance_number = self._instance_count.get(name, 0) self._instance_count[name] = self.instance_number + 1 @@ -139,13 +167,13 @@ class Core(object): self.core_number = n return n + 1 - def add_vfiles(self, cfg): + def configure(self, cfg): if self.instance_number == 0: - self.vfiles = cfg.get(self.name, "vfiles").split() - if cfg.has_option(self.name, "requires"): - for required in cfg.get(self.name, "requires").split(): - if required not in self._instance_count: - self.vfiles.extend(cfg.get(required, "vfiles").split()) + self.vfiles.extend(cfg.getvalues(self.name, "vfiles")) + for required in cfg.getvalues(self.name, "requires"): + if required not in self._instance_count: + self.vfiles.extend(cfg.getvalues(required, "vfiles")) + self.reset_high = cfg.getboolean(self.name, "reset_high", self.reset_high) @property def instance_name(self): @@ -160,7 +188,7 @@ class Core(object): @property def reset_pin(self): - return ".rst(sys_rst)" + return ".rst(sys_rst)" if self.reset_high else ".reset_n(~sys_rst)" def createInstance(self): return createInstance_template_generic.format(core = self) @@ -175,17 +203,6 @@ class Core(object): return "".join(" \\\n\t$(CORE_TREE)/" + vfile for vfile in self.vfiles) -class InvertedResetCore(Core): - """ - Core which inverts the reset signal. Seems to vary by author. - No, I don't know why we don't just pick one convention or the other. - """ - - @property - def reset_pin(self): - return ".reset_n(~sys_rst)" - - class SubCore(Core): """" Override mux handling for TRNG's sub-cores. @@ -199,7 +216,7 @@ class SubCore(Core): return createMux_template.format(core = self, core0 = self.parent) -class TRNGCore(InvertedResetCore): +class TRNGCore(Core): """ The TRNG core has an internal mux and a collection of sub-cores. Mostly this means that our method calls have to iterate over all @@ -252,16 +269,9 @@ class ModExpS6Core(Core): # Hook special classes in as handlers for the cores that require them. -# Moving the reset-high/reset-low logic to the config file should simplify this. Core.special_class.update( trng = TRNGCore, - aes = InvertedResetCore, - chacha = InvertedResetCore, - sha1 = InvertedResetCore, - sha256 = InvertedResetCore, - sha512 = InvertedResetCore, - modexp = InvertedResetCore, modexps6 = ModExpS6Core) @@ -296,7 +306,8 @@ createInstance_template_generic = """\ .address(addr_core_reg), .write_data(sys_write_data), - .read_data(read_data_{core.instance_name}) + .read_data(read_data_{core.instance_name}), + .error(error_{core.instance_name}) ); reg [31: 0] read_data_{core.instance_name}_reg; @@ -315,7 +326,6 @@ createInstance_template_ModExpS6 = """\ //---------------------------------------------------------------- wire enable_{core.instance_name} = (addr_core_num >= CORE_ADDR_{core.upper_instance_name}) && (addr_core_num <= CORE_ADDR_{core.upper_instance_name} + 3); wire [31: 0] read_data_{core.instance_name}; - wire error_{core.instance_name}; wire [1:0] {core.instance_name}_prefix = addr_core_num[1:0] - CORE_ADDR_{core.upper_instance_name}; {core.name}_wrapper {core.instance_name}_inst @@ -358,6 +368,7 @@ createInstance_template_TRNG = """\ .address({{{core.instance_name}_prefix, addr_core_reg}}), .write_data(sys_write_data), .read_data(read_data_{core.instance_name}), + .error(error_{core.instance_name}), .avalanche_noise(noise), .debug(debug) diff --git a/config/core_selector.v b/config/core_selector.v index 16d1a09..cc7ca14 100644 --- a/config/core_selector.v +++ b/config/core_selector.v @@ -58,7 +58,8 @@ module core_selector .address(addr_core_reg), .write_data(sys_write_data), - .read_data(read_data_board_regs) + .read_data(read_data_board_regs), + .error(error_board_regs) ); reg [31: 0] read_data_board_regs_reg; @@ -83,7 +84,8 @@ module core_selector .address(addr_core_reg), .write_data(sys_write_data), - .read_data(read_data_comm_regs) + .read_data(read_data_comm_regs), + .error(error_comm_regs) ); reg [31: 0] read_data_comm_regs_reg; @@ -108,7 +110,8 @@ module core_selector .address(addr_core_reg), .write_data(sys_write_data), - .read_data(read_data_sha256) + .read_data(read_data_sha256), + .error(error_sha256) ); reg [31: 0] read_data_sha256_reg; @@ -133,7 +136,8 @@ module core_selector .address(addr_core_reg), .write_data(sys_write_data), - .read_data(read_data_aes) + .read_data(read_data_aes), + .error(error_aes) ); reg [31: 0] read_data_aes_reg; @@ -160,6 +164,7 @@ module core_selector .address({trng_prefix, addr_core_reg}), .write_data(sys_write_data), .read_data(read_data_trng), + .error(error_trng), .avalanche_noise(noise), .debug(debug) @@ -187,7 +192,8 @@ module core_selector .address(addr_core_reg), .write_data(sys_write_data), - .read_data(read_data_modexp) + .read_data(read_data_modexp), + .error(error_modexp) ); reg [31: 0] read_data_modexp_reg; -- cgit v1.2.3 From 28a2e6633ca414ffa58bd718ca89ec6b3ba723ef Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Mon, 28 Sep 2015 19:30:25 -0400 Subject: RawConfigParser doesn't support super(). --- config/config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/config.py b/config/config.py index 3ae809b..57dbddc 100755 --- a/config/config.py +++ b/config/config.py @@ -125,7 +125,8 @@ class RawConfigParser(configparser.RawConfigParser): def getboolean(self, section, option, default = False): if self.has_option(section, option): - return super(RawConfigParser, self).getboolean(section, option) + # RawConfigParser is an old-stle class, super() doesn't work, feh. + return configparser.RawConfigParser.getboolean(self, section, option) else: return default -- cgit v1.2.3 From e3eb4913425d4f48967c0af8213a41d49a470e62 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Mon, 28 Sep 2015 19:36:30 -0400 Subject: ModExpS6 has no error output. --- config/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/config.py b/config/config.py index 57dbddc..26385d0 100755 --- a/config/config.py +++ b/config/config.py @@ -401,7 +401,7 @@ createMux_modexps6_template = """\ CORE_ADDR_{core.upper_instance_name} + 3: begin sys_read_data_mux = read_data_{core.instance_name}; - sys_error_mux = error_{core.instance_name}; + sys_error_mux = 0; end """ -- cgit v1.2.3 From ff4cf7a0530218cb86a860c803e6fccdafcff385 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Mon, 28 Sep 2015 22:03:48 -0400 Subject: Comment update. --- config/config.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/config/config.py b/config/config.py index 26385d0..c0c3c5e 100755 --- a/config/config.py +++ b/config/config.py @@ -1,9 +1,10 @@ #!/usr/bin/env python + """ -Generate core_selector.v for a set of cores. +Generate core_selector.v and core_vfiles.mk for a set of cores. """ -# History of cryptech bus addressing scheme, as best I understand it. +# History of Cryptech bus addressing scheme, as best I understand it. # # The old old addressing scheme that Joachim and Paul came up with # was: @@ -33,7 +34,7 @@ Generate core_selector.v for a set of cores. # Except that this would waste space for most cores, and make things # very confusing for the TRNG cores. So, instead, we keep Paul's # two-level (no segment) scheme and handle modexps6 as a set of four -# consecutive "cores" with a 10-bit composite register selector. +# contiguous "cores" with a 10-bit composite register selector. # The modexps6 core also drags in a one clock cycle delay to other # cores, to compensate for the extra clock cycle consumed by the block @@ -41,9 +42,6 @@ Generate core_selector.v for a set of cores. # To Do: # -# - Move reset-high/reset-low to a boolean variable in the config -# file, simplify Core classes accordingly. -# # - Consider automating the one-clock-cycle delay stuff by adding # another boolean flag to the config file. Default would be no # delay, if any included core sets the "I use block memories" flag, -- cgit v1.2.3 From c421ca5e30120861006a6a0ca0ba3f23b14d88ed Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Tue, 29 Sep 2015 00:04:01 -0400 Subject: Sick hacks to compensate for sparse MUX within TRNG core. --- config/config.py | 52 ++++++++++++++++++++++++++++++++++++++++++-------- config/core_selector.v | 12 ++++++------ 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/config/config.py b/config/config.py index c0c3c5e..3cb69db 100755 --- a/config/config.py +++ b/config/config.py @@ -36,6 +36,32 @@ Generate core_selector.v and core_vfiles.mk for a set of cores. # two-level (no segment) scheme and handle modexps6 as a set of four # contiguous "cores" with a 10-bit composite register selector. +# Gah: the TRNG core's internal multiplexer doesn't allocate cores +# contiguously, there's a gap, and one just has to know what the +# offsets are. So we need to adjust for all of that. Feh. In theory +# we could hide the gap from the outside world, as it's just a matter +# of (magic) constant offsets on top of the ones we're already +# fiddling with in the core_selector mux. See +# core/rng/trng/src/rtl/trng.v for the authoritative list, but the +# magic offsets for the high 4 bits of the 12-bit TRNG address are: +# +# 0: trng +# 1: - +# 2: - +# 3: - +# 4: - +# 5: entropy1 (avalanche) +# 6: entropy2 (rosc) +# 7: - +# 8: - +# 9: - +# a: mixer +# b: csprng +# c: - +# d: - +# e: - +# f: - + # The modexps6 core also drags in a one clock cycle delay to other # cores, to compensate for the extra clock cycle consumed by the block # memories used in the modexps6 core. @@ -217,23 +243,33 @@ class SubCore(Core): class TRNGCore(Core): """ - The TRNG core has an internal mux and a collection of sub-cores. + The TRNG core has an internal mux with slots for 15 sub-cores, + most of which are empty. This is a bit of a mess. + Mostly this means that our method calls have to iterate over all of the subcores after handling the base TRNG core, but we also use - a different instance template in the hope that it is easier to read. + different templates, and fiddle with addresses a bit. + + Mux numbers have to be dug out of the TRNG Verilog source. """ - subcore_names = ("avalanche_entropy", "rosc_entropy", "trng_mixer", "trng_csprng") + # TRNG subcore name -> internal mux number. + subcore_parameters = dict(avalanche_entropy = 0x5, + rosc_entropy = 0x6, + trng_mixer = 0xa, + trng_csprng = 0xb) def __init__(self, name): super(TRNGCore, self).__init__(name) - self.subcores = tuple(SubCore(name, self) for name in self.subcore_names) + self.subcores = tuple(SubCore(name, self) + for name in sorted(self.subcore_parameters, + key = lambda x: self.subcore_parameters[x])) def assign_core_number(self, n): n = super(TRNGCore, self).assign_core_number(n) for subcore in self.subcores: - n = subcore.assign_core_number(n) - return n + subcore.assign_core_number(self.core_number + self.subcore_parameters[subcore.name]) + return n + 15 @property def last_subcore_upper_instance_name(self): @@ -323,7 +359,7 @@ createInstance_template_ModExpS6 = """\ //---------------------------------------------------------------- // {core.upper_instance_name} //---------------------------------------------------------------- - wire enable_{core.instance_name} = (addr_core_num >= CORE_ADDR_{core.upper_instance_name}) && (addr_core_num <= CORE_ADDR_{core.upper_instance_name} + 3); + wire enable_{core.instance_name} = (addr_core_num >= CORE_ADDR_{core.upper_instance_name}) && (addr_core_num <= CORE_ADDR_{core.upper_instance_name} + 9'h03); wire [31: 0] read_data_{core.instance_name}; wire [1:0] {core.instance_name}_prefix = addr_core_num[1:0] - CORE_ADDR_{core.upper_instance_name}; @@ -351,7 +387,7 @@ createInstance_template_TRNG = """\ //---------------------------------------------------------------- // {core.upper_instance_name} //---------------------------------------------------------------- - wire enable_{core.instance_name} = (addr_core_num >= CORE_ADDR_{core.upper_instance_name}) && (addr_core_num <= CORE_ADDR_{core.last_subcore_upper_instance_name}); + wire enable_{core.instance_name} = (addr_core_num >= CORE_ADDR_{core.upper_instance_name}) && (addr_core_num <= CORE_ADDR_{core.upper_instance_name} + 9'h0f); wire [31: 0] read_data_{core.instance_name}; wire error_{core.instance_name}; wire [3:0] {core.instance_name}_prefix = addr_core_num[3:0] - CORE_ADDR_{core.upper_instance_name}; diff --git a/config/core_selector.v b/config/core_selector.v index cc7ca14..90b688e 100644 --- a/config/core_selector.v +++ b/config/core_selector.v @@ -34,11 +34,11 @@ module core_selector 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; + localparam CORE_ADDR_AVALANCHE_ENTROPY = 9'h09; + localparam CORE_ADDR_ROSC_ENTROPY = 9'h0a; + localparam CORE_ADDR_TRNG_MIXER = 9'h0e; + localparam CORE_ADDR_TRNG_CSPRNG = 9'h0f; + localparam CORE_ADDR_MODEXP = 9'h14; //---------------------------------------------------------------- @@ -148,7 +148,7 @@ module core_selector //---------------------------------------------------------------- // TRNG //---------------------------------------------------------------- - wire enable_trng = (addr_core_num >= CORE_ADDR_TRNG) && (addr_core_num <= CORE_ADDR_TRNG_CSPRNG); + wire enable_trng = (addr_core_num >= CORE_ADDR_TRNG) && (addr_core_num <= CORE_ADDR_TRNG + 9'h0f); wire [31: 0] read_data_trng; wire error_trng; wire [3:0] trng_prefix = addr_core_num[3:0] - CORE_ADDR_TRNG; -- cgit v1.2.3 From c71a4b55a2c11349d3de2cd503eb058b384f5d34 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Tue, 29 Sep 2015 18:09:04 -0400 Subject: Add support for error_wire and block_memory options. --- config/config.cfg | 17 ++++++++- config/config.py | 99 +++++++++++++++++++++++++++++--------------------- config/core_selector.v | 43 ++++++---------------- 3 files changed, 85 insertions(+), 74 deletions(-) diff --git a/config/config.cfg b/config/config.cfg index a4120b1..7e4571c 100644 --- a/config/config.cfg +++ b/config/config.cfg @@ -1,6 +1,6 @@ # Config file for the Cryptech Novena FPGA framework. # -# At present, there are four kinds of variables in this file: +# Variables used in this file: # # default-section: Name of the configuration to build if the user # doesn't specify one. Only meaningful in the default section. @@ -16,6 +16,16 @@ # this core. This has no effect on the generated core_selector.v # file, and has no effect at all if an instance of a core named here # is already included in the build. +# +# reset_high: boolean indicating whether the core uses active reset. +# +# error_wire: boolean indicating whether the core wants a error wire. +# +# block_memory: boolean indicating whether the core uses block memory. +# Effect of this is a bit strange: setting it triggers generation of +# a one-cycle timing delay for every core in this build that does +# *not* use block memory. When no cores in the build use block +# memory, the delay isn't necessary and is therefore omitted. [default] default-section = rsa @@ -86,7 +96,9 @@ vfiles = cipher/chacha/src/rtl/chacha_qr.v [modexps6] -reset_high = true +block_memory = yes +reset_high = yes +error_wire = no vfiles = math/modexps6/src/rtl/modexps6_adder64_carry32.v math/modexps6/src/rtl/modexps6_buffer_core.v @@ -101,6 +113,7 @@ vfiles = math/modexps6/src/rtl/ipcore/subtractor_s6.v [modexp] +error_wire = no vfiles = math/modexp/src/rtl/adder.v math/modexp/src/rtl/blockmem1r1w.v diff --git a/config/config.py b/config/config.py index 3cb69db..1c5e5d0 100755 --- a/config/config.py +++ b/config/config.py @@ -36,35 +36,24 @@ Generate core_selector.v and core_vfiles.mk for a set of cores. # two-level (no segment) scheme and handle modexps6 as a set of four # contiguous "cores" with a 10-bit composite register selector. -# Gah: the TRNG core's internal multiplexer doesn't allocate cores +# At present, TRNG core's internal multiplexer doesn't allocate cores # contiguously, there's a gap, and one just has to know what the -# offsets are. So we need to adjust for all of that. Feh. In theory -# we could hide the gap from the outside world, as it's just a matter -# of (magic) constant offsets on top of the ones we're already -# fiddling with in the core_selector mux. See -# core/rng/trng/src/rtl/trng.v for the authoritative list, but the -# magic offsets for the high 4 bits of the 12-bit TRNG address are: +# offsets are. Current theory is that we'll fix the TRNG core to get +# rid of this problem, but for now the workaround requires this script +# to know the magic offsets for the high 4 bits of the 12-bit TRNG +# address: # -# 0: trng -# 1: - -# 2: - -# 3: - -# 4: - -# 5: entropy1 (avalanche) -# 6: entropy2 (rosc) -# 7: - -# 8: - -# 9: - -# a: mixer -# b: csprng -# c: - -# d: - -# e: - -# f: - - -# The modexps6 core also drags in a one clock cycle delay to other -# cores, to compensate for the extra clock cycle consumed by the block -# memories used in the modexps6 core. +# 0x0: trng +# 0x5: entropy1 (avalanche) +# 0x6: entropy2 (rosc) +# 0xa: mixer +# 0xb: csprng + +# The modexps6 core drags in a one clock cycle delay to other cores, +# to compensate for the extra clock cycle consumed by the block +# memories used in the modexps6 core. We probably want a general +# solution for this, because we're going to run into this problem for +# any core that handles arguments big enough to require block memory. # To Do: # @@ -123,6 +112,8 @@ def main(): for core in cores: core.configure(cfg) + Core.need_one_cycle_delay = any(core.block_memory for core in cores) + args.verilog.write(createModule_template.format( addrs = "".join(core.createAddr() for core in cores), insts = "".join(core.createInstance() for core in cores), @@ -172,15 +163,22 @@ class Core(object): _instance_count = {} - # Map from core name to subclass for the special case cores. + # Class variable mapping core name to subclass for special cases. special_class = {} + # Class variable recording whether we need a one-cycle delay to + # compensate for block memories. + + need_one_cycle_delay = False + def __init__(self, name): self.name = name self.core_number = None self.vfiles = [] self.reset_high = False + self.error_wire = True + self.block_memory = False self.instance_number = self._instance_count.get(name, 0) self._instance_count[name] = self.instance_number + 1 @@ -199,6 +197,8 @@ class Core(object): if required not in self._instance_count: self.vfiles.extend(cfg.getvalues(required, "vfiles")) self.reset_high = cfg.getboolean(self.name, "reset_high", self.reset_high) + self.error_wire = cfg.getboolean(self.name, "error_wire", self.error_wire) + self.block_memory = cfg.getboolean(self.name, "block_memory", self.block_memory) @property def instance_name(self): @@ -215,6 +215,22 @@ class Core(object): def reset_pin(self): return ".rst(sys_rst)" if self.reset_high else ".reset_n(~sys_rst)" + @property + def error_port(self): + return ",\n .error(error_{core.instance_name})".format(core = self) if self.error_wire else "" + + @property + def one_cycle_delay(self): + return one_cycle_delay_template.format(core = self) if self.need_one_cycle_delay and not self.block_memory else "" + + @property + def mux_data_reg(self): + return "read_data_" + self.instance_name + ("_reg" if self.need_one_cycle_delay and not self.block_memory else "") + + @property + def mux_error_reg(self): + return "error_" + self.instance_name if self.error_wire else "0" + def createInstance(self): return createInstance_template_generic.format(core = self) @@ -300,7 +316,7 @@ class ModExpS6Core(Core): return createInstance_template_ModExpS6.format(core = self) def createMux(self): - return createMux_modexps6_template.format(core = self) + return createMux_modexps6_template.format(core = self, core0 = self) # Hook special classes in as handlers for the cores that require them. @@ -341,14 +357,10 @@ createInstance_template_generic = """\ .address(addr_core_reg), .write_data(sys_write_data), - .read_data(read_data_{core.instance_name}), - .error(error_{core.instance_name}) + .read_data(read_data_{core.instance_name}){core.error_port} ); - reg [31: 0] read_data_{core.instance_name}_reg; - always @(posedge sys_clk) - read_data_{core.instance_name}_reg <= read_data_{core.instance_name}; - +{core.one_cycle_delay} """ @@ -409,11 +421,16 @@ createInstance_template_TRNG = """\ .debug(debug) ); +{core.one_cycle_delay} + +""" + +# Template for one-cycle delay code. + +one_cycle_delay_template = """\ reg [31: 0] read_data_{core.instance_name}_reg; always @(posedge sys_clk) read_data_{core.instance_name}_reg <= read_data_{core.instance_name}; - - """ # Template for .createMux() methods. @@ -421,8 +438,8 @@ createInstance_template_TRNG = """\ createMux_template = """\ CORE_ADDR_{core.upper_instance_name}: begin - sys_read_data_mux = read_data_{core0.instance_name}_reg; - sys_error_mux = error_{core0.instance_name}; + sys_read_data_mux = {core0.mux_data_reg}; + sys_error_mux = {core0.mux_error_reg}; end """ @@ -434,8 +451,8 @@ createMux_modexps6_template = """\ CORE_ADDR_{core.upper_instance_name} + 2, CORE_ADDR_{core.upper_instance_name} + 3: begin - sys_read_data_mux = read_data_{core.instance_name}; - sys_error_mux = 0; + sys_read_data_mux = {core0.mux_data_reg}; + sys_error_mux = {core0.mux_error_reg}; end """ diff --git a/config/core_selector.v b/config/core_selector.v index 90b688e..0f60771 100644 --- a/config/core_selector.v +++ b/config/core_selector.v @@ -62,9 +62,6 @@ module core_selector .error(error_board_regs) ); - reg [31: 0] read_data_board_regs_reg; - always @(posedge sys_clk) - read_data_board_regs_reg <= read_data_board_regs; //---------------------------------------------------------------- @@ -88,9 +85,6 @@ module core_selector .error(error_comm_regs) ); - reg [31: 0] read_data_comm_regs_reg; - always @(posedge sys_clk) - read_data_comm_regs_reg <= read_data_comm_regs; //---------------------------------------------------------------- @@ -114,9 +108,6 @@ module core_selector .error(error_sha256) ); - reg [31: 0] read_data_sha256_reg; - always @(posedge sys_clk) - read_data_sha256_reg <= read_data_sha256; //---------------------------------------------------------------- @@ -140,9 +131,6 @@ module core_selector .error(error_aes) ); - reg [31: 0] read_data_aes_reg; - always @(posedge sys_clk) - read_data_aes_reg <= read_data_aes; //---------------------------------------------------------------- @@ -170,9 +158,6 @@ module core_selector .debug(debug) ); - reg [31: 0] read_data_trng_reg; - always @(posedge sys_clk) - read_data_trng_reg <= read_data_trng; //---------------------------------------------------------------- @@ -192,13 +177,9 @@ module core_selector .address(addr_core_reg), .write_data(sys_write_data), - .read_data(read_data_modexp), - .error(error_modexp) + .read_data(read_data_modexp) ); - reg [31: 0] read_data_modexp_reg; - always @(posedge sys_clk) - read_data_modexp_reg <= read_data_modexp; @@ -215,53 +196,53 @@ module core_selector case (addr_core_num) CORE_ADDR_BOARD_REGS: begin - sys_read_data_mux = read_data_board_regs_reg; + 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_reg; + 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_reg; + sys_read_data_mux = read_data_sha256; sys_error_mux = error_sha256; end CORE_ADDR_AES: begin - sys_read_data_mux = read_data_aes_reg; + sys_read_data_mux = read_data_aes; sys_error_mux = error_aes; end CORE_ADDR_TRNG: begin - sys_read_data_mux = read_data_trng_reg; + 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_reg; + 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_reg; + 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_reg; + 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_reg; + sys_read_data_mux = read_data_trng; sys_error_mux = error_trng; end CORE_ADDR_MODEXP: begin - sys_read_data_mux = read_data_modexp_reg; - sys_error_mux = error_modexp; + sys_read_data_mux = read_data_modexp; + sys_error_mux = 0; end default: -- cgit v1.2.3 From 47508ec70ea2c85cb1541b1c3a214439357ad735 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Tue, 29 Sep 2015 21:38:00 -0400 Subject: Attempting to optimize out the one-cycle delay didn't work, relatively low priority, so just disable the optimization for now. --- config/config.py | 11 +++++++++-- config/core_selector.v | 38 ++++++++++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/config/config.py b/config/config.py index 1c5e5d0..0f3818f 100755 --- a/config/config.py +++ b/config/config.py @@ -112,7 +112,14 @@ def main(): for core in cores: core.configure(cfg) - Core.need_one_cycle_delay = any(core.block_memory for core in cores) + if False: + + # For some reason, attempting to optimize out the delay + # code entirely results in a non-working bitstream. Don't + # know why, disabling the optimization works, so just do + # that for now. + + Core.need_one_cycle_delay = any(core.block_memory for core in cores) args.verilog.write(createModule_template.format( addrs = "".join(core.createAddr() for core in cores), @@ -170,7 +177,7 @@ class Core(object): # Class variable recording whether we need a one-cycle delay to # compensate for block memories. - need_one_cycle_delay = False + need_one_cycle_delay = True def __init__(self, name): self.name = name diff --git a/config/core_selector.v b/config/core_selector.v index 0f60771..3c0a31f 100644 --- a/config/core_selector.v +++ b/config/core_selector.v @@ -62,6 +62,9 @@ module core_selector .error(error_board_regs) ); + reg [31: 0] read_data_board_regs_reg; + always @(posedge sys_clk) + read_data_board_regs_reg <= read_data_board_regs; //---------------------------------------------------------------- @@ -85,6 +88,9 @@ module core_selector .error(error_comm_regs) ); + reg [31: 0] read_data_comm_regs_reg; + always @(posedge sys_clk) + read_data_comm_regs_reg <= read_data_comm_regs; //---------------------------------------------------------------- @@ -108,6 +114,9 @@ module core_selector .error(error_sha256) ); + reg [31: 0] read_data_sha256_reg; + always @(posedge sys_clk) + read_data_sha256_reg <= read_data_sha256; //---------------------------------------------------------------- @@ -131,6 +140,9 @@ module core_selector .error(error_aes) ); + reg [31: 0] read_data_aes_reg; + always @(posedge sys_clk) + read_data_aes_reg <= read_data_aes; //---------------------------------------------------------------- @@ -158,6 +170,9 @@ module core_selector .debug(debug) ); + reg [31: 0] read_data_trng_reg; + always @(posedge sys_clk) + read_data_trng_reg <= read_data_trng; //---------------------------------------------------------------- @@ -180,6 +195,9 @@ module core_selector .read_data(read_data_modexp) ); + reg [31: 0] read_data_modexp_reg; + always @(posedge sys_clk) + read_data_modexp_reg <= read_data_modexp; @@ -196,52 +214,52 @@ module core_selector case (addr_core_num) CORE_ADDR_BOARD_REGS: begin - sys_read_data_mux = read_data_board_regs; + sys_read_data_mux = read_data_board_regs_reg; sys_error_mux = error_board_regs; end CORE_ADDR_COMM_REGS: begin - sys_read_data_mux = read_data_comm_regs; + sys_read_data_mux = read_data_comm_regs_reg; sys_error_mux = error_comm_regs; end CORE_ADDR_SHA256: begin - sys_read_data_mux = read_data_sha256; + sys_read_data_mux = read_data_sha256_reg; sys_error_mux = error_sha256; end CORE_ADDR_AES: begin - sys_read_data_mux = read_data_aes; + sys_read_data_mux = read_data_aes_reg; sys_error_mux = error_aes; end CORE_ADDR_TRNG: begin - sys_read_data_mux = read_data_trng; + sys_read_data_mux = read_data_trng_reg; sys_error_mux = error_trng; end CORE_ADDR_AVALANCHE_ENTROPY: begin - sys_read_data_mux = read_data_trng; + sys_read_data_mux = read_data_trng_reg; sys_error_mux = error_trng; end CORE_ADDR_ROSC_ENTROPY: begin - sys_read_data_mux = read_data_trng; + sys_read_data_mux = read_data_trng_reg; sys_error_mux = error_trng; end CORE_ADDR_TRNG_MIXER: begin - sys_read_data_mux = read_data_trng; + sys_read_data_mux = read_data_trng_reg; sys_error_mux = error_trng; end CORE_ADDR_TRNG_CSPRNG: begin - sys_read_data_mux = read_data_trng; + sys_read_data_mux = read_data_trng_reg; sys_error_mux = error_trng; end CORE_ADDR_MODEXP: begin - sys_read_data_mux = read_data_modexp; + sys_read_data_mux = read_data_modexp_reg; sys_error_mux = 0; end -- cgit v1.2.3