diff options
author | Fredrik Thulin <fredrik@thulin.net> | 2016-06-16 16:31:50 +0200 |
---|---|---|
committer | Fredrik Thulin <fredrik@thulin.net> | 2016-06-16 16:31:50 +0200 |
commit | 52f1eb5c3dccd47d2434e0c7a302c23363790e1d (patch) | |
tree | 788cccf19c5dec657e633c1f26020f144def9603 | |
parent | 58c3a85cbe684632e9c51d82c037708adfc6dee1 (diff) | |
parent | 1c3e4894ea9f1a6f9bc6602e6454a6efd9562efa (diff) |
Merge branch 'master' into ft-ks_flash
-rw-r--r-- | .gitignore | 5 | ||||
-rw-r--r-- | GNUmakefile | 196 | ||||
-rw-r--r-- | core.c | 1 | ||||
-rw-r--r-- | hal.h | 10 | ||||
-rw-r--r-- | hal_internal.h | 23 | ||||
-rw-r--r-- | hash.c | 2 | ||||
-rw-r--r-- | ks.c | 45 | ||||
-rw-r--r-- | rpc_client.c | 11 | ||||
-rw-r--r-- | rpc_server.c | 2 | ||||
-rw-r--r-- | rsa.c | 17 | ||||
-rw-r--r-- | tests/GNUmakefile | 40 | ||||
-rw-r--r-- | tests/test-rsa.c | 2 | ||||
-rw-r--r-- | verilog_constants.h | 17 |
13 files changed, 232 insertions, 139 deletions
@@ -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} @@ -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) @@ -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_ */ @@ -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; @@ -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) { @@ -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. */ |