aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/rtl/lint-dummy.v14
-rw-r--r--common/rtl/novena_regs.v4
-rw-r--r--config/config.cfg128
-rwxr-xr-xconfig/config.py543
-rw-r--r--config/core_selector.v279
-rw-r--r--config/core_vfiles.mk42
-rw-r--r--eim/build/Makefile110
-rw-r--r--eim/build/xilinx.mk16
-rw-r--r--eim/rtl/novena_eim.v4
-rw-r--r--fmc/build/Makefile109
-rw-r--r--i2c/build/Makefile102
-rw-r--r--i2c/build/xilinx.mk16
-rw-r--r--i2c/rtl/novena_i2c.v14
-rwxr-xr-xsw/Makefile2
-rwxr-xr-xsw/Makefile.i2c2
-rw-r--r--sw/aes_tester.c102
-rw-r--r--sw/capability.c145
-rw-r--r--sw/configure-fpga.sh6
-rw-r--r--sw/cryptech.h405
-rw-r--r--sw/hash.c84
-rw-r--r--sw/hash_tester.c206
-rw-r--r--sw/modexp_tester.c333
-rw-r--r--sw/modexps6_tester.c224
-rw-r--r--sw/novena-eim.c16
-rw-r--r--sw/tc_eim.c28
-rw-r--r--sw/tc_i2c.c6
-rw-r--r--sw/trng_extractor.c58
-rw-r--r--sw/trng_tester.c119
28 files changed, 2171 insertions, 946 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 4edf028..69c9bd1 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.cfg b/config/config.cfg
new file mode 100644
index 0000000..7e4571c
--- /dev/null
+++ b/config/config.cfg
@@ -0,0 +1,128 @@
+# Config file for the Cryptech Novena FPGA framework.
+#
+# 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.
+#
+# 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.
+#
+# 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.
+#
+# 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
+
+[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
+
+[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]
+requires = chacha sha512
+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]
+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
+ 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]
+error_wire = no
+vfiles =
+ math/modexp/src/rtl/adder.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/shl.v
+ math/modexp/src/rtl/shr.v
diff --git a/config/config.py b/config/config.py
new file mode 100755
index 0000000..0f3818f
--- /dev/null
+++ b/config/config.py
@@ -0,0 +1,543 @@
+#!/usr/bin/env python
+
+"""
+Generate core_selector.v and core_vfiles.mk 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'd get:
+#
+# 7 bits of core selector [16:10]
+# 10 bits of register selector [9:0]
+#
+# 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
+# contiguous "cores" with a 10-bit composite register selector.
+
+# 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. 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:
+#
+# 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:
+#
+# - 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():
+ """
+ Parse arguments and config file, generate core list, generate output.
+ """
+
+ 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")
+ 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:
+ 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 = tuple(Core.new(core) for core in cores)
+
+ core_number = 0
+ for core in cores:
+ core_number = core.assign_core_number(core_number)
+
+ cores[0].reset_high = True
+ cores[1].reset_high = True
+
+ for core in cores:
+ core.configure(cfg)
+
+ 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),
+ insts = "".join(core.createInstance() 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:
+ raise
+ 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):
+ # RawConfigParser is an old-stle class, super() doesn't work, feh.
+ return configparser.RawConfigParser.getboolean(self, 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
+ 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 = {}
+
+ # 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 = True
+
+ 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
+
+ @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
+
+ def configure(self, cfg):
+ if self.instance_number == 0:
+ 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)
+ 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):
+ 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 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)
+
+ def createAddr(self):
+ return createAddr_template.format(core = self)
+
+ 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):
+ """"
+ Override mux handling for TRNG's sub-cores.
+ """
+
+ 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):
+ """
+ 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
+ different templates, and fiddle with addresses a bit.
+
+ Mux numbers have to be dug out of the TRNG Verilog source.
+ """
+
+ # 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 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:
+ subcore.assign_core_number(self.core_number + self.subcore_parameters[subcore.name])
+ return n + 15
+
+ @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)
+
+ 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)
+
+
+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)
+ return n + 3
+
+ def createInstance(self):
+ return createInstance_template_ModExpS6.format(core = self)
+
+ def createMux(self):
+ return createMux_modexps6_template.format(core = self, core0 = self)
+
+
+# Hook special classes in as handlers for the cores that require them.
+
+Core.special_class.update(
+ trng = TRNGCore,
+ modexps6 = ModExpS6Core)
+
+
+# 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}
+ //----------------------------------------------------------------
+ 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),
+ {core.reset_pin},
+
+ .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}){core.error_port}
+ );
+
+{core.one_cycle_delay}
+
+"""
+
+# 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} + 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};
+
+ {core.name}_wrapper {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})
+ );
+
+
+"""
+
+# 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}
+ //----------------------------------------------------------------
+ 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};
+
+ {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}),
+ .error(error_{core.instance_name}),
+
+ .avalanche_noise(noise),
+ .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.
+
+createMux_template = """\
+ CORE_ADDR_{core.upper_instance_name}:
+ begin
+ sys_read_data_mux = {core0.mux_data_reg};
+ sys_error_mux = {core0.mux_error_reg};
+ 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 = {core0.mux_data_reg};
+ sys_error_mux = {core0.mux_error_reg};
+ end
+"""
+
+
+# Top-level (createModule) template.
+
+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
+//======================================================================
+"""
+
+# Template for makefile snippet listing Verilog source files.
+
+listVfiles_template = """\
+# NOTE: This file is generated; do not edit by hand.
+
+vfiles +={vfiles}
+"""
+
+# Run main program.
+
+if __name__ == "__main__":
+ main()
diff --git a/config/core_selector.v b/config/core_selector.v
new file mode 100644
index 0000000..3c0a31f
--- /dev/null
+++ b/config/core_selector.v
@@ -0,0 +1,279 @@
+// 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'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;
+
+
+ //----------------------------------------------------------------
+ // 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),
+ .rst(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),
+ .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;
+
+
+ //----------------------------------------------------------------
+ // 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),
+ .rst(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),
+ .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;
+
+
+ //----------------------------------------------------------------
+ // 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),
+ .error(error_sha256)
+ );
+
+ reg [31: 0] read_data_sha256_reg;
+ always @(posedge sys_clk)
+ read_data_sha256_reg <= 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),
+ .error(error_aes)
+ );
+
+ reg [31: 0] read_data_aes_reg;
+ always @(posedge sys_clk)
+ read_data_aes_reg <= read_data_aes;
+
+
+ //----------------------------------------------------------------
+ // TRNG
+ //----------------------------------------------------------------
+ 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;
+
+ 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),
+ .error(error_trng),
+
+ .avalanche_noise(noise),
+ .debug(debug)
+ );
+
+ reg [31: 0] read_data_trng_reg;
+ always @(posedge sys_clk)
+ read_data_trng_reg <= read_data_trng;
+
+
+ //----------------------------------------------------------------
+ // 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)
+ );
+
+ reg [31: 0] read_data_modexp_reg;
+ always @(posedge sys_clk)
+ read_data_modexp_reg <= 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_reg;
+ sys_error_mux = error_board_regs;
+ end
+ CORE_ADDR_COMM_REGS:
+ begin
+ 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_reg;
+ sys_error_mux = error_sha256;
+ end
+ CORE_ADDR_AES:
+ begin
+ 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_reg;
+ sys_error_mux = error_trng;
+ end
+ CORE_ADDR_AVALANCHE_ENTROPY:
+ begin
+ 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_reg;
+ sys_error_mux = error_trng;
+ end
+ CORE_ADDR_TRNG_MIXER:
+ begin
+ 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_reg;
+ sys_error_mux = error_trng;
+ end
+ CORE_ADDR_MODEXP:
+ begin
+ sys_read_data_mux = read_data_modexp_reg;
+ sys_error_mux = 0;
+ end
+
+ default:
+ begin
+ sys_read_data_mux = {32{1'b0}};
+ sys_error_mux = 1;
+ end
+ endcase
+
+
+endmodule
+
+
+//======================================================================
+// EOF core_selector.v
+//======================================================================
diff --git a/config/core_vfiles.mk b/config/core_vfiles.mk
new file mode 100644
index 0000000..8def572
--- /dev/null
+++ b/config/core_vfiles.mk
@@ -0,0 +1,42 @@
+# 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)/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 \
+ $(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
diff --git a/eim/build/Makefile b/eim/build/Makefile
index 678a2e5..a7eec60 100644
--- a/eim/build/Makefile
+++ b/eim/build/Makefile
@@ -1,74 +1,48 @@
-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
+# Localize all the relative path awfulness in one variable.
+
+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 xilinx.mk.
+
+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/$(project).ucf
+
+# Verilog files that always go with builds on this platform.
vfiles = \
- ../rtl/novena_eim.v \
- ../../common/rtl/novena_regs.v \
- ../../common/rtl/novena_clkmgr.v \
- ../../common/rtl/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 \
- ../../../../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/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 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
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 23f08aa..8feec20 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).
@@ -163,7 +163,7 @@ module novena_top
.noise(ct_noise),
.debug(ct_led)
- );
+ );
//----------------------------------------------------------------
diff --git a/fmc/build/Makefile b/fmc/build/Makefile
index 7c73c89..81a43d0 100644
--- a/fmc/build/Makefile
+++ b/fmc/build/Makefile
@@ -1,70 +1,47 @@
-project = novena_fmc
-vendor = xilinx
-family = spartan6
-part = xc6slx45csg324-3
-top_module = novena_fmc_top
-isedir = /opt/Xilinx/14.7/ISE_DS
-xil_env = . $(isedir)/settings64.sh
-ucf = ../ucf/$(project).ucf
+# Localize all the relative path awfulness in one variable.
+
+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 xilinx.mk.
+
+project = novena_fmc
+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/$(project).ucf
+
+# Verilog files that always go with builds on this platform.
vfiles = \
- ../rtl/novena_fmc_top.v \
- ../../common/rtl/novena_regs.v \
- ../../common/rtl/novena_clkmgr.v \
- ../../common/rtl/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 \
- ../../../../comm/fmc/src/rtl/cdc_bus_pulse.v \
- ../../../../comm/fmc/src/rtl/fmc_arbiter_cdc.v \
- ../../../../comm/fmc/src/rtl/fmc_arbiter.v \
- ../../../../comm/fmc/src/rtl/fmc_d_phy.v \
- ../../../../comm/fmc/src/rtl/fmc_indicator.v \
- ../../../../comm/fmc/src/rtl/fmc_regs.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/modexp/src/rtl/adder.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/shl.v \
- ../../../../math/modexp/src/rtl/shr.v
+ $(CORE_TREE)/platform/novena/fmc/rtl/novena_fmc_top.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/clkmgr_dcm.v \
+ $(CORE_TREE)/platform/novena/config/core_selector.v \
+ $(CORE_TREE)/comm/fmc/src/rtl/cdc_bus_pulse.v \
+ $(CORE_TREE)/comm/fmc/src/rtl/fmc_arbiter_cdc.v \
+ $(CORE_TREE)/comm/fmc/src/rtl/fmc_arbiter.v \
+ $(CORE_TREE)/comm/fmc/src/rtl/fmc_d_phy.v \
+ $(CORE_TREE)/comm/fmc/src/rtl/fmc_indicator.v \
+ $(CORE_TREE)/comm/fmc/src/rtl/fmc_regs.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 ${VERILATOR_FLAGS} $(vfiles) $(CORE_TREE)/platform/novena/common/rtl/lint-dummy.v
diff --git a/i2c/build/Makefile b/i2c/build/Makefile
index 1859da3..441b67a 100644
--- a/i2c/build/Makefile
+++ b/i2c/build/Makefile
@@ -1,70 +1,44 @@
-project = novena_i2c
-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_i2c.ucf
+# Localize all the relative path awfulness in one variable.
+
+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 xilinx.mk.
+
+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/$(project).ucf
+
+# Verilog files that always go with builds on this platform.
vfiles = \
- ../rtl/novena_i2c.v \
- ../../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 \
- ../../../../comm/i2c/src/rtl/i2c_regs.v \
- ../../../../comm/i2c/src/rtl/i2c_core.v \
- ../../../../comm/coretest/src/rtl/coretest.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/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
+ $(CORE_TREE)/platform/novena/i2c/rtl/novena_i2c.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/clkmgr_dcm.v \
+ $(CORE_TREE)/platform/novena/config/core_selector.v \
+ $(CORE_TREE)/comm/i2c/src/rtl/i2c_regs.v \
+ $(CORE_TREE)/comm/i2c/src/rtl/i2c_core.v \
+ $(CORE_TREE)/comm/coretest/src/rtl/coretest.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
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 4ea6f82..db2c203 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.
@@ -99,7 +99,7 @@ module novena_top
wire sda_pd;
wire sda_int;
-
+
wire clk = sys_clk;
// Coretest connections.
@@ -143,7 +143,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),
@@ -154,15 +154,15 @@ module novena_top
(
.clk(clk),
.reset_n(sys_rst_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),
@@ -199,7 +199,7 @@ module novena_top
.noise(ct_noise),
.debug(ct_led)
- );
+ );
//----------------------------------------------------------------
diff --git a/sw/Makefile b/sw/Makefile
index 63c9197..015f6f0 100755
--- a/sw/Makefile
+++ b/sw/Makefile
@@ -16,7 +16,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 d993883..5c69069 100755
--- a/sw/Makefile.i2c
+++ b/sw/Makefile.i2c
@@ -16,7 +16,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..051b23a
--- /dev/null
+++ b/sw/capability.c
@@ -0,0 +1,145 @@
+/*
+ * capability.c
+ * ------------
+ * This module contains code to probe the FPGA for its installed cores.
+ *
+ * Author: Paul Selkirk
+ * Copyright (c) 2015, NORDUnet A/S All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the NORDUnet nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "cryptech.h"
+
+static struct core_info *tc_probe_cores(void)
+{
+ static struct core_info *head = NULL;
+ struct core_info *tail = NULL, *node;
+ off_t offset;
+
+ if (head != NULL)
+ return head;
+
+ /* XXX could use unix linked-list macros */
+ for (offset = 0; offset < 0x10000; offset += CORE_SIZE) {
+ node = calloc(1, sizeof(struct core_info));
+ if (node == NULL) {
+ perror("malloc");
+ goto fail;
+ }
+
+ if (tc_read(offset, (uint8_t *)&node->name[0], 8) ||
+ tc_read(offset + 2, (uint8_t *)&node->version[0], 4)) {
+ fprintf(stderr, "tc_read(%04x) error\n", (unsigned int)offset);
+ free(node);
+ goto fail;
+ }
+ if (node->name[0] == 0) {
+ free(node);
+ break;
+ }
+
+ node->base = offset;
+
+ if (head == NULL) {
+ head = tail = node;
+ }
+ else {
+ tail->next = node;
+ tail = node;
+ }
+ }
+
+ return head;
+
+fail:
+ while (head) {
+ node = head;
+ head = node->next;
+ free(node);
+ }
+ return NULL;
+}
+
+static struct core_info *tc_core_find(struct core_info *node, char *name)
+{
+ struct core_info *core;
+ size_t len;
+
+ if ((name == NULL) || (*name == '\0'))
+ return node;
+
+ len = strlen(name);
+ for (core = node->next; core != NULL; core = core->next) {
+ if (strncmp(core->name, name, len) == 0)
+ return core;
+ }
+
+ return NULL;
+}
+
+struct core_info *tc_core_first(char *name)
+{
+ struct core_info *head;
+
+ head = tc_probe_cores();
+ if (head == NULL)
+ return NULL;
+
+ return tc_core_find(head, name);
+}
+
+struct core_info *tc_core_next(struct core_info *node, char *name)
+{
+ if (node == NULL) {
+ node = tc_core_first(name);
+ if (node == NULL)
+ return NULL;
+ }
+
+ return tc_core_find(node->next, name);
+}
+
+off_t tc_core_base(char *name)
+{
+ struct core_info *node;
+
+ node = tc_core_first(name);
+ if (node == NULL)
+ return 0;
+ /* 0 is the base address for the "board-regs" core, installed
+ * unconditionally at that address. Probing for any other core,
+ * and getting 0, should be considered an error.
+ */
+
+ return node->base;
+}
diff --git a/sw/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/cryptech.h b/sw/cryptech.h
index 13088b1..8fbef62 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 "
@@ -423,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"
@@ -456,6 +435,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/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 8ef4f06..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:
@@ -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/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:
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) {