diff options
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | ecdsa.c | 3 | ||||
-rw-r--r-- | hash.c | 145 | ||||
-rw-r--r-- | pbkdf2.c | 9 | ||||
-rw-r--r-- | rpc_client.c | 2 | ||||
-rw-r--r-- | rsa.c | 2 | ||||
-rw-r--r-- | slip.c | 46 | ||||
-rw-r--r-- | slip_internal.h | 1 |
8 files changed, 141 insertions, 72 deletions
@@ -225,8 +225,9 @@ server: serial: ${MAKE} RPC_MODE=client-mixed RPC_TRANSPORT=serial -daemon: - ${MAKE} RPC_MODE=client-mixed RPC_TRANSPORT=daemon ${LIB} cryptech_rpcd +daemon: mixed cryptech_rpcd + +.PHONY: client mixed server serial daemon cryptech_rpcd: daemon.o ${LIB} ${CC} ${CFLAGS} -o $@ $^ ${LDFLAGS} @@ -71,6 +71,7 @@ #include <assert.h> #include "hal.h" +#include "hal_internal.h" #include <tfm.h> #include "asn1_internal.h" @@ -83,7 +84,7 @@ #define HAL_ECDSA_DEBUG_ONLY_STATIC_TEST_VECTOR_RANDOM 0 #endif -#ifdef RPC_CLIENT +#if defined(RPC_CLIENT) && RPC_CLIENT != RPC_CLIENT_LOCAL #define hal_get_random(core, buffer, length) hal_rpc_get_random(buffer, length) #endif @@ -48,14 +48,23 @@ * for use when the Verilog cores aren't available. */ -#if RPC_CLIENT == RPC_CLIENT_MIXED -#define HAL_ENABLE_SOFTWARE_HASH_CORES 1 -#endif - #ifndef HAL_ENABLE_SOFTWARE_HASH_CORES #define HAL_ENABLE_SOFTWARE_HASH_CORES 0 #endif +/* + * Use only the software hash cores when running on remote host, without + * access to the Verilog cores. + */ + +#ifndef HAL_ONLY_USE_SOFTWARE_HASH_CORES +#define HAL_ONLY_USE_SOFTWARE_HASH_CORES 0 +#endif + +#if HAL_ONLY_USE_SOFTWARE_HASH_CORES && ! HAL_ENABLE_SOFTWARE_HASH_CORES +#error HAL_ONLY_USE_SOFTWARE_HASH_CORES && ! HAL_ENABLE_SOFTWARE_HASH_CORES +#endif + typedef hal_error_t (*sw_hash_core_t)(hal_hash_state_t *); #if HAL_ENABLE_SOFTWARE_HASH_CORES @@ -103,8 +112,8 @@ struct hal_hash_state { hal_core_t *core; const hal_hash_descriptor_t *descriptor; const hal_hash_driver_t *driver; - long long unsigned msg_length_high; /* Total data hashed in this message */ - long long unsigned msg_length_low; /* (128 bits in SHA-512 cases) */ + uint64_t msg_length_high; /* Total data hashed in this message */ + uint64_t msg_length_low; /* (128 bits in SHA-512 cases) */ uint8_t block[HAL_MAX_HASH_BLOCK_LENGTH], /* Block we're accumulating */ core_state[HAL_MAX_HASH_DIGEST_LENGTH]; /* Saved core state */ size_t block_used; /* How much of the block we've used */ @@ -219,7 +228,7 @@ const hal_hash_descriptor_t hal_hash_sha512_224[1] = {{ SHA512_BLOCK_LEN, SHA512_224_DIGEST_LEN, sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t), dalgid_sha512_224, sizeof(dalgid_sha512_224), - &sha512_224_driver, SHA512_NAME, 0 + &sha512_224_driver, SHA512_NAME, 1 }}; const hal_hash_descriptor_t hal_hash_sha512_256[1] = {{ @@ -227,7 +236,7 @@ const hal_hash_descriptor_t hal_hash_sha512_256[1] = {{ SHA512_BLOCK_LEN, SHA512_256_DIGEST_LEN, sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t), dalgid_sha512_256, sizeof(dalgid_sha512_256), - &sha512_256_driver, SHA512_NAME, 0 + &sha512_256_driver, SHA512_NAME, 1 }}; const hal_hash_descriptor_t hal_hash_sha384[1] = {{ @@ -235,7 +244,7 @@ const hal_hash_descriptor_t hal_hash_sha384[1] = {{ SHA512_BLOCK_LEN, SHA384_DIGEST_LEN, sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t), dalgid_sha384, sizeof(dalgid_sha384), - &sha384_driver, SHA512_NAME, 0 + &sha384_driver, SHA512_NAME, 1 }}; const hal_hash_descriptor_t hal_hash_sha512[1] = {{ @@ -243,7 +252,7 @@ const hal_hash_descriptor_t hal_hash_sha512[1] = {{ SHA512_BLOCK_LEN, SHA512_DIGEST_LEN, sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t), dalgid_sha512, sizeof(dalgid_sha512), - &sha512_driver, SHA512_NAME, 0 + &sha512_driver, SHA512_NAME, 1 }}; /* @@ -349,6 +358,39 @@ static inline void swytebop(void *out_, const void * const in_, const size_t n, } /* + * Internal utility to check core against descriptor, including + * attempting to locate an appropriate core if we weren't given one. + */ + +static inline hal_error_t check_core(hal_core_t **core, + const hal_hash_descriptor_t * const descriptor, + unsigned *flags) +{ + assert(descriptor != NULL && descriptor->driver != NULL); + +#if HAL_ONLY_USE_SOFTWARE_HASH_CORES + hal_error_t err = HAL_ERROR_CORE_NOT_FOUND; +#else + hal_error_t err = hal_core_alloc(descriptor->core_name, core); +#endif + +#if HAL_ENABLE_SOFTWARE_HASH_CORES + if ((err == HAL_ERROR_CORE_NOT_FOUND || err == HAL_ERROR_CORE_BUSY) && + descriptor->driver->sw_core) { + + *core = NULL; + + if (flags != NULL) + *flags |= STATE_FLAG_SOFTWARE_CORE; + + err = HAL_OK; + } +#endif /* HAL_ENABLE_SOFTWARE_HASH_CORES */ + + return err; +} + +/* * Internal utility to do whatever checking we need of a descriptor, * then extract the driver pointer in a way that works nicely with * initialization of an automatic const pointer. @@ -373,6 +415,7 @@ hal_error_t hal_hash_initialize(hal_core_t *core, const hal_hash_driver_t * const driver = check_driver(descriptor); hal_hash_state_t *state = state_buffer; unsigned flags = 0; + hal_error_t err; if (driver == NULL || state_ == NULL) return HAL_ERROR_BAD_ARGUMENTS; @@ -380,6 +423,19 @@ hal_error_t hal_hash_initialize(hal_core_t *core, if (state_buffer != NULL && state_length < descriptor->hash_state_length) return HAL_ERROR_BAD_ARGUMENTS; + if ((err = check_core(&core, descriptor, &flags)) != HAL_OK) + return err; + +#if ! HAL_ONLY_USE_SOFTWARE_HASH_CORES + /* + * If we're using a Verilog core that can save/restore state, then we + * free it after every operation, so that it can possibly be used by + * another client. + */ + if (descriptor->can_restore_state) + hal_core_free(core); +#endif + if (state_buffer == NULL && (state = alloc_static_hash_state()) == NULL) return HAL_ERROR_ALLOCATION_FAILURE; @@ -415,7 +471,7 @@ void hal_hash_cleanup(hal_hash_state_t **state_) *state_ = NULL; } -#if RPC_CLIENT != RPC_CLIENT_MIXED +#if ! HAL_ONLY_USE_SOFTWARE_HASH_CORES /* * Read hash result from core. At least for now, this also serves to @@ -473,9 +529,12 @@ static hal_error_t hash_write_block(hal_hash_state_t * const state) if (debug) fprintf(stderr, "[ %s ]\n", state->block_count == 0 ? "init" : "next"); -#if RPC_CLIENT == RPC_CLIENT_MIXED - return state->driver->sw_core(state); -#else +#if HAL_ENABLE_SOFTWARE_HASH_CORES + if ((state->flags & STATE_FLAG_SOFTWARE_CORE) != 0) + return state->driver->sw_core(state); +#endif + +#if ! HAL_ONLY_USE_SOFTWARE_HASH_CORES uint8_t ctrl_cmd[4]; hal_error_t err; @@ -506,6 +565,9 @@ static hal_error_t hash_write_block(hal_hash_state_t * const state) return hal_io_wait_valid(state->core); #endif + + /*NOTREACHED*/ + return HAL_ERROR_IMPOSSIBLE; } /* @@ -529,8 +591,10 @@ hal_error_t hal_hash_update(hal_hash_state_t *state, /* Opaque state assert(state->descriptor != NULL && state->driver != NULL); assert(state->descriptor->block_length <= sizeof(state->block)); -#if RPC_CLIENT != RPC_CLIENT_MIXED - if ((err = hal_core_alloc(state->descriptor->core_name, &state->core)) != HAL_OK) +#if ! HAL_ONLY_USE_SOFTWARE_HASH_CORES + if (((state->flags & STATE_FLAG_SOFTWARE_CORE) == 0) && + state->descriptor->can_restore_state && + (err = hal_core_alloc(state->descriptor->core_name, &state->core)) != HAL_OK) return err; #endif @@ -540,7 +604,7 @@ hal_error_t hal_hash_update(hal_hash_state_t *state, /* Opaque state */ if (debug) fprintf(stderr, "[ Full block, data_buffer_length %lu, used %lu, n %lu, msg_length %llu ]\n", - (unsigned long) data_buffer_length, (unsigned long) state->block_used, (unsigned long) n, state->msg_length_low); + (unsigned long) data_buffer_length, (unsigned long) state->block_used, (unsigned long) n, (unsigned long long)state->msg_length_low); memcpy(state->block + state->block_used, p, n); if ((state->msg_length_low += n) < n) state->msg_length_high++; @@ -558,7 +622,7 @@ hal_error_t hal_hash_update(hal_hash_state_t *state, /* Opaque state */ if (debug) fprintf(stderr, "[ Partial block, data_buffer_length %lu, used %lu, n %lu, msg_length %llu ]\n", - (unsigned long) data_buffer_length, (unsigned long) state->block_used, (unsigned long) n, state->msg_length_low); + (unsigned long) data_buffer_length, (unsigned long) state->block_used, (unsigned long) n, (unsigned long long)state->msg_length_low); assert(data_buffer_length < n); memcpy(state->block + state->block_used, p, data_buffer_length); if ((state->msg_length_low += data_buffer_length) < data_buffer_length) @@ -567,8 +631,9 @@ hal_error_t hal_hash_update(hal_hash_state_t *state, /* Opaque state } out: -#if RPC_CLIENT != RPC_CLIENT_MIXED - hal_core_free(state->core); +#if ! HAL_ONLY_USE_SOFTWARE_HASH_CORES + if (state->descriptor->can_restore_state) + hal_core_free(state->core); #endif return err; } @@ -597,8 +662,10 @@ hal_error_t hal_hash_finalize(hal_hash_state_t *state, /* Opaqu assert(state->descriptor->block_length <= sizeof(state->block)); -#if RPC_CLIENT != RPC_CLIENT_MIXED - if ((err = hal_core_alloc(NULL, &state->core)) != HAL_OK) +#if ! HAL_ONLY_USE_SOFTWARE_HASH_CORES + if (((state->flags & STATE_FLAG_SOFTWARE_CORE) == 0) && + state->descriptor->can_restore_state && + (err = hal_core_alloc(state->descriptor->core_name, &state->core)) != HAL_OK) return err; #endif @@ -617,7 +684,7 @@ hal_error_t hal_hash_finalize(hal_hash_state_t *state, /* Opaqu if ((n = state->descriptor->block_length - state->block_used) < state->driver->length_length) { if (debug) fprintf(stderr, "[ Overflow block, used %lu, n %lu, msg_length %llu ]\n", - (unsigned long) state->block_used, (unsigned long) n, state->msg_length_low); + (unsigned long) state->block_used, (unsigned long) n, (unsigned long long)state->msg_length_low); if (n > 0) memset(state->block + state->block_used, 0, n); if ((err = hash_write_block(state)) != HAL_OK) @@ -633,7 +700,7 @@ hal_error_t hal_hash_finalize(hal_hash_state_t *state, /* Opaqu memset(state->block + state->block_used, 0, n); if (debug) fprintf(stderr, "[ Final block, used %lu, n %lu, msg_length %llu ]\n", - (unsigned long) state->block_used, (unsigned long) n, state->msg_length_low); + (unsigned long) state->block_used, (unsigned long) n, (unsigned long long)state->msg_length_low); p = state->block + state->descriptor->block_length; for (i = 0; (bit_length_low || bit_length_high) && i < state->driver->length_length; i++) { *--p = (uint8_t) (bit_length_low & 0xFF); @@ -650,16 +717,22 @@ hal_error_t hal_hash_finalize(hal_hash_state_t *state, /* Opaqu state->block_count++; /* All data pushed to core, now we just need to read back the result */ -#if RPC_CLIENT == RPC_CLIENT_MIXED - swytebop(digest_buffer, state->core_state, state->descriptor->digest_length, state->driver->sw_word_size); -out: - return err; -#else - err = hash_read_digest(state->core, state->driver, digest_buffer, state->descriptor->digest_length); +#if HAL_ENABLE_SOFTWARE_HASH_CORES + if ((state->flags & STATE_FLAG_SOFTWARE_CORE) != 0) { + swytebop(digest_buffer, state->core_state, state->descriptor->digest_length, state->driver->sw_word_size); + return HAL_OK; + } +#endif +#if ! HAL_ONLY_USE_SOFTWARE_HASH_CORES + if ((state->flags & STATE_FLAG_SOFTWARE_CORE) == 0) + err = hash_read_digest(state->core, state->driver, digest_buffer, state->descriptor->digest_length); +#endif + out: +#if ! HAL_ONLY_USE_SOFTWARE_HASH_CORES hal_core_free(state->core); - return err; #endif + return err; } /* @@ -969,17 +1042,15 @@ static hal_error_t sw_hash_core_sha1(hal_hash_state_t *state) if (debug) fprintf(stderr, - "[Round %02d < a = 0x%08lx, b = 0x%08lx, c = 0x%08lx, d = 0x%08lx, e = 0x%08lx, f = 0x%08lx, k = 0x%08lx, w = 0x%08lx]\n", - i, (unsigned long) S[a], (unsigned long) S[b], (unsigned long) S[c], (unsigned long) S[d], (unsigned long) S[e], - (unsigned long) f, (unsigned long) k, (unsigned long) W[i]); + "[Round %02d < a = 0x%08x, b = 0x%08x, c = 0x%08x, d = 0x%08x, e = 0x%08x, f = 0x%08x, k = 0x%08x, w = 0x%08x]\n", + i, (unsigned)S[a], (unsigned)S[b], (unsigned)S[c], (unsigned)S[d], (unsigned)S[e], (unsigned)f, (unsigned)k, (unsigned)W[i]); S[e] = rot_l_32(S[a], 5) + f + S[e] + k + W[i]; S[b] = rot_l_32(S[b], 30); if (debug) - fprintf(stderr, "[Round %02d > a = 0x%08lx, b = 0x%08lx, c = 0x%08lx, d = 0x%08lx, e = 0x%08lx]\n", - i, (unsigned long) S[a], (unsigned long) S[b], - (unsigned long) S[c], (unsigned long) S[d], (unsigned long) S[e]); + fprintf(stderr, "[Round %02d > a = 0x%08x, b = 0x%08x, c = 0x%08x, d = 0x%08x, e = 0x%08x]\n", + i, (unsigned)S[a], (unsigned)S[b], (unsigned)S[c], (unsigned)S[d], (unsigned)S[e]); } for (int i = 0; i < 5; i++) @@ -105,15 +105,6 @@ hal_error_t hal_pbkdf2(hal_core_t *core, if ((uint64_t) derived_key_length > ((uint64_t) 0xFFFFFFFF) * descriptor->block_length) return HAL_ERROR_UNSUPPORTED_KEY; -#if 1 - /* HACK - find the second sha256 core, to avoid interfering with rpc. - * If there isn't a second one, this will set core to NULL, and - * hal_hash_initialize will find the first one. - */ - core = hal_core_find(descriptor->core_name, NULL); - core = hal_core_find(descriptor->core_name, core); -#endif - memset(result, 0, sizeof(result)); memset(mac, 0, sizeof(mac)); diff --git a/rpc_client.c b/rpc_client.c index 0183947..4adf247 100644 --- a/rpc_client.c +++ b/rpc_client.c @@ -47,7 +47,7 @@ #include <stdio.h> #define check(op) do { const hal_error_t _err_ = (op); if (_err_ != HAL_OK) { printf("%s returned %d (%s)\n", #op, _err_, hal_error_string(_err_)); return _err_; } } while (0) #else -#define check(op) do { const hal_error_t _err_ = (op); if (_err_ != HAL_OK) { return _err_; } } while (0) +#define check(op) do { const hal_error_t _err_ = (op); if (_err_ != HAL_OK) { return _err_; } } while (0) #endif #define pad(n) (((n) + 3) & ~3) @@ -86,7 +86,7 @@ #define HAL_RSA_USE_MODEXP 1 #endif -#ifdef RPC_CLIENT +#if defined(RPC_CLIENT) && RPC_CLIENT != RPC_CLIENT_LOCAL #define hal_get_random(core, buffer, length) hal_rpc_get_random(buffer, length) #endif @@ -33,8 +33,6 @@ */ -#include <stdio.h> /* perror */ - #include "slip_internal.h" /* SLIP special character codes @@ -44,9 +42,16 @@ #define ESC_END 0334 /* ESC ESC_END means END data byte */ #define ESC_ESC 0335 /* ESC ESC_ESC means ESC data byte */ -#define check_send_char(c) \ - if (hal_serial_send_char(c) != HAL_OK) \ - return perror("hal_serial_send_char"), HAL_ERROR_RPC_TRANSPORT; +#ifndef HAL_SLIP_DEBUG +#define HAL_SLIP_DEBUG 0 +#endif + +#if HAL_SLIP_DEBUG +#include <stdio.h> +#define check(op) do { const hal_error_t _err_ = (op); if (_err_ != HAL_OK) { printf("%s returned %d (%s)\n", #op, _err_, hal_error_string(_err_)); return _err_; } } while (0) +#else +#define check(op) do { const hal_error_t _err_ = (op); if (_err_ != HAL_OK) { return _err_; } } while (0) +#endif /* Send a single character with SLIP escaping. */ @@ -54,15 +59,15 @@ hal_error_t hal_slip_send_char(const uint8_t c) { switch (c) { case END: - check_send_char(ESC); - check_send_char(ESC_END); + check(hal_serial_send_char(ESC)); + check(hal_serial_send_char(ESC_END)); break; case ESC: - check_send_char(ESC); - check_send_char(ESC_ESC); + check(hal_serial_send_char(ESC)); + check(hal_serial_send_char(ESC_ESC)); break; default: - check_send_char(c); + check(hal_serial_send_char(c)); } return HAL_OK; @@ -75,7 +80,7 @@ hal_error_t hal_slip_send(const uint8_t * const buf, const size_t len) /* send an initial END character to flush out any data that may * have accumulated in the receiver due to line noise */ - check_send_char(END); + check(hal_serial_send_char(END)); /* for each byte in the packet, send the appropriate character * sequence @@ -88,25 +93,17 @@ hal_error_t hal_slip_send(const uint8_t * const buf, const size_t len) /* tell the receiver that we're done sending the packet */ - check_send_char(END); + check(hal_serial_send_char(END)); return HAL_OK; } -#define check_recv_char(c) \ - if (hal_serial_recv_char(c) != HAL_OK) \ - return perror("hal_serial_recv_char"), HAL_ERROR_RPC_TRANSPORT; - /* Receive a single character into a buffer, with SLIP un-escaping */ -hal_error_t hal_slip_recv_char(uint8_t * const buf, size_t * const len, const size_t maxlen, int * const complete) +hal_error_t hal_slip_process_char(uint8_t c, uint8_t * const buf, size_t * const len, const size_t maxlen, int * const complete) { #define buf_push(c) do { if (*len < maxlen) buf[(*len)++] = c; } while (0) static int esc_flag = 0; - uint8_t c; - hal_error_t ret = hal_serial_recv_char(&c); - if (ret != HAL_OK) - return perror("hal_slip_recv_char"), ret; *complete = 0; switch (c) { case END: @@ -138,6 +135,13 @@ hal_error_t hal_slip_recv_char(uint8_t * const buf, size_t * const len, const si return HAL_OK; } +hal_error_t hal_slip_recv_char(uint8_t * const buf, size_t * const len, const size_t maxlen, int * const complete) +{ + uint8_t c; + check(hal_serial_recv_char(&c)); + return hal_slip_process_char(c, buf, len, maxlen, complete); +} + /* Receive a message with SLIP framing, blocking mode. */ hal_error_t hal_slip_recv(uint8_t * const buf, size_t * const len, const size_t maxlen) diff --git a/slip_internal.h b/slip_internal.h index 4c36c31..46a39be 100644 --- a/slip_internal.h +++ b/slip_internal.h @@ -41,6 +41,7 @@ */ extern hal_error_t hal_slip_send_char(const uint8_t c); extern hal_error_t hal_slip_send(const uint8_t * const buf, const size_t len); +extern hal_error_t hal_slip_process_char(uint8_t c, uint8_t * const buf, size_t * const len, const size_t maxlen, int * const complete); extern hal_error_t hal_slip_recv_char(uint8_t * const buf, size_t * const len, const size_t maxlen, int * const complete); extern hal_error_t hal_slip_recv(uint8_t * const buf, size_t * const len, const size_t maxlen); |