aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--GNUmakefile196
-rw-r--r--core.c1
-rw-r--r--hal.h10
-rw-r--r--hal_internal.h23
-rw-r--r--hash.c2
-rw-r--r--ks.c45
-rw-r--r--rpc_client.c11
-rw-r--r--rpc_server.c2
-rw-r--r--rsa.c17
-rw-r--r--tests/GNUmakefile40
-rw-r--r--tests/test-rsa.c2
-rw-r--r--verilog_constants.h17
13 files changed, 232 insertions, 139 deletions
diff --git a/.gitignore b/.gitignore
index 7131463..1625b1a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,14 +11,15 @@ tests/test-bus
tests/test-ecdsa
tests/test-ecdsa-*.der
tests/test-hash
+tests/test-mkmif
tests/test-pbkdf2
+tests/test-rpc_get_random
+tests/test-rpc_get_version
tests/test-rpc_hash
tests/test-rpc_pkey
tests/test-rpc_server
tests/test-rsa
tests/test-rsa-*.der
tests/test-trng
-tests/test-rpc_get_version
-tests/test-rpc_get_random
utils/cores
utils/eim_peek_poke
diff --git a/GNUmakefile b/GNUmakefile
index 0b3647b..14e94c6 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -37,29 +37,61 @@ STATIC_PKEY_STATE_BLOCKS = 6
INC = hal.h hal_internal.h
LIB = libhal.a
-USAGE = "usage: make [IO_BUS=eim|i2c|fmc] [RPC_CLIENT=local|remote|mixed] [RPC_SERVER=yes] [KS=mmap|volatile|flash]"
+# Error checking on known control options, some of which allow the user entirely too much rope.
+
+USAGE := "usage: ${MAKE} [IO_BUS=eim|i2c|fmc] [RPC_MODE=none|server|client-simple|client-mixed] [KS=volatile|mmap|flash] [RPC_TRANSPORT=none|loopback|serial|daemon] [MODEXP_CORE=no|yes]"
+
+IO_BUS ?= eim
+KS ?= volatile
+RPC_MODE ?= none
+RPC_TRANSPORT ?= daemon
+MODEXP_CORE ?= no
+
+ifeq (,$(and \
+ $(filter none eim i2c fmc ,${IO_BUS}),\
+ $(filter none server client-simple client-mixed ,${RPC_MODE}),\
+ $(filter volatile mmap flash ,${KS}),\
+ $(filter none loopback serial daemon ,${RPC_TRANSPORT}),\
+ $(filter no yes ,${MODEXP_CORE})))
+ $(error ${USAGE})
+endif
+
+$(info Building libhal with configuration IO_BUS=${IO_BUS} RPC_MODE=${RPC_MODE} KS=${KS} RPC_TRANSPORT=${RPC_TRANSPORT} MODEXP_CORE=${MODEXP_CORE})
+
+# Whether the RSA code should use the ModExp | ModExpS6 | ModExpA7 core.
+
+ifeq "${MODEXP_CORE}" "yes"
+ RSA_USE_MODEXP_CORE := 1
+else
+ RSA_USE_MODEXP_CORE := 0
+endif
+
+# Object files to build, initialized with ones we always want.
+# There's a balance here between skipping files we don't strictly
+# need and reducing the number of unnecessary conditionals in this
+# makefile, so the working definition of "always want" is sometimes
+# just "building this is harmless even if we don't use it."
+
+OBJ = errorstrings.o hash.o asn1.o ecdsa.o rsa.o ${KS_OBJ}
-OBJ = errorstrings.o
-CORE_OBJ = core.o ${HASH_OBJ} ${MISC_OBJ} ${PKEY_OBJ} ${PKEY2_OBJ} ${KS_OBJ} ${IO_OBJ} ${MKMIF_OBJ}
-HASH_OBJ = hash.o
-MISC_OBJ = csprng.o pbkdf2.o
-PKEY_OBJ = asn1.o ecdsa.o rsa.o
-PKEY2_OBJ = aes_keywrap.o modexp.o
-MKMIF_OBJ = mkmif.o
+# Object files to build when we're on a platform with direct access
+# to our hardware (Verilog) cores.
+
+CORE_OBJ = core.o csprng.o pbkdf2.o aes_keywrap.o modexp.o mkmif.o ${IO_OBJ}
# I/O bus to the FPGA
#
-# IO_BUS = eim | i2c | fmc
-# eim: EIM bus from Novena
-# i2c: older I2C bus from Novena
-# fmc: FMC bus from dev-bridge and alpha boards
+# IO_BUS = none | eim | i2c | fmc
+# none: No FPGA I/O bus
+# eim: EIM bus from Novena
+# i2c: Older I2C bus from Novena
+# fmc: FMC bus from dev-bridge and alpha boards
-IO_BUS ?= eim
-ifeq (${IO_BUS},eim)
+ifeq "${IO_BUS}" "eim"
IO_OBJ = hal_io_eim.o novena-eim.o
-else ifeq (${IO_BUS},i2c)
+else ifeq "${IO_BUS}" "i2c"
IO_OBJ = hal_io_i2c.o
-else ifeq (${IO_BUS},fmc)
+else ifeq "${IO_BUS}" "fmc"
IO_OBJ = hal_io_fmc.o
endif
@@ -67,7 +99,7 @@ endif
# hard-to-debug function pointer errors. OTOH, if we're building for Linux
# (even on the Novena), we want to make it possible to build a shared library.
-ifneq (${IO_BUS},fmc)
+ifneq "${IO_BUS}" "fmc"
CFLAGS += -fPIC
endif
@@ -80,91 +112,75 @@ endif
# and we haven't yet written the flash code for the bridge board.
KS_OBJ = ks.o
-KS ?= mmap
-ifeq (${KS},mmap)
+
+ifeq "${KS}" "mmap"
KS_OBJ += ks_mmap.o
-else ifeq (${KS},volatile)
+else ifeq "${KS}" "volatile"
KS_OBJ += ks_volatile.o
-else ifeq (${KS},flash)
+else ifeq "${KS}" "flash"
KS_OBJ += ks_flash.o
endif
-# RPC_CLIENT = local | remote | mixed
-# local: Build for Novena or dev-bridge, access FPGA cores directly.
-# remote: Build for other host, communicate with RPC server.
-# mixed: Do hashing locally in software, other functions remotely.
-#
-# RPC_SERVER = yes
+# RPC_MODE = none | server | client-simple | client-mixed
+# none: Build without RPC client, use cores directly.
+# server: Build for server side of RPC (HSM), use cores directly.
+# client-simple: Build for other host, communicate with cores via RPC server.
+# client-mixed: Like client-simple but do hashing locally in software and
+# support a local keystore (for PKCS #11 public keys, etc)
#
# RPC_TRANSPORT = loopback | serial | daemon
-# loopback: communicate over loopback socket on Novena
-# serial: communicate over USB in serial pass-through mode
-# daemon: communicate over USB via a daemon, to arbitrate multiple clients
+# loopback: Communicate over loopback socket on Novena
+# serial: Communicate over USB in serial pass-through mode
+# daemon: Communicate over USB via a daemon, to arbitrate multiple clients
+#
+# Note that RPC_MODE setting also controls the RPC_CLIENT setting passed to the C
+# preprocessor via CFLAGS. Whatever we pass here must evaluate to an integer in
+# the C preprocessor: we can use symbolic names so long as they're defined as macros
+# in the C code, but we can't use things like C enum symbols.
-RPC_TRANSPORT ?= daemon
+ifneq "${RPC_MODE}" "none"
+ OBJ += rpc_api.o xdr.o
+endif
-RPC_CLIENT_OBJ = rpc_api.o rpc_client.o xdr.o
-ifeq (${RPC_TRANSPORT},loopback)
+ifeq "${RPC_TRANSPORT}" "serial"
+ OBJ += slip.o
+endif
+
+RPC_CLIENT_OBJ = rpc_client.o
+ifeq "${RPC_TRANSPORT}" "loopback"
RPC_CLIENT_OBJ += rpc_client_loopback.o
-else ifeq (${RPC_TRANSPORT},serial)
- RPC_CLIENT_OBJ += rpc_client_serial.o slip.o
-else ifeq (${RPC_TRANSPORT},daemon)
+else ifeq "${RPC_TRANSPORT}" "serial"
+ RPC_CLIENT_OBJ += rpc_client_serial.o
+else ifeq "${RPC_TRANSPORT}" "daemon"
RPC_CLIENT_OBJ += rpc_client_daemon.o
endif
RPC_DISPATCH_OBJ = rpc_hash.o rpc_misc.o rpc_pkey.o
-RPC_SERVER_OBJ = rpc_api.o rpc_server.o xdr.o ${RPC_DISPATCH_OBJ}
-ifeq (${RPC_TRANSPORT},loopback)
+RPC_SERVER_OBJ = rpc_server.o
+ifeq "${RPC_TRANSPORT}" "loopback"
RPC_SERVER_OBJ += rpc_server_loopback.o
-else ifeq (${RPC_TRANSPORT},serial)
- RPC_SERVER_OBJ += rpc_server_serial.o slip.o
-endif
-
-# Not building any of the RPC stuff, access FPGA cores directly.
-ifndef RPC_CLIENT
- ifndef RPC_SERVER
- OBJ += ${CORE_OBJ}
- endif
+else ifeq "${RPC_TRANSPORT}" "serial"
+ RPC_SERVER_OBJ += rpc_server_serial.o
endif
-# Building the RPC server.
-ifdef RPC_SERVER
- OBJ += ${CORE_OBJ} ${RPC_SERVER_OBJ}
-endif
-
-# Building the RPC client, in all its variations.
-ifdef RPC_CLIENT
+ifeq "${RPC_MODE}" "none"
+ OBJ += ${CORE_OBJ}
+ CFLAGS += -DHAL_RSA_USE_MODEXP=${RSA_USE_MODEXP_CORE}
+else ifeq "${RPC_MODE}" "server"
+ OBJ += ${CORE_OBJ} ${RPC_SERVER_OBJ} ${RPC_DISPATCH_OBJ}
+ CFLAGS += -DRPC_CLIENT=RPC_CLIENT_LOCAL -DHAL_RSA_USE_MODEXP=${RSA_USE_MODEXP_CORE}
+else ifeq "${RPC_MODE}" "client-simple"
OBJ += ${RPC_CLIENT_OBJ}
- ifeq (${RPC_CLIENT},local)
- OBJ += ${CORE_OBJ} ${RPC_DISPATCH_OBJ}
- else
- CFLAGS += -DHAL_RSA_USE_MODEXP=0
- OBJ += ${PKEY_OBJ}
- ifeq (${RPC_CLIENT},mixed)
- KS = volatile
- OBJ += ${HASH_OBJ} ${PKEY2_OBJ} ${RPC_DISPATCH_OBJ} ${KS_OBJ}
- endif
- endif
-endif
-
-# RPC client locality, for rpc_client.c. This has to be kept in sync with
-# hal_internal.h. Yeah, it's ugly, but the C preprocessor can only
-# compare integers, not strings.
-
-ifeq (${RPC_CLIENT},local)
- RPC_CLIENT_FLAG = 0
-else ifeq (${RPC_CLIENT},remote)
- RPC_CLIENT_FLAG = 1
-else ifeq (${RPC_CLIENT},mixed)
- RPC_CLIENT_FLAG = 2
-endif
-ifdef RPC_CLIENT_FLAG
-CFLAGS += -DRPC_CLIENT=${RPC_CLIENT_FLAG}
+ CFLAGS += -DRPC_CLIENT=RPC_CLIENT_REMOTE -DHAL_RSA_USE_MODEXP=0
+else ifeq "${RPC_MODE}" "client-mixed"
+ OBJ += ${RPC_CLIENT_OBJ} ${RPC_DISPATCH_OBJ}
+ CFLAGS += -DRPC_CLIENT=RPC_CLIENT_MIXED -DHAL_RSA_USE_MODEXP=0
+ KS = volatile
endif
TFMDIR := $(abspath ../thirdparty/libtfm)
-CFLAGS += -g3 -Wall -std=c99 -I${TFMDIR}
+CFLAGS += -g3 -Wall -std=c99 -Wno-strict-aliasing -I${TFMDIR}
LDFLAGS := -g3 -L${TFMDIR} -ltfm
CFLAGS += -DHAL_STATIC_HASH_STATE_BLOCKS=${STATIC_HASH_STATE_BLOCKS}
@@ -175,24 +191,17 @@ all: ${LIB}
cd tests; ${MAKE} CFLAGS='${CFLAGS} -I..' LDFLAGS='${LDFLAGS}' $@
cd utils; ${MAKE} CFLAGS='${CFLAGS} -I..' LDFLAGS='${LDFLAGS}' $@
-local:
- ${MAKE} RPC_CLIENT=local RPC_TRANSPORT=none
-
client:
- ${MAKE} RPC_CLIENT=remote
+ ${MAKE} RPC_MODE=client-simple
mixed:
- ${MAKE} RPC_CLIENT=mixed KS=volatile
+ ${MAKE} RPC_MODE=client-mixed
server:
- ${MAKE} RPC_SERVER=yes
-
-loopback:
- ${MAKE} RPC_CLIENT=remote RPC_SERVER=yes RPC_TRANSPORT=loopback
+ ${MAKE} RPC_MODE=server
daemon: cryptech_rpcd
-# ${MAKE} RPC_CLIENT=mixed RPC_TRANSPORT=daemon
- ${MAKE} RPC_CLIENT=remote RPC_TRANSPORT=daemon
+ ${MAKE} RPC_MODE=client-mixed RPC_TRANSPORT=daemon
cryptech_rpcd: daemon.o slip.o rpc_serial.o xdr.o
${CC} ${CFLAGS} -o $@ $^ ${LDFLAGS}
@@ -212,7 +221,7 @@ last_gasp_pin_internal.h:
./utils/last_gasp_default_pin >$@
test: all
- export RPC_CLIENT RPC_SERVER
+ export RPC_MODE
cd tests; ${MAKE} -k $@
clean:
@@ -227,3 +236,6 @@ tags: TAGS
TAGS: *.[ch] tests/*.[ch] utils/*.[ch]
etags $^
+
+help usage:
+ @echo ${USAGE}
diff --git a/core.c b/core.c
index b7bf3b0..ffe61e6 100644
--- a/core.c
+++ b/core.c
@@ -108,6 +108,7 @@ static int name_matches(const hal_core_t *const core, const char * const name)
static const struct { const char *name; hal_addr_t extra; } gaps[] = {
{ "csprng", 11 * CORE_SIZE }, /* empty slots after csprng */
{ "modexps6", 3 * CORE_SIZE }, /* ModexpS6 uses four slots */
+ { "modexpa7", 3 * CORE_SIZE }, /* ModexpA7 uses four slots */
};
static hal_core_t *probe_cores(void)
diff --git a/hal.h b/hal.h
index 12ed579..776acac 100644
--- a/hal.h
+++ b/hal.h
@@ -90,8 +90,14 @@
#define CHACHA_NAME "chacha "
#define CHACHA_VERSION "0.80"
-#define MODEXPS6_NAME "modexps6"
-#define MODEXPS6_VERSION "0.10"
+#define MODEXP_NAME "modexp"
+#define MODEXP_VERSION "0.10"
+
+#define MODEXPS6_NAME "modexps6"
+#define MODEXPS6_VERSION "0.10"
+
+#define MODEXPA7_NAME "modexpa7"
+#define MODEXPA7_VERSION "0.10"
#define MKMIF_NAME "mkmif "
#define MKMIF_VERSION "0.10"
diff --git a/hal_internal.h b/hal_internal.h
index 0934718..0c38c00 100644
--- a/hal_internal.h
+++ b/hal_internal.h
@@ -241,7 +241,7 @@ extern const hal_rpc_pkey_dispatch_t hal_rpc_local_pkey_dispatch, hal_rpc_remote
* See code in rpc_pkey.c for how this flag fits into the pkey handle.
*/
-#define HAL_PKEY_HANDLE_PROXIMATE_FLAG (1 << 31)
+#define HAL_PKEY_HANDLE_PROXIMATE_FLAG (1 << 31)
/*
* Keystore API.
@@ -257,9 +257,9 @@ extern const hal_rpc_pkey_dispatch_t hal_rpc_local_pkey_dispatch, hal_rpc_remote
*
* 2048-bit RSA: 1194 bytes
* 4096-bit RSA: 2351 bytes
- * 8192-bit RSA: 4655 bytes
- * EC P-256: 121 bytes
- * EC P-384: 167 bytes
+ * 8192-bit RSA: 4655 bytes
+ * EC P-256: 121 bytes
+ * EC P-384: 167 bytes
* EC P-521: 223 bytes
*
* Plus we need a bit of AES-keywrap overhead, since we're storing the
@@ -271,7 +271,7 @@ extern const hal_rpc_pkey_dispatch_t hal_rpc_local_pkey_dispatch, hal_rpc_remote
* to keep them private, they don't require tamper-protected RAM.
*/
-#define HAL_KS_WRAPPED_KEYSIZE ((4655 + 15) & ~7)
+#define HAL_KS_WRAPPED_KEYSIZE ((4655 + 15) & ~7)
#ifndef HAL_STATIC_PKEY_STATE_BLOCKS
#define HAL_STATIC_PKEY_STATE_BLOCKS 0
@@ -435,14 +435,17 @@ typedef enum {
RPC_FUNC_PKEY_RENAME,
} rpc_func_num_t;
-#define RPC_VERSION 0x00010000 /* 0.1.0.0 */
+#define RPC_VERSION 0x00010000 /* 0.1.0.0 */
-/* RPC client locality. These have to be defines rather than an enum,
+/*
+ * RPC client locality. These have to be defines rather than an enum,
* because they're handled by the preprocessor.
*/
-#define RPC_CLIENT_LOCAL 0
-#define RPC_CLIENT_REMOTE 1
-#define RPC_CLIENT_MIXED 2
+
+#define RPC_CLIENT_LOCAL 0
+#define RPC_CLIENT_REMOTE 1
+#define RPC_CLIENT_MIXED 2
+#define RPC_CLIENT_NONE 3
#endif /* _HAL_INTERNAL_H_ */
diff --git a/hash.c b/hash.c
index 225a99d..5fface0 100644
--- a/hash.c
+++ b/hash.c
@@ -1031,7 +1031,7 @@ static hal_error_t sw_hash_core_sha256(hal_hash_state_t *state)
uint32_t *H = (uint32_t *) state->core_state, S[8], W[64];
if (state->block_count == 0) {
- switch (state->driver_ctrl_mode & SHA256_MODE_MASK) {
+ switch (state->driver->ctrl_mode & SHA256_MODE_MASK) {
case SHA256_MODE_SHA_224: memcpy(H, sha224_iv, sizeof(sha224_iv)); break;
case SHA256_MODE_SHA_256: memcpy(H, sha256_iv, sizeof(sha256_iv)); break;
default: return HAL_ERROR_IMPOSSIBLE;
diff --git a/ks.c b/ks.c
index b6cb32f..d252620 100644
--- a/ks.c
+++ b/ks.c
@@ -42,12 +42,28 @@
#define KEK_LENGTH (bitsToBytes(256))
+/*
+ * In "remote" and "mixed" RPC modes we're a software only RPC client
+ * without (direct) access to secure hardware, thus there is no real
+ * point in encrypting keys. As precautions, we (a) warn about this
+ * when configured in one of these modes, and (b) refuse to store any
+ * sort of private keys.
+ */
+
+#define USE_KEK (RPC_CLIENT != RPC_CLIENT_REMOTE && RPC_CLIENT != RPC_CLIENT_MIXED)
+
+#if !USE_KEK
+#warning ks.c compiled without KEK support and will only accept public keys -- this is normal for the host-side build of libhsm
+#endif
+
static inline int acceptable_key_type(const hal_key_type_t type)
{
switch (type) {
+#if USE_KEK
case HAL_KEY_TYPE_RSA_PRIVATE:
- case HAL_KEY_TYPE_RSA_PUBLIC:
case HAL_KEY_TYPE_EC_PRIVATE:
+#endif
+ case HAL_KEY_TYPE_RSA_PUBLIC:
case HAL_KEY_TYPE_EC_PUBLIC:
return 1;
default:
@@ -96,6 +112,8 @@ hal_error_t hal_ks_store(const hal_key_type_t type,
memset(&k, 0, sizeof(k));
k.der_len = sizeof(k.der);
+#if USE_KEK
+
uint8_t kek[KEK_LENGTH];
size_t kek_len;
@@ -107,6 +125,16 @@ hal_error_t hal_ks_store(const hal_key_type_t type,
if (err != HAL_OK)
return err;
+#else /* USE_KEK */
+
+ if (der_len > k.der_len)
+ return HAL_ERROR_RESULT_TOO_LONG;
+
+ k.der_len = der_len;
+ memcpy(k.der, der, der_len);
+
+#endif /* USE_KEK */
+
assert(name_len <= sizeof(k.name));
memcpy(k.name, name, name_len);
k.name_len = name_len;
@@ -199,6 +227,9 @@ hal_error_t hal_ks_fetch(const hal_key_type_t type,
*der_len = k->der_len;
if (der != NULL) {
+
+#if USE_KEK
+
uint8_t kek[KEK_LENGTH];
size_t kek_len, der_len_;
hal_error_t err;
@@ -215,6 +246,18 @@ hal_error_t hal_ks_fetch(const hal_key_type_t type,
if (err != HAL_OK)
return err;
+
+#else /* USE_KEK */
+
+ if (k->der_len > der_max)
+ return HAL_ERROR_RESULT_TOO_LONG;
+
+ if (der_len != NULL)
+ *der_len = k->der_len;
+
+ memcpy(der, k->der, k->der_len);
+
+#endif /* USE_KEK */
}
return HAL_OK;
diff --git a/rpc_client.c b/rpc_client.c
index 3ac6d6e..c92571b 100644
--- a/rpc_client.c
+++ b/rpc_client.c
@@ -971,15 +971,14 @@ const hal_rpc_pkey_dispatch_t hal_rpc_mixed_pkey_dispatch = {
#endif /* RPC_CLIENT != RPC_CLIENT_LOCAL */
-#if RPC_CLIENT == RPC_CLIENT_LOCAL
-const hal_rpc_misc_dispatch_t * hal_rpc_misc_dispatch = &hal_rpc_local_misc_dispatch;
-const hal_rpc_hash_dispatch_t * hal_rpc_hash_dispatch = &hal_rpc_local_hash_dispatch;
-const hal_rpc_pkey_dispatch_t * hal_rpc_pkey_dispatch = &hal_rpc_local_pkey_dispatch;
-#elif RPC_CLIENT == RPC_CLIENT_REMOTE
+
+#if RPC_CLIENT == RPC_CLIENT_REMOTE
const hal_rpc_misc_dispatch_t * hal_rpc_misc_dispatch = &hal_rpc_remote_misc_dispatch;
const hal_rpc_hash_dispatch_t * hal_rpc_hash_dispatch = &hal_rpc_remote_hash_dispatch;
const hal_rpc_pkey_dispatch_t * hal_rpc_pkey_dispatch = &hal_rpc_remote_pkey_dispatch;
-#elif RPC_CLIENT == RPC_CLIENT_MIXED
+#endif
+
+#if RPC_CLIENT == RPC_CLIENT_MIXED
const hal_rpc_misc_dispatch_t * hal_rpc_misc_dispatch = &hal_rpc_remote_misc_dispatch;
const hal_rpc_hash_dispatch_t * hal_rpc_hash_dispatch = &hal_rpc_local_hash_dispatch;
const hal_rpc_pkey_dispatch_t * hal_rpc_pkey_dispatch = &hal_rpc_mixed_pkey_dispatch;
diff --git a/rpc_server.c b/rpc_server.c
index a1bca26..65ba6bb 100644
--- a/rpc_server.c
+++ b/rpc_server.c
@@ -738,9 +738,11 @@ void hal_rpc_server_main(void)
* Dispatch vectors.
*/
+#if RPC_CLIENT == RPC_CLIENT_LOCAL
const hal_rpc_misc_dispatch_t *hal_rpc_misc_dispatch = &hal_rpc_local_misc_dispatch;
const hal_rpc_hash_dispatch_t *hal_rpc_hash_dispatch = &hal_rpc_local_hash_dispatch;
const hal_rpc_pkey_dispatch_t *hal_rpc_pkey_dispatch = &hal_rpc_local_pkey_dispatch;
+#endif
hal_error_t hal_rpc_server_init(void)
{
diff --git a/rsa.c b/rsa.c
index 7269aa9..c8a1479 100644
--- a/rsa.c
+++ b/rsa.c
@@ -197,7 +197,8 @@ static hal_error_t modexp(const hal_core_t *core,
{
hal_error_t err = HAL_OK;
- if ((err = hal_core_check_name(&core, MODEXPS6_NAME)) != HAL_OK)
+ if (((err = hal_core_check_name(&core, MODEXPS6_NAME)) != HAL_OK) &&
+ ((err = hal_core_check_name(&core, MODEXPA7_NAME)) != HAL_OK))
return err;
assert(msg != NULL && exp != NULL && mod != NULL && res != NULL);
@@ -697,7 +698,7 @@ hal_error_t hal_rsa_private_key_to_der(const hal_rsa_key_t * const key,
{
hal_error_t err = HAL_OK;
- if (key == NULL || der_len == NULL || key->type != HAL_KEY_TYPE_RSA_PRIVATE)
+ if (key == NULL || key->type != HAL_KEY_TYPE_RSA_PRIVATE)
return HAL_ERROR_BAD_ARGUMENTS;
fp_int version[1] = INIT_FP_INT;
@@ -706,9 +707,9 @@ hal_error_t hal_rsa_private_key_to_der(const hal_rsa_key_t * const key,
* Calculate data length.
*/
- size_t vlen = 0;
+ size_t hlen = 0, vlen = 0;
-#define _(x) { size_t i; if ((err = hal_asn1_encode_integer(x, NULL, &i, der_max - vlen)) != HAL_OK) return err; vlen += i; }
+#define _(x) { size_t n; if ((err = hal_asn1_encode_integer(x, NULL, &n, der_max - vlen)) != HAL_OK) return err; vlen += n; }
RSAPrivateKey_fields;
#undef _
@@ -716,11 +717,11 @@ hal_error_t hal_rsa_private_key_to_der(const hal_rsa_key_t * const key,
* Encode header.
*/
- if ((err = hal_asn1_encode_header(ASN1_SEQUENCE, vlen, der, der_len, der_max)) != HAL_OK)
+ if ((err = hal_asn1_encode_header(ASN1_SEQUENCE, vlen, der, &hlen, der_max)) != HAL_OK)
return err;
- const size_t hlen = *der_len;
- *der_len += vlen;
+ if (der_len != NULL)
+ *der_len = hlen + vlen;
if (der == NULL)
return HAL_OK;
@@ -731,7 +732,7 @@ hal_error_t hal_rsa_private_key_to_der(const hal_rsa_key_t * const key,
der += hlen;
-#define _(x) { size_t i; if ((err = hal_asn1_encode_integer(x, der, &i, vlen)) != HAL_OK) return err; der += i; vlen -= i; }
+#define _(x) { size_t n; if ((err = hal_asn1_encode_integer(x, der, &n, vlen)) != HAL_OK) return err; der += n; vlen -= n; }
RSAPrivateKey_fields;
#undef _
diff --git a/tests/GNUmakefile b/tests/GNUmakefile
index 65c7a25..f4299a0 100644
--- a/tests/GNUmakefile
+++ b/tests/GNUmakefile
@@ -29,21 +29,27 @@
INC = ../hal.h
LIB = ../libhal.a
-BIN := test-aes-key-wrap test-hash test-pbkdf2 test-ecdsa test-bus test-trng test-rsa
-ifndef RPC_SERVER
- ifdef RPC_CLIENT
- ifneq (${RPC_CLIENT},local)
- # If we're only building a remote RPC client lib, don't include
- # tests that access the FPGA cores.
- BIN :=
- endif
- endif
-endif
-ifdef RPC_CLIENT
- BIN += test-rpc_hash test-rpc_pkey test-rpc_get_version test-rpc_get_random
-endif
-ifdef RPC_SERVER
- BIN += test-rpc_server
+
+# Which tests to build depends on how the library was compiled.
+
+CORE_TESTS = test-aes-key-wrap test-hash test-pbkdf2 test-ecdsa test-bus test-trng test-rsa test-mkmif
+SERVER_TESTS = test-rpc_server
+CLIENT_TESTS = test-rpc_hash test-rpc_pkey test-rpc_get_version test-rpc_get_random
+
+ALL_TESTS = ${CORE_TESTS} ${SERVER_TESTS} ${CLIENT_TESTS}
+
+ifeq "${RPC_MODE}" "none"
+
+ BIN += ${CORE_TESTS}
+
+else ifeq "${RPC_MODE}" "server"
+
+ BIN += ${CORE_TESTS} ${SERVER_TESTS}
+
+else
+
+ BIN += ${CLIENT_TESTS}
+
endif
CFLAGS = -g3 -Wall -fPIC -std=c99 -I..
@@ -53,8 +59,8 @@ all: ${BIN}
test: all
for i in ${BIN}; do (set -x; ./$$i); done
-clean:
- rm -f *.o ${BIN}
+clean distclean:
+ rm -f *.o ${ALL_TESTS}
${BIN}: %: %.o ${LIB}
${CC} ${CFLAGS} -o $@ $^ ${LDFLAGS}
diff --git a/tests/test-rsa.c b/tests/test-rsa.c
index 1fc516b..60fe2a5 100644
--- a/tests/test-rsa.c
+++ b/tests/test-rsa.c
@@ -299,6 +299,8 @@ static int test_rsa(const hal_core_t *core, const rsa_tc_t * const tc)
int main(int argc, char *argv[])
{
const hal_core_t *core = hal_core_find(MODEXPS6_NAME, NULL);
+ if (core == NULL)
+ core = hal_core_find(MODEXPA7_NAME, NULL);
const hal_core_info_t *core_info = hal_core_info(core);
if (core_info != NULL)
diff --git a/verilog_constants.h b/verilog_constants.h
index 085b973..f0ae070 100644
--- a/verilog_constants.h
+++ b/verilog_constants.h
@@ -224,6 +224,23 @@
#define MODEXPS6_ADDR_RESULT (MODEXPS6_ADDR_OPERANDS + 3 * MODEXPS6_OPERAND_WORDS)
/*
+ * ModExpA7 core. MODEXPA7_OPERAND_BITS is size in bits of largest
+ * supported modulus.
+ */
+
+#define MODEXPA7_OPERAND_BITS (4096)
+#define MODEXPA7_OPERAND_WORDS (MODEXPA7_OPERAND_BITS / 32)
+#define MODEXPA7_ADDR_REGISTERS (0 * MODEXPA7_OPERAND_WORDS)
+#define MODEXPA7_ADDR_OPERANDS (4 * MODEXPA7_OPERAND_WORDS)
+#define MODEXPA7_ADDR_MODE (MODEXPA7_ADDR_REGISTERS + 0x10)
+#define MODEXPA7_ADDR_MODULUS_WIDTH (MODEXPA7_ADDR_REGISTERS + 0x11)
+#define MODEXPA7_ADDR_EXPONENT_WIDTH (MODEXPA7_ADDR_REGISTERS + 0x12)
+#define MODEXPA7_ADDR_MODULUS (MODEXPA7_ADDR_OPERANDS + 0 * MODEXPA7_OPERAND_WORDS)
+#define MODEXPA7_ADDR_MESSAGE (MODEXPA7_ADDR_OPERANDS + 1 * MODEXPA7_OPERAND_WORDS)
+#define MODEXPA7_ADDR_EXPONENT (MODEXPA7_ADDR_OPERANDS + 2 * MODEXPA7_OPERAND_WORDS)
+#define MODEXPA7_ADDR_RESULT (MODEXPA7_ADDR_OPERANDS + 3 * MODEXPA7_OPERAND_WORDS)
+
+/*
* Utility cores.
*/