From 79559c5041835ce6835a35265a97e291789ec0b0 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Wed, 16 Mar 2016 10:15:47 -0400 Subject: Added serial RPC transport and lots more... Added RPC function to get server version number. Substantially reworked GNUMakefile with conditionals. Renamed rpc_*() and xdr_*() to hal_*() for consistency. Moved hal_io_fmc.c from stm32 repo. --- GNUmakefile | 125 +++++++++++--- hal.h | 12 ++ hal_internal.h | 67 +++----- hal_io_fmc.c | 207 ++++++++++++++++++++++ hash.c | 2 +- rpc_api.c | 5 + rpc_client.c | 449 +++++++++++++++++++++++++----------------------- rpc_client_loopback.c | 8 +- rpc_client_serial.c | 116 +++++++++++++ rpc_hash.c | 3 +- rpc_misc.c | 8 +- rpc_server.c | 228 +++++++++++++----------- rpc_server_loopback.c | 22 +-- rpc_server_serial.c | 79 +++++++++ rpc_xdr.c | 245 -------------------------- slip.c | 141 +++++++++++++++ slip_internal.h | 51 ++++++ tests/GNUmakefile | 18 +- tests/test-rpc_hash.c | 7 +- tests/test-rpc_server.c | 10 +- xdr.c | 265 ++++++++++++++++++++++++++++ xdr_internal.h | 66 +++++++ 22 files changed, 1473 insertions(+), 661 deletions(-) create mode 100644 hal_io_fmc.c create mode 100644 rpc_client_serial.c create mode 100644 rpc_server_serial.c delete mode 100644 rpc_xdr.c create mode 100644 slip.c create mode 100644 slip_internal.h create mode 100644 xdr.c create mode 100644 xdr_internal.h diff --git a/GNUmakefile b/GNUmakefile index 0637f76..dc518b3 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,4 +1,4 @@ -# Copyright (c) 2015, NORDUnet A/S +# Copyright (c) 2015-2016, NORDUnet A/S # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -36,28 +36,98 @@ STATIC_PKEY_STATE_BLOCKS = 6 INC = hal.h hal_internal.h LIB = libhal.a -OBJ = core.o csprng.o hash.o aes_keywrap.o pbkdf2.o \ - modexp.o rsa.o ecdsa.o asn1.o errorstrings.o \ - ${IO_OBJ} ${RPC_OBJ} ${KS_OBJ} -IO_OBJ_EIM = hal_io_eim.o novena-eim.o -IO_OBJ_I2C = hal_io_i2c.o +OBJ = errorstrings.o ${CORE_OBJ} ${IO_OBJ} ${RPC_OBJ} ${KS_OBJ} +CORE_OBJ := core.o csprng.o hash.o aes_keywrap.o pbkdf2.o \ + modexp.o rsa.o ecdsa.o asn1.o -# Default I/O bus is EIM, override this to use I2C instead -IO_OBJ = ${IO_OBJ_EIM} +USAGE = "usage: make [IO_BUS=eim|i2c|fmc] [RPC_CLIENT=local|remote|mixed] [RPC_SERVER=yes] [KS=mmap|volatile|flash]" -RPC_OBJ_COMMON = rpc_api.o rpc_hash.o rpc_misc.o rpc_pkey.o rpc_xdr.o -RPC_OBJ_CLIENT = rpc_client.o rpc_client_loopback.o -RPC_OBJ_SERVER = rpc_server.o rpc_server_loopback.o - -# Default should be to build the RPC server code. We'll probably end up -# needing a makefile conditional to handle all this properly. -RPC_OBJ = ${RPC_OBJ_COMMON} ${RPC_OBJ_CLIENT} ${RPC_OBJ_SERVER} - -KS_OBJ_COMMON = ks.o -KS_OBJ_MMAP = ${KS_OBJ_COMMON} ks_mmap.o -KS_OBJ_VOLATILE = ${KS_OBJ_COMMON} ks_volatile.o -KS_OBJ_FLASH = ${KS_OBJ_COMMON} ks_flash.o +# 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 board + +IO_BUS ?= eim +ifeq (${IO_BUS},eim) + IO_OBJ = hal_io_eim.o novena-eim.o +else ifeq (${IO_BUS},i2c) + IO_OBJ = hal_io_i2c.o +else ifeq (${IO_BUS},fmc) + IO_OBJ = hal_io_fmc.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_TRANSPORT = loopback | serial +# loopback: communicate over loopback socket on Novena +# serial: communicate over USB in serial pass-through mode + +RPC_CORE_OBJ = rpc_api.o rpc_hash.o rpc_misc.o rpc_pkey.o + +ifdef RPC_SERVER + RPC_SERVER_OBJ = rpc_server.o ${RPC_CORE_OBJ} + RPC_TRANSPORT ?= serial +endif + +ifdef RPC_CLIENT + RPC_CLIENT_OBJ = rpc_client.o + ifeq (${RPC_CLIENT},local) + RPC_CLIENT_OBJ += ${RPC_CORE_OBJ} + else + RPC_TRANSPORT ?= serial + ifeq (${RPC_CLIENT},mixed) + CFLAGS += -DHAL_ENABLE_SOFTWARE_HASH_CORES + endif + ifndef RPC_SERVER + # If we're only building a remote RPC client lib, don't include + # the modules that access the FPGA cores. + CORE_OBJ := + IO_OBJ := + endif + endif +endif + +ifdef RPC_TRANSPORT + RPC_TRANSPORT_OBJ = xdr.o + ifeq (${RPC_TRANSPORT},loopback) + ifdef RPC_SERVER + RPC_TRANSPORT_OBJ += rpc_server_loopback.o + endif + ifdef RPC_CLIENT + RPC_TRANSPORT_OBJ += rpc_client_loopback.o + endif + else ifeq (${RPC_TRANSPORT},serial) + RPC_TRANSPORT_OBJ += slip.o + ifdef RPC_SERVER + RPC_TRANSPORT_OBJ += rpc_server_serial.o + endif + ifdef RPC_CLIENT + RPC_TRANSPORT_OBJ += rpc_client_serial.o + endif + endif +endif + +RPC_OBJ = ${RPC_SERVER_OBJ} ${RPC_CLIENT_OBJ} ${RPC_TRANSPORT_OBJ} + +# 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 # The mmap and flash keystore implementations are both server code. # @@ -67,7 +137,15 @@ KS_OBJ_FLASH = ${KS_OBJ_COMMON} ks_flash.o # Default at the moment is mmap, since that should work on the Novena # and we haven't yet written the flash code for the bridge board. -KS_OBJ = ${KS_OBJ_MMAP} +KS_OBJ = ks.o +KS ?= mmap +ifeq (${KS},mmap) + KS_OBJ += ks_mmap.o +else ifeq (${KS},volatile) + KS_OBJ += ks_volatile.o +else ifeq (${KS},flash) + KS_OBJ += ks_flash.o +endif TFMDIR := $(abspath ../thirdparty/libtfm) CFLAGS += -g3 -Wall -fPIC -std=c99 -I${TFMDIR} -DHAL_ECDSA_DEBUG_ONLY_STATIC_TEST_VECTOR_RANDOM=1 @@ -76,10 +154,13 @@ LDFLAGS := -g3 -L${TFMDIR} -ltfm CFLAGS += -DHAL_STATIC_HASH_STATE_BLOCKS=${STATIC_HASH_STATE_BLOCKS} CFLAGS += -DHAL_STATIC_HMAC_STATE_BLOCKS=${STATIC_HMAC_STATE_BLOCKS} CFLAGS += -DHAL_STATIC_PKEY_STATE_BLOCKS=${STATIC_PKEY_STATE_BLOCKS} +CFLAGS += -DRPC_CLIENT=${RPC_CLIENT_FLAG} all: ${LIB} cd tests; ${MAKE} CFLAGS='${CFLAGS} -I..' LDFLAGS='${LDFLAGS}' $@ +ifneq (${CORE_OBJ},) cd utils; ${MAKE} CFLAGS='${CFLAGS} -I..' LDFLAGS='${LDFLAGS}' $@ +endif ${OBJ}: ${INC} @@ -89,8 +170,10 @@ ${LIB}: ${OBJ} asn1.o rsa.o ecdsa.o: asn1_internal.h ecdsa.o: ecdsa_curves.h novena-eim.o hal_io_eim.o: novena-eim.h +slip.o rpc_client_serial.o rpc_server_serial.o: slip_internal.h test: all + export RPC_CLIENT RPC_SERVER cd tests; ${MAKE} -k $@ clean: diff --git a/hal.h b/hal.h index f3b59ad..1dd996d 100644 --- a/hal.h +++ b/hal.h @@ -561,6 +561,12 @@ extern hal_error_t hal_rpc_logout_all(void); extern hal_error_t hal_rpc_is_logged_in(const hal_client_handle_t client, const hal_user_t user); +/* + * Get the version number of the remote RPC server. + */ + +extern hal_error_t hal_rpc_get_version(uint32_t *version); + /* * Get random bytes. */ @@ -599,6 +605,12 @@ extern hal_error_t hal_rpc_hash_update(const hal_hash_handle_t hash, extern hal_error_t hal_rpc_hash_finalize(const hal_hash_handle_t hash, uint8_t *digest, const size_t length); +extern hal_error_t hal_rpc_client_init(void); +extern hal_error_t hal_rpc_client_close(void); +extern hal_error_t hal_rpc_server_init(void); +extern hal_error_t hal_rpc_server_close(void); +extern void hal_rpc_server_main(void); + /* * Public key functions. * diff --git a/hal_internal.h b/hal_internal.h index 692067e..8c0b0bc 100644 --- a/hal_internal.h +++ b/hal_internal.h @@ -102,6 +102,8 @@ typedef struct { hal_error_t (*get_random)(void *buffer, const size_t length); + hal_error_t (*get_version)(uint32_t *version); + } hal_rpc_misc_dispatch_t; @@ -326,67 +328,30 @@ extern hal_error_t hal_ks_get_pin(const hal_user_t user, extern hal_error_t hal_ks_set_pin(const hal_user_t user, const hal_ks_pin_t * const pin); -/* - * RPC serialization/deserialization routines, using XDR (RFC 4506) encoding. - */ - -hal_error_t rpc_encode_int(uint8_t ** const outbuf, - const uint8_t * const limit, - const uint32_t value); - -hal_error_t rpc_decode_int(uint8_t ** const inbuf, - const uint8_t * const limit, - uint32_t * const value); - -hal_error_t rpc_encode_buffer(uint8_t ** const outbuf, - const uint8_t * const limit, - const uint8_t * const value, - const uint32_t len); - -hal_error_t rpc_decode_buffer_in_place(uint8_t ** const inbuf, - const uint8_t * const limit, - uint8_t ** const vptr, - uint32_t * const len); - -hal_error_t rpc_decode_buffer(uint8_t ** const inbuf, - const uint8_t * const limit, - uint8_t * const value, - uint32_t * const len); - -/* XXX move to hal.h? */ -typedef enum { - RPC_LOCAL, - RPC_REMOTE, - RPC_MIXED, -} rpc_locality_t; - /* * RPC lowest-level send and receive routines. These are blocking, and * transport-specific (sockets, USB). */ -hal_error_t rpc_send(const uint8_t * const buf, const size_t len); -hal_error_t rpc_recv(uint8_t * const buf, size_t * const len); +extern hal_error_t hal_rpc_send(const uint8_t * const buf, const size_t len); +extern hal_error_t hal_rpc_recv(uint8_t * const buf, size_t * const len); -hal_error_t rpc_client_init(rpc_locality_t locality); -hal_error_t rpc_client_close(void); -hal_error_t rpc_client_transport_init(void); -hal_error_t rpc_client_transport_close(void); +extern hal_error_t hal_rpc_sendto(const uint8_t * const buf, const size_t len, void *opaque); +extern hal_error_t hal_rpc_recvfrom(uint8_t * const buf, size_t * const len, void **opaque); -hal_error_t rpc_sendto(const uint8_t * const buf, const size_t len, void *opaque); -hal_error_t rpc_recvfrom(uint8_t * const buf, size_t * const len, void **opaque); +extern hal_error_t hal_rpc_client_transport_init(void); +extern hal_error_t hal_rpc_client_transport_close(void); + +extern hal_error_t hal_rpc_server_transport_init(void); +extern hal_error_t hal_rpc_server_transport_close(void); -hal_error_t rpc_server_init(void); -hal_error_t rpc_server_close(void); -hal_error_t rpc_server_transport_init(void); -hal_error_t rpc_server_transport_close(void); -void rpc_server_main(void); /* * RPC function numbers */ typedef enum { + RPC_FUNC_GET_VERSION = 0, RPC_FUNC_GET_RANDOM, RPC_FUNC_SET_PIN, RPC_FUNC_LOGIN, @@ -414,6 +379,14 @@ typedef enum { RPC_FUNC_PKEY_LIST, } rpc_func_num_t; +#define RPC_VERSION 0x00010000 /* 0.1.0.0 */ + +/* 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 #endif /* _HAL_INTERNAL_H_ */ diff --git a/hal_io_fmc.c b/hal_io_fmc.c new file mode 100644 index 0000000..904b93f --- /dev/null +++ b/hal_io_fmc.c @@ -0,0 +1,207 @@ +/* + * hal_io_fmc.c + * ------------ + * This module contains common code to talk to the FPGA over the FMC 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: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include "stm-fmc.h" +#include "libhal/hal.h" +#include "libhal/verilog_constants.h" + +static int debug = 0; +static int inited = 0; + +#ifndef FMC_IO_TIMEOUT +#define FMC_IO_TIMEOUT 100000000 +#endif + +/* not available in arm-none-eabi libc */ +#ifdef __ARMEL__ // Little endian +static inline uint32_t htonl(uint32_t w) +{ + return + ((w & 0x000000ff) << 24) + + ((w & 0x0000ff00) << 8) + + ((w & 0x00ff0000) >> 8) + + ((w & 0xff000000) >> 24); +} +#else // Big endian +#define htonl(x) (x) +#endif +#define ntohl htonl + +static hal_error_t init(void) +{ + if (!inited) { + fmc_init(); + inited = 1; + } + return HAL_OK; +} + +/* Translate cryptech register number to FMC address. + * + * register number format: + * 3 bits segment selector + * 5 bits core selector (6 bits in native eim) + * 8 bits register selector + * + * sss ccccc rrrrrrrr => sss 0 ccccc rrrrrrrr 00 + */ +static hal_addr_t fmc_offset(hal_addr_t offset) +{ + return ((offset & ~0x1fff) << 3) + ((offset & 0x1fff) << 2); +} + +void hal_io_set_debug(int onoff) +{ + debug = onoff; +} + +static void dump(char *label, const uint8_t *buf, size_t len) +{ + if (debug) { + size_t i; + printf("%s [", label); + for (i = 0; i < len; ++i) + printf(" %02x", buf[i]); + printf(" ]\n"); + } +} + +hal_error_t hal_io_write(const hal_core_t *core, hal_addr_t offset, const uint8_t *buf, size_t len) +{ + hal_error_t err; + + if (core == NULL) + return HAL_ERROR_CORE_NOT_FOUND; + + if (len % 4 != 0) + return HAL_ERROR_IO_BAD_COUNT; + + if ((err = init()) != HAL_OK) + return err; + + dump("write ", buf, len); + + offset = fmc_offset(offset + hal_core_base(core)); + for (; len > 0; offset += 4, buf += 4, len -= 4) { + uint32_t val; + val = htonl(*(uint32_t *)buf); + fmc_write_32(offset, &val); + } + + return HAL_OK; +} + +hal_error_t hal_io_read(const hal_core_t *core, hal_addr_t offset, uint8_t *buf, size_t len) +{ + uint8_t *rbuf = buf; + int rlen = len; + hal_error_t err; + + if (core == NULL) + return HAL_ERROR_CORE_NOT_FOUND; + + if (len % 4 != 0) + return HAL_ERROR_IO_BAD_COUNT; + + if ((err = init()) != HAL_OK) + return err; + + offset = fmc_offset(offset + hal_core_base(core)); + for (; rlen > 0; offset += 4, rbuf += 4, rlen -= 4) { + uint32_t val; + fmc_read_32(offset, &val); + *(uint32_t *)rbuf = ntohl(val); + } + + dump("read ", buf, len); + + return HAL_OK; +} + +hal_error_t hal_io_init(const hal_core_t *core) +{ + uint8_t buf[4] = { 0, 0, 0, CTRL_INIT }; + return hal_io_write(core, ADDR_CTRL, buf, sizeof(buf)); +} + +hal_error_t hal_io_next(const hal_core_t *core) +{ + uint8_t buf[4] = { 0, 0, 0, CTRL_NEXT }; + return hal_io_write(core, ADDR_CTRL, buf, sizeof(buf)); +} + +hal_error_t hal_io_wait(const hal_core_t *core, uint8_t status, int *count) +{ + hal_error_t err; + uint8_t buf[4]; + int i; + + for (i = 1; ; ++i) { + + if (count && (*count > 0) && (i >= *count)) + return HAL_ERROR_IO_TIMEOUT; + + if ((err = hal_io_read(core, ADDR_STATUS, buf, sizeof(buf))) != HAL_OK) + return err; + + if ((buf[3] & status) != 0) { + if (count) + *count = i; + return HAL_OK; + } + } +} + +hal_error_t hal_io_wait_ready(const hal_core_t *core) +{ + int limit = FMC_IO_TIMEOUT; + return hal_io_wait(core, STATUS_READY, &limit); +} + +hal_error_t hal_io_wait_valid(const hal_core_t *core) +{ + int limit = FMC_IO_TIMEOUT; + return hal_io_wait(core, STATUS_VALID, &limit); +} + +/* + * Local variables: + * indent-tabs-mode: nil + * c-basic-offset: 2 + * End: + */ diff --git a/hash.c b/hash.c index 3c5f5d7..e2a7f43 100644 --- a/hash.c +++ b/hash.c @@ -3,7 +3,7 @@ * ------ * HAL interface to Cryptech hash cores. * - * Authors: Joachim Strömbergson, Paul Selkirk, Rob Austein + * Authors: Joachim Strömbergson, Paul Selkirk, Rob Austein * Copyright (c) 2014-2016, NORDUnet A/S * All rights reserved. * diff --git a/rpc_api.c b/rpc_api.c index b494ca8..a903f57 100644 --- a/rpc_api.c +++ b/rpc_api.c @@ -88,6 +88,11 @@ static inline int check_pkey_type_curve_flags(const hal_key_type_t type, } +hal_error_t hal_rpc_get_version(uint32_t *version) +{ + return hal_rpc_misc_dispatch->get_version(version); +} + hal_error_t hal_rpc_get_random(void *buffer, const size_t length) { if (buffer == NULL) diff --git a/rpc_client.c b/rpc_client.c index d58cb92..5903895 100644 --- a/rpc_client.c +++ b/rpc_client.c @@ -37,6 +37,7 @@ #include "hal.h" #include "hal_internal.h" +#include "xdr_internal.h" /* * RPC calls. @@ -46,6 +47,27 @@ #define pad(n) (((n) + 3) & ~3) +#if RPC_CLIENT != RPC_CLIENT_LOCAL + +static hal_error_t get_version(uint32_t *version) +{ + uint8_t outbuf[4], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); + uint8_t inbuf[8], *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); + size_t ilen = sizeof(inbuf); + hal_error_t ret, rpc_ret; + + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_GET_VERSION)); + check(hal_rpc_send(outbuf, optr - outbuf)); + + check(hal_rpc_recv(inbuf, &ilen)); + assert(ilen <= sizeof(inbuf)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); + if (rpc_ret == HAL_OK) { + check(hal_xdr_decode_int(&iptr, ilimit, version)); + } + return rpc_ret; +} + static hal_error_t get_random(void *buffer, const size_t length) { uint8_t outbuf[8], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); @@ -54,15 +76,15 @@ static hal_error_t get_random(void *buffer, const size_t length) uint32_t rcvlen = length; hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_GET_RANDOM)); - check(rpc_encode_int(&optr, olimit, (uint32_t)length)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_GET_RANDOM)); + check(hal_xdr_encode_int(&optr, olimit, (uint32_t)length)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { - check(rpc_decode_buffer(&iptr, ilimit, buffer, &rcvlen)); + check(hal_xdr_decode_buffer(&iptr, ilimit, buffer, &rcvlen)); // XXX check rcvlen vs length } return rpc_ret; @@ -77,15 +99,15 @@ static hal_error_t set_pin(const hal_client_handle_t client, size_t ilen = sizeof(inbuf); hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_SET_PIN)); - check(rpc_encode_int(&optr, olimit, client.handle)); - check(rpc_encode_int(&optr, olimit, user)); - check(rpc_encode_buffer(&optr, olimit, (const uint8_t *)pin, pin_len)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_SET_PIN)); + check(hal_xdr_encode_int(&optr, olimit, client.handle)); + check(hal_xdr_encode_int(&optr, olimit, user)); + check(hal_xdr_encode_buffer(&optr, olimit, (const uint8_t *)pin, pin_len)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; } @@ -112,15 +134,15 @@ static hal_error_t login(const hal_client_handle_t client, size_t ilen = sizeof(inbuf); hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_LOGIN)); - check(rpc_encode_int(&optr, olimit, client.handle)); - check(rpc_encode_int(&optr, olimit, user)); - check(rpc_encode_buffer(&optr, olimit, (const uint8_t *)pin, pin_len)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_LOGIN)); + check(hal_xdr_encode_int(&optr, olimit, client.handle)); + check(hal_xdr_encode_int(&optr, olimit, user)); + check(hal_xdr_encode_buffer(&optr, olimit, (const uint8_t *)pin, pin_len)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; } @@ -131,13 +153,13 @@ static hal_error_t logout(const hal_client_handle_t client) size_t ilen = sizeof(inbuf); hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_LOGOUT)); - check(rpc_encode_int(&optr, olimit, client.handle)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_LOGOUT)); + check(hal_xdr_encode_int(&optr, olimit, client.handle)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; } @@ -148,12 +170,12 @@ static hal_error_t logout_all(void) size_t ilen = sizeof(inbuf); hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_LOGOUT_ALL)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_LOGOUT_ALL)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; } @@ -165,14 +187,14 @@ static hal_error_t is_logged_in(const hal_client_handle_t client, size_t ilen = sizeof(inbuf); hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_IS_LOGGED_IN)); - check(rpc_encode_int(&optr, olimit, client.handle)); - check(rpc_encode_int(&optr, olimit, user)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_IS_LOGGED_IN)); + check(hal_xdr_encode_int(&optr, olimit, client.handle)); + check(hal_xdr_encode_int(&optr, olimit, user)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; } @@ -184,15 +206,15 @@ static hal_error_t hash_get_digest_len(const hal_digest_algorithm_t alg, size_t uint32_t len32; hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_HASH_GET_DIGEST_LEN)); - check(rpc_encode_int(&optr, olimit, alg)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_HASH_GET_DIGEST_LEN)); + check(hal_xdr_encode_int(&optr, olimit, alg)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { - check(rpc_decode_int(&iptr, ilimit, &len32)); + check(hal_xdr_decode_int(&iptr, ilimit, &len32)); *length = (size_t)len32; } return rpc_ret; @@ -207,16 +229,16 @@ static hal_error_t hash_get_digest_algorithm_id(const hal_digest_algorithm_t alg uint32_t len32 = len_max; hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_HASH_GET_DIGEST_LEN)); - check(rpc_encode_int(&optr, olimit, alg)); - check(rpc_encode_int(&optr, olimit, len_max)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_HASH_GET_DIGEST_LEN)); + check(hal_xdr_encode_int(&optr, olimit, alg)); + check(hal_xdr_encode_int(&optr, olimit, len_max)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { - check(rpc_decode_buffer(&iptr, ilimit, id, &len32)); + check(hal_xdr_decode_buffer(&iptr, ilimit, id, &len32)); *len = len32; } return rpc_ret; @@ -230,15 +252,15 @@ static hal_error_t hash_get_algorithm(const hal_hash_handle_t hash, hal_digest_a uint32_t alg32; hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_HASH_GET_ALGORITHM)); - check(rpc_encode_int(&optr, olimit, hash.handle)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_HASH_GET_ALGORITHM)); + check(hal_xdr_encode_int(&optr, olimit, hash.handle)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { - check(rpc_decode_int(&iptr, ilimit, &alg32)); + check(hal_xdr_decode_int(&iptr, ilimit, &alg32)); *alg = (hal_digest_algorithm_t)alg32; } return rpc_ret; @@ -255,18 +277,18 @@ static hal_error_t hash_initialize(const hal_client_handle_t client, size_t ilen = sizeof(inbuf); hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_HASH_INITIALIZE)); - check(rpc_encode_int(&optr, olimit, client.handle)); - check(rpc_encode_int(&optr, olimit, session.handle)); - check(rpc_encode_int(&optr, olimit, alg)); - check(rpc_encode_buffer(&optr, olimit, key, key_len)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_HASH_INITIALIZE)); + check(hal_xdr_encode_int(&optr, olimit, client.handle)); + check(hal_xdr_encode_int(&optr, olimit, session.handle)); + check(hal_xdr_encode_int(&optr, olimit, alg)); + check(hal_xdr_encode_buffer(&optr, olimit, key, key_len)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { - check(rpc_decode_int(&iptr, ilimit, &hash->handle)); + check(hal_xdr_decode_int(&iptr, ilimit, &hash->handle)); } return rpc_ret; } @@ -279,14 +301,14 @@ static hal_error_t hash_update(const hal_hash_handle_t hash, size_t ilen = sizeof(inbuf); hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_HASH_UPDATE)); - check(rpc_encode_int(&optr, olimit, hash.handle)); - check(rpc_encode_buffer(&optr, olimit, data, length)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_HASH_UPDATE)); + check(hal_xdr_encode_int(&optr, olimit, hash.handle)); + check(hal_xdr_encode_buffer(&optr, olimit, data, length)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; } @@ -299,16 +321,16 @@ static hal_error_t hash_finalize(const hal_hash_handle_t hash, uint32_t digest_len = length; hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_HASH_FINALIZE)); - check(rpc_encode_int(&optr, olimit, hash.handle)); - check(rpc_encode_int(&optr, olimit, length)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_HASH_FINALIZE)); + check(hal_xdr_encode_int(&optr, olimit, hash.handle)); + check(hal_xdr_encode_int(&optr, olimit, length)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { - check(rpc_decode_buffer(&iptr, ilimit, digest, &digest_len)); + check(hal_xdr_decode_buffer(&iptr, ilimit, digest, &digest_len)); /* XXX check digest_len vs length */ } return rpc_ret; @@ -328,21 +350,21 @@ static hal_error_t pkey_load(const hal_client_handle_t client, size_t ilen = sizeof(inbuf); hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_LOAD)); - check(rpc_encode_int(&optr, olimit, client.handle)); - check(rpc_encode_int(&optr, olimit, session.handle)); - check(rpc_encode_int(&optr, olimit, type)); - check(rpc_encode_int(&optr, olimit, curve)); - check(rpc_encode_buffer(&optr, olimit, name, name_len)); - check(rpc_encode_buffer(&optr, olimit, der, der_len)); - check(rpc_encode_int(&optr, olimit, flags)); - check(rpc_send(outbuf, optr - outbuf)); - - check(rpc_recv(inbuf, &ilen)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_LOAD)); + check(hal_xdr_encode_int(&optr, olimit, client.handle)); + check(hal_xdr_encode_int(&optr, olimit, session.handle)); + check(hal_xdr_encode_int(&optr, olimit, type)); + check(hal_xdr_encode_int(&optr, olimit, curve)); + check(hal_xdr_encode_buffer(&optr, olimit, name, name_len)); + check(hal_xdr_encode_buffer(&optr, olimit, der, der_len)); + check(hal_xdr_encode_int(&optr, olimit, flags)); + check(hal_rpc_send(outbuf, optr - outbuf)); + + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) - check(rpc_decode_int(&iptr, ilimit, &pkey->handle)); + check(hal_xdr_decode_int(&iptr, ilimit, &pkey->handle)); return rpc_ret; } @@ -358,18 +380,18 @@ static hal_error_t pkey_find(const hal_client_handle_t client, size_t ilen = sizeof(inbuf); hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_FIND)); - check(rpc_encode_int(&optr, olimit, client.handle)); - check(rpc_encode_int(&optr, olimit, session.handle)); - check(rpc_encode_int(&optr, olimit, type)); - check(rpc_encode_buffer(&optr, olimit, name, name_len)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_FIND)); + check(hal_xdr_encode_int(&optr, olimit, client.handle)); + check(hal_xdr_encode_int(&optr, olimit, session.handle)); + check(hal_xdr_encode_int(&optr, olimit, type)); + check(hal_xdr_encode_buffer(&optr, olimit, name, name_len)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) - check(rpc_decode_int(&iptr, ilimit, &pkey->handle)); + check(hal_xdr_decode_int(&iptr, ilimit, &pkey->handle)); return rpc_ret; } @@ -387,20 +409,20 @@ static hal_error_t pkey_generate_rsa(const hal_client_handle_t client, size_t ilen = sizeof(inbuf); hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_GENERATE_RSA)); - check(rpc_encode_int(&optr, olimit, client.handle)); - check(rpc_encode_int(&optr, olimit, session.handle)); - check(rpc_encode_buffer(&optr, olimit, name, name_len)); - check(rpc_encode_int(&optr, olimit, key_len)); - check(rpc_encode_buffer(&optr, olimit, exp, exp_len)); - check(rpc_encode_int(&optr, olimit, flags)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_GENERATE_RSA)); + check(hal_xdr_encode_int(&optr, olimit, client.handle)); + check(hal_xdr_encode_int(&optr, olimit, session.handle)); + check(hal_xdr_encode_buffer(&optr, olimit, name, name_len)); + check(hal_xdr_encode_int(&optr, olimit, key_len)); + check(hal_xdr_encode_buffer(&optr, olimit, exp, exp_len)); + check(hal_xdr_encode_int(&optr, olimit, flags)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) - check(rpc_decode_int(&iptr, ilimit, &pkey->handle)); + check(hal_xdr_decode_int(&iptr, ilimit, &pkey->handle)); return rpc_ret; } @@ -417,19 +439,19 @@ static hal_error_t pkey_generate_ec(const hal_client_handle_t client, size_t ilen = sizeof(inbuf); hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_GENERATE_EC)); - check(rpc_encode_int(&optr, olimit, client.handle)); - check(rpc_encode_int(&optr, olimit, session.handle)); - check(rpc_encode_buffer(&optr, olimit, name, name_len)); - check(rpc_encode_int(&optr, olimit, curve)); - check(rpc_encode_int(&optr, olimit, flags)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_GENERATE_EC)); + check(hal_xdr_encode_int(&optr, olimit, client.handle)); + check(hal_xdr_encode_int(&optr, olimit, session.handle)); + check(hal_xdr_encode_buffer(&optr, olimit, name, name_len)); + check(hal_xdr_encode_int(&optr, olimit, curve)); + check(hal_xdr_encode_int(&optr, olimit, flags)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) - check(rpc_decode_int(&iptr, ilimit, &pkey->handle)); + check(hal_xdr_decode_int(&iptr, ilimit, &pkey->handle)); return rpc_ret; } @@ -441,13 +463,13 @@ static hal_error_t pkey_close(const hal_pkey_handle_t pkey) size_t ilen = sizeof(inbuf); hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_CLOSE)); - check(rpc_encode_int(&optr, olimit, pkey.handle)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_CLOSE)); + check(hal_xdr_encode_int(&optr, olimit, pkey.handle)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; } @@ -458,13 +480,13 @@ static hal_error_t pkey_delete(const hal_pkey_handle_t pkey) size_t ilen = sizeof(inbuf); hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_DELETE)); - check(rpc_encode_int(&optr, olimit, pkey.handle)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_DELETE)); + check(hal_xdr_encode_int(&optr, olimit, pkey.handle)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; } @@ -477,15 +499,15 @@ static hal_error_t pkey_get_key_type(const hal_pkey_handle_t pkey, uint32_t type32; hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_GET_KEY_TYPE)); - check(rpc_encode_int(&optr, olimit, pkey.handle)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_GET_KEY_TYPE)); + check(hal_xdr_encode_int(&optr, olimit, pkey.handle)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { - check(rpc_decode_int(&iptr, ilimit, &type32)); + check(hal_xdr_decode_int(&iptr, ilimit, &type32)); *type = (hal_key_type_t)type32; } return rpc_ret; @@ -500,15 +522,15 @@ static hal_error_t pkey_get_key_flags(const hal_pkey_handle_t pkey, uint32_t flags32; hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_GET_KEY_FLAGS)); - check(rpc_encode_int(&optr, olimit, pkey.handle)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_GET_KEY_FLAGS)); + check(hal_xdr_encode_int(&optr, olimit, pkey.handle)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { - check(rpc_decode_int(&iptr, ilimit, &flags32)); + check(hal_xdr_decode_int(&iptr, ilimit, &flags32)); *flags = (hal_key_flags_t)flags32; } return rpc_ret; @@ -522,15 +544,15 @@ static size_t pkey_get_public_key_len(const hal_pkey_handle_t pkey) uint32_t len32; hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_GET_PUBLIC_KEY_LEN)); - check(rpc_encode_int(&optr, olimit, pkey.handle)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_GET_PUBLIC_KEY_LEN)); + check(hal_xdr_encode_int(&optr, olimit, pkey.handle)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { - check(rpc_decode_int(&iptr, ilimit, &len32)); + check(hal_xdr_decode_int(&iptr, ilimit, &len32)); return (size_t)len32; } else @@ -546,16 +568,16 @@ static hal_error_t pkey_get_public_key(const hal_pkey_handle_t pkey, uint32_t dlen32 = der_max; hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_GET_PUBLIC_KEY)); - check(rpc_encode_int(&optr, olimit, pkey.handle)); - check(rpc_encode_int(&optr, olimit, der_max)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_GET_PUBLIC_KEY)); + check(hal_xdr_encode_int(&optr, olimit, pkey.handle)); + check(hal_xdr_encode_int(&optr, olimit, der_max)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { - check(rpc_decode_buffer(&iptr, ilimit, der, &dlen32)); + check(hal_xdr_decode_buffer(&iptr, ilimit, der, &dlen32)); *der_len = (size_t)dlen32; } return rpc_ret; @@ -573,19 +595,19 @@ static hal_error_t pkey_remote_sign(const hal_session_handle_t session, uint32_t slen32 = signature_max; hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_REMOTE_SIGN)); - check(rpc_encode_int(&optr, olimit, session.handle)); - check(rpc_encode_int(&optr, olimit, pkey.handle)); - check(rpc_encode_int(&optr, olimit, hash.handle)); - check(rpc_encode_buffer(&optr, olimit, input, input_len)); - check(rpc_encode_int(&optr, olimit, signature_max)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_REMOTE_SIGN)); + check(hal_xdr_encode_int(&optr, olimit, session.handle)); + check(hal_xdr_encode_int(&optr, olimit, pkey.handle)); + check(hal_xdr_encode_int(&optr, olimit, hash.handle)); + check(hal_xdr_encode_buffer(&optr, olimit, input, input_len)); + check(hal_xdr_encode_int(&optr, olimit, signature_max)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { - check(rpc_decode_buffer(&iptr, ilimit, signature, &slen32)); + check(hal_xdr_decode_buffer(&iptr, ilimit, signature, &slen32)); *signature_len = (size_t)slen32; } return rpc_ret; @@ -602,29 +624,29 @@ static hal_error_t pkey_remote_verify(const hal_session_handle_t session, size_t ilen = sizeof(inbuf); hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_REMOTE_VERIFY)); - check(rpc_encode_int(&optr, olimit, session.handle)); - check(rpc_encode_int(&optr, olimit, pkey.handle)); - check(rpc_encode_int(&optr, olimit, hash.handle)); - check(rpc_encode_buffer(&optr, olimit, input, input_len)); - check(rpc_encode_buffer(&optr, olimit, signature, signature_len)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_REMOTE_VERIFY)); + check(hal_xdr_encode_int(&optr, olimit, session.handle)); + check(hal_xdr_encode_int(&optr, olimit, pkey.handle)); + check(hal_xdr_encode_int(&optr, olimit, hash.handle)); + check(hal_xdr_encode_buffer(&optr, olimit, input, input_len)); + check(hal_xdr_encode_buffer(&optr, olimit, signature, signature_len)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; } -static hal_error_t rpc_decode_pkey_info(uint8_t **iptr, const uint8_t * const ilimit, hal_pkey_info_t *info) +static hal_error_t hal_xdr_decode_pkey_info(uint8_t **iptr, const uint8_t * const ilimit, hal_pkey_info_t *info) { uint32_t i32; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &i32)); info->type = i32; - check(rpc_decode_int(iptr, ilimit, &i32)); info->curve = i32; - check(rpc_decode_int(iptr, ilimit, &i32)); info->flags = i32; - check(rpc_decode_buffer(iptr, ilimit, (uint8_t *)&info->name[0], &i32)); info->name_len = i32; + check(hal_xdr_decode_int(iptr, ilimit, &i32)); info->type = i32; + check(hal_xdr_decode_int(iptr, ilimit, &i32)); info->curve = i32; + check(hal_xdr_decode_int(iptr, ilimit, &i32)); info->flags = i32; + check(hal_xdr_decode_buffer(iptr, ilimit, (uint8_t *)&info->name[0], &i32)); info->name_len = i32; return HAL_OK; } @@ -638,19 +660,19 @@ static hal_error_t pkey_list(hal_pkey_info_t *result, uint32_t len; hal_error_t ret, rpc_ret; - check(rpc_encode_int(&optr, olimit, RPC_FUNC_PKEY_LIST)); - check(rpc_encode_int(&optr, olimit, result_max)); - check(rpc_send(outbuf, optr - outbuf)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_LIST)); + check(hal_xdr_encode_int(&optr, olimit, result_max)); + check(hal_rpc_send(outbuf, optr - outbuf)); - check(rpc_recv(inbuf, &ilen)); + check(hal_rpc_recv(inbuf, &ilen)); assert(ilen <= sizeof(inbuf)); - check(rpc_decode_int(&iptr, ilimit, &rpc_ret)); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { int i; - check(rpc_decode_int(&iptr, ilimit, &len)); + check(hal_xdr_decode_int(&iptr, ilimit, &len)); *result_len = len; for (i = 0; i < len; ++i) { - if ((ret = rpc_decode_pkey_info(&iptr, ilimit, &result[i])) != HAL_OK) { + if ((ret = hal_xdr_decode_pkey_info(&iptr, ilimit, &result[i])) != HAL_OK) { *result_len = 0; return ret; } @@ -726,7 +748,7 @@ static hal_error_t pkey_mixed_verify(const hal_session_handle_t session, */ const hal_rpc_misc_dispatch_t hal_rpc_remote_misc_dispatch = { - set_pin, login, logout, logout_all, is_logged_in, get_random + set_pin, login, logout, logout_all, is_logged_in, get_random, get_version }; const hal_rpc_hash_dispatch_t hal_rpc_remote_hash_dispatch = { @@ -748,37 +770,38 @@ const hal_rpc_pkey_dispatch_t hal_rpc_mixed_pkey_dispatch = { pkey_list }; -const hal_rpc_misc_dispatch_t * hal_rpc_misc_dispatch; -const hal_rpc_hash_dispatch_t * hal_rpc_hash_dispatch; -const hal_rpc_pkey_dispatch_t * hal_rpc_pkey_dispatch; - -hal_error_t rpc_client_init(rpc_locality_t locality) +#endif + +#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 +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 +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; //mixed? +const hal_rpc_pkey_dispatch_t * hal_rpc_pkey_dispatch = &hal_rpc_mixed_pkey_dispatch; +#endif + +hal_error_t hal_rpc_client_init(void) { - switch (locality) { - case RPC_LOCAL: - hal_rpc_misc_dispatch = &hal_rpc_local_misc_dispatch; - hal_rpc_hash_dispatch = &hal_rpc_local_hash_dispatch; - hal_rpc_pkey_dispatch = &hal_rpc_local_pkey_dispatch; - break; - case RPC_REMOTE: - hal_rpc_misc_dispatch = &hal_rpc_remote_misc_dispatch; - hal_rpc_hash_dispatch = &hal_rpc_remote_hash_dispatch; - hal_rpc_pkey_dispatch = &hal_rpc_remote_pkey_dispatch; - break; - case RPC_MIXED: - hal_rpc_misc_dispatch = &hal_rpc_remote_misc_dispatch; - hal_rpc_hash_dispatch = &hal_rpc_remote_hash_dispatch; - hal_rpc_pkey_dispatch = &hal_rpc_mixed_pkey_dispatch; - break; - default: - return HAL_ERROR_BAD_ARGUMENTS; - } - return rpc_client_transport_init(); +#if RPC_CLIENT == RPC_CLIENT_LOCAL + return HAL_OK; +#else + return hal_rpc_client_transport_init(); +#endif } -hal_error_t rpc_client_close(void) +hal_error_t hal_rpc_client_close(void) { - return rpc_client_transport_close(); +#if RPC_CLIENT == RPC_CLIENT_LOCAL + return HAL_OK; +#else + return hal_rpc_client_transport_close(); +#endif } diff --git a/rpc_client_loopback.c b/rpc_client_loopback.c index a3d7e73..b31bdd2 100644 --- a/rpc_client_loopback.c +++ b/rpc_client_loopback.c @@ -43,7 +43,7 @@ static int sock = -1; -hal_error_t rpc_client_transport_init(void) +hal_error_t hal_rpc_client_transport_init(void) { struct sockaddr_in sin; @@ -58,7 +58,7 @@ hal_error_t rpc_client_transport_init(void) return HAL_OK; } -hal_error_t rpc_client_transport_close(void) +hal_error_t hal_rpc_client_transport_close(void) { int ret = close(sock); sock = -1; @@ -67,14 +67,14 @@ hal_error_t rpc_client_transport_close(void) return HAL_OK; } -hal_error_t rpc_send(const uint8_t * const buf, const size_t len) +hal_error_t hal_rpc_send(const uint8_t * const buf, const size_t len) { if (send(sock, buf, len, 0) == -1) return perror("send"), HAL_ERROR_RPC_TRANSPORT; return HAL_OK; } -hal_error_t rpc_recv(uint8_t * const buf, size_t * const len) +hal_error_t hal_rpc_recv(uint8_t * const buf, size_t * const len) { int ret; diff --git a/rpc_client_serial.c b/rpc_client_serial.c new file mode 100644 index 0000000..d6bda1d --- /dev/null +++ b/rpc_client_serial.c @@ -0,0 +1,116 @@ +/* + * rpc_client_serial.c + * ------------------- + * Remote procedure call transport over serial line with SLIP framing. + * + * Copyright (c) 2016, NORDUnet A/S All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "hal.h" +#include "hal_internal.h" +#include "slip_internal.h" + +#define DEVICE "/dev/ttyUSB0" +#define SPEED B115200 + +static int fd = -1; + +hal_error_t hal_rpc_client_transport_init(void) +{ + struct termios tty; + + fd = open(DEVICE, O_RDWR | O_NOCTTY | O_SYNC); + if (fd == -1) + return perror("open"), HAL_ERROR_RPC_TRANSPORT; + + if (tcgetattr (fd, &tty) != 0) + return perror("tcgetattr"), HAL_ERROR_RPC_TRANSPORT; + + cfsetospeed (&tty, SPEED); + cfsetispeed (&tty, SPEED); + + tty.c_cflag &= ~CSIZE; + tty.c_cflag |= (CS8 | CLOCAL | CREAD); + + tty.c_iflag = 0; + tty.c_oflag = 0; + tty.c_lflag = 0; + + tty.c_cc[VMIN] = 1; + tty.c_cc[VTIME] = 0; + + if (tcsetattr (fd, TCSANOW, &tty) != 0) + return perror("tcsetattr"), HAL_ERROR_RPC_TRANSPORT; + + return HAL_OK; +} + +hal_error_t hal_rpc_client_transport_close(void) +{ + int ret = close(fd); + fd = -1; + if (ret != 0) + return perror("close"), HAL_ERROR_RPC_TRANSPORT; + return HAL_OK; +} + +hal_error_t hal_rpc_send(const uint8_t * const buf, const size_t len) +{ + if (hal_slip_send(buf, len) == -1) + return HAL_ERROR_RPC_TRANSPORT; + return HAL_OK; +} + +hal_error_t hal_rpc_recv(uint8_t * const buf, size_t * const len) +{ + int ret; + + if ((ret = hal_slip_recv(buf, *len)) == -1) + return HAL_ERROR_RPC_TRANSPORT; + *len = ret; + return HAL_OK; +} + +int hal_slip_send_char(const uint8_t c) +{ + return write(fd, &c, 1); +} + +int hal_slip_recv_char(uint8_t * const c) +{ + return read(fd, c, 1); +} diff --git a/rpc_hash.c b/rpc_hash.c index 1bce86e..3c4c79b 100644 --- a/rpc_hash.c +++ b/rpc_hash.c @@ -143,8 +143,9 @@ static inline handle_slot_t *find_handle(const hal_hash_handle_t handle) return NULL; } -static inline free_handle(handle_slot_t *slot) +static inline void free_handle(handle_slot_t *slot) { + if (slot != NULL) /* state is a union, so this this works for hash and hmac */ slot->state.hash = NULL; } diff --git a/rpc_misc.c b/rpc_misc.c index bcd1974..c0558da 100644 --- a/rpc_misc.c +++ b/rpc_misc.c @@ -38,6 +38,12 @@ #include "hal.h" #include "hal_internal.h" +static hal_error_t get_version(uint32_t *version) +{ + *version = RPC_VERSION; + return HAL_OK; +} + static hal_error_t get_random(void *buffer, const size_t length) { assert(buffer != NULL && length > 0); @@ -219,7 +225,7 @@ static hal_error_t logout_all(void) } const hal_rpc_misc_dispatch_t hal_rpc_local_misc_dispatch = { - set_pin, login, logout, logout_all, is_logged_in, get_random + set_pin, login, logout, logout_all, is_logged_in, get_random, get_version }; /* diff --git a/rpc_server.c b/rpc_server.c index 3447c53..d57fc57 100644 --- a/rpc_server.c +++ b/rpc_server.c @@ -34,6 +34,7 @@ #include "hal.h" #include "hal_internal.h" +#include "xdr_internal.h" /* * RPC calls. @@ -43,20 +44,36 @@ #define pad(n) (((n) + 3) & ~3) +static hal_error_t get_version(uint8_t **iptr, const uint8_t * const ilimit, + uint8_t **optr, const uint8_t * const olimit) +{ + uint32_t version; + hal_error_t ret; + + check(hal_xdr_encode_int(optr, olimit, RPC_VERSION)); + + /* call the local function */ + ret = hal_rpc_local_misc_dispatch.get_version(&version); + if (ret == HAL_OK) + check(hal_xdr_encode_int(optr, olimit, version)); + + return ret; +} + static hal_error_t get_random(uint8_t **iptr, const uint8_t * const ilimit, uint8_t **optr, const uint8_t * const olimit) { uint32_t length; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &length)); + check(hal_xdr_decode_int(iptr, ilimit, &length)); /* sanity check length */ if (length == 0 || length > olimit - *optr - 4) return HAL_ERROR_IO_BAD_COUNT; /* need a better error */ /* call the local function */ /* get the data directly into the output buffer */ - check(rpc_encode_int(optr, olimit, length)); + check(hal_xdr_encode_int(optr, olimit, length)); ret = hal_rpc_local_misc_dispatch.get_random(*optr, (size_t)length); if (ret == HAL_OK) *optr += pad(length); @@ -71,14 +88,14 @@ static hal_error_t set_pin(uint8_t **iptr, const uint8_t * const ilimit, uint8_t **optr, const uint8_t * const olimit) { hal_client_handle_t client; - hal_user_t user; + uint32_t user; uint8_t *pin; uint32_t pin_len; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &client.handle)); - check(rpc_decode_int(iptr, ilimit, &user)); - check(rpc_decode_buffer_in_place(iptr, ilimit, &pin, &pin_len)); + check(hal_xdr_decode_int(iptr, ilimit, &client.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &user)); + check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &pin, &pin_len)); /* call the local function */ ret = hal_rpc_local_misc_dispatch.set_pin(client, user, (const char * const)pin, pin_len); @@ -89,14 +106,14 @@ static hal_error_t login(uint8_t **iptr, const uint8_t * const ilimit, uint8_t **optr, const uint8_t * const olimit) { hal_client_handle_t client; - hal_user_t user; + uint32_t user; uint8_t *pin; uint32_t pin_len; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &client.handle)); - check(rpc_decode_int(iptr, ilimit, &user)); - check(rpc_decode_buffer_in_place(iptr, ilimit, &pin, &pin_len)); + check(hal_xdr_decode_int(iptr, ilimit, &client.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &user)); + check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &pin, &pin_len)); /* call the local function */ ret = hal_rpc_local_misc_dispatch.login(client, user, (const char * const)pin, pin_len); @@ -109,7 +126,7 @@ static hal_error_t logout(uint8_t **iptr, const uint8_t * const ilimit, hal_client_handle_t client; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &client.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &client.handle)); /* call the local function */ ret = hal_rpc_local_misc_dispatch.logout(client); @@ -130,11 +147,11 @@ static hal_error_t is_logged_in(uint8_t **iptr, const uint8_t * const ilimit, uint8_t **optr, const uint8_t * const olimit) { hal_client_handle_t client; - hal_user_t user; + uint32_t user; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &client.handle)); - check(rpc_decode_int(iptr, ilimit, &user)); + check(hal_xdr_decode_int(iptr, ilimit, &client.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &user)); /* call the local function */ ret = hal_rpc_local_misc_dispatch.is_logged_in(client, user); @@ -144,30 +161,30 @@ static hal_error_t is_logged_in(uint8_t **iptr, const uint8_t * const ilimit, static hal_error_t hash_get_digest_len(uint8_t **iptr, const uint8_t * const ilimit, uint8_t **optr, const uint8_t * const olimit) { - hal_digest_algorithm_t alg; + uint32_t alg; size_t length; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &alg)); + check(hal_xdr_decode_int(iptr, ilimit, &alg)); /* call the local function */ ret = hal_rpc_local_hash_dispatch.get_digest_length(alg, &length); if (ret == HAL_OK) - check(rpc_encode_int(optr, olimit, length)); + check(hal_xdr_encode_int(optr, olimit, length)); return ret; } static hal_error_t hash_get_digest_algorithm_id(uint8_t **iptr, const uint8_t * const ilimit, uint8_t **optr, const uint8_t * const olimit) { - hal_digest_algorithm_t alg; + uint32_t alg; size_t len; uint32_t len_max; uint8_t *optr_orig = *optr; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &alg)); - check(rpc_decode_int(iptr, ilimit, &len_max)); + check(hal_xdr_decode_int(iptr, ilimit, &alg)); + check(hal_xdr_decode_int(iptr, ilimit, &len_max)); /* sanity check len_max */ if (len_max > olimit - *optr - 4) return HAL_ERROR_IO_BAD_COUNT; /* need a better error */ @@ -178,7 +195,7 @@ static hal_error_t hash_get_digest_algorithm_id(uint8_t **iptr, const uint8_t * ret = hal_rpc_local_hash_dispatch.get_digest_algorithm_id(alg, *optr, &len, (size_t)len_max); if (ret == HAL_OK) { *optr = optr_orig; - check(rpc_encode_int(optr, olimit, len)); + check(hal_xdr_encode_int(optr, olimit, len)); *optr += pad(len); } else { @@ -195,12 +212,12 @@ static hal_error_t hash_get_algorithm(uint8_t **iptr, const uint8_t * const ilim hal_digest_algorithm_t alg; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &hash.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &hash.handle)); /* call the local function */ ret = hal_rpc_local_hash_dispatch.get_algorithm(hash, &alg); if (ret == HAL_OK) - check(rpc_encode_int(optr, olimit, alg)); + check(hal_xdr_encode_int(optr, olimit, alg)); return ret; } @@ -215,15 +232,15 @@ static hal_error_t hash_initialize(uint8_t **iptr, const uint8_t * const ilimit, uint32_t key_len; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &client.handle)); - check(rpc_decode_int(iptr, ilimit, &session.handle)); - check(rpc_decode_int(iptr, ilimit, &alg)); - check(rpc_decode_buffer_in_place(iptr, ilimit, &key, &key_len)); + check(hal_xdr_decode_int(iptr, ilimit, &client.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &session.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &alg)); + check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &key, &key_len)); /* call the local function */ ret = hal_rpc_local_hash_dispatch.initialize(client, session, &hash, (hal_digest_algorithm_t)alg, key, (size_t)key_len); if (ret == HAL_OK) - check(rpc_encode_int(optr, olimit, hash.handle)); + check(hal_xdr_encode_int(optr, olimit, hash.handle)); return ret; } @@ -235,8 +252,8 @@ static hal_error_t hash_update(uint8_t **iptr, const uint8_t * const ilimit, uint32_t length; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &hash.handle)); - check(rpc_decode_buffer_in_place(iptr, ilimit, &data, &length)); + check(hal_xdr_decode_int(iptr, ilimit, &hash.handle)); + check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &data, &length)); /* call the local function */ ret = hal_rpc_local_hash_dispatch.update(hash, data, (size_t)length); @@ -250,15 +267,15 @@ static hal_error_t hash_finalize(uint8_t **iptr, const uint8_t * const ilimit, uint32_t length; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &hash.handle)); - check(rpc_decode_int(iptr, ilimit, &length)); + check(hal_xdr_decode_int(iptr, ilimit, &hash.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &length)); /* sanity check length */ if (length == 0 || length > olimit - *optr - 4) return HAL_ERROR_IO_BAD_COUNT; /* need a better error */ /* call the local function */ /* get the data directly into the output buffer */ - check(rpc_encode_int(optr, olimit, length)); + check(hal_xdr_encode_int(optr, olimit, length)); ret = hal_rpc_local_hash_dispatch.finalize(hash, *optr, (size_t)length); if (ret == HAL_OK) *optr += pad(length); @@ -274,25 +291,25 @@ static hal_error_t pkey_load(uint8_t **iptr, const uint8_t * const ilimit, hal_client_handle_t client; hal_session_handle_t session; hal_pkey_handle_t pkey; - hal_key_type_t type; - hal_curve_name_t curve; + uint32_t type; + uint32_t curve; uint8_t *name, *der; uint32_t name_len, der_len; hal_key_flags_t flags; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &client.handle)); - check(rpc_decode_int(iptr, ilimit, &session.handle)); - check(rpc_decode_int(iptr, ilimit, &type)); - check(rpc_decode_int(iptr, ilimit, &curve)); - check(rpc_decode_buffer_in_place(iptr, ilimit, &name, &name_len)); - check(rpc_decode_buffer_in_place(iptr, ilimit, &der, &der_len)); - check(rpc_decode_int(iptr, ilimit, &flags)); + check(hal_xdr_decode_int(iptr, ilimit, &client.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &session.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &type)); + check(hal_xdr_decode_int(iptr, ilimit, &curve)); + check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &name, &name_len)); + check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &der, &der_len)); + check(hal_xdr_decode_int(iptr, ilimit, &flags)); /* call the local function */ ret = hal_rpc_local_pkey_dispatch.load(client, session, &pkey, type, curve, name, name_len, der, der_len, flags); if (ret == HAL_OK) - check(rpc_encode_int(optr, olimit, pkey.handle)); + check(hal_xdr_encode_int(optr, olimit, pkey.handle)); return ret; } @@ -302,20 +319,20 @@ static hal_error_t pkey_find(uint8_t **iptr, const uint8_t * const ilimit, hal_client_handle_t client; hal_session_handle_t session; hal_pkey_handle_t pkey; - hal_key_type_t type; + uint32_t type; uint8_t *name; uint32_t name_len; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &client.handle)); - check(rpc_decode_int(iptr, ilimit, &session.handle)); - check(rpc_decode_int(iptr, ilimit, &type)); - check(rpc_decode_buffer_in_place(iptr, ilimit, &name, &name_len)); + check(hal_xdr_decode_int(iptr, ilimit, &client.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &session.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &type)); + check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &name, &name_len)); /* call the local function */ ret = hal_rpc_local_pkey_dispatch.find(client, session, &pkey, type, name, name_len); if (ret == HAL_OK) - check(rpc_encode_int(optr, olimit, pkey.handle)); + check(hal_xdr_encode_int(optr, olimit, pkey.handle)); return ret; } @@ -327,23 +344,23 @@ static hal_error_t pkey_generate_rsa(uint8_t **iptr, const uint8_t * const ilimi hal_pkey_handle_t pkey; uint8_t *name; uint32_t name_len; - unsigned key_len; + uint32_t key_len; uint8_t *exp; uint32_t exp_len; hal_key_flags_t flags; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &client.handle)); - check(rpc_decode_int(iptr, ilimit, &session.handle)); - check(rpc_decode_buffer_in_place(iptr, ilimit, &name, &name_len)); - check(rpc_decode_int(iptr, ilimit, &key_len)); - check(rpc_decode_buffer_in_place(iptr, ilimit, &exp, &exp_len)); - check(rpc_decode_int(iptr, ilimit, &flags)); + check(hal_xdr_decode_int(iptr, ilimit, &client.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &session.handle)); + check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &name, &name_len)); + check(hal_xdr_decode_int(iptr, ilimit, &key_len)); + check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &exp, &exp_len)); + check(hal_xdr_decode_int(iptr, ilimit, &flags)); /* call the local function */ ret = hal_rpc_local_pkey_dispatch.generate_rsa(client, session, &pkey, name, name_len, key_len, exp, exp_len, flags); if (ret == HAL_OK) - check(rpc_encode_int(optr, olimit, pkey.handle)); + check(hal_xdr_encode_int(optr, olimit, pkey.handle)); return ret; } @@ -355,20 +372,20 @@ static hal_error_t pkey_generate_ec(uint8_t **iptr, const uint8_t * const ilimit hal_pkey_handle_t pkey; uint8_t *name; uint32_t name_len; - hal_curve_name_t curve; + uint32_t curve; hal_key_flags_t flags; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &client.handle)); - check(rpc_decode_int(iptr, ilimit, &session.handle)); - check(rpc_decode_buffer_in_place(iptr, ilimit, &name, &name_len)); - check(rpc_decode_int(iptr, ilimit, &curve)); - check(rpc_decode_int(iptr, ilimit, &flags)); + check(hal_xdr_decode_int(iptr, ilimit, &client.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &session.handle)); + check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &name, &name_len)); + check(hal_xdr_decode_int(iptr, ilimit, &curve)); + check(hal_xdr_decode_int(iptr, ilimit, &flags)); /* call the local function */ ret = hal_rpc_local_pkey_dispatch.generate_ec(client, session, &pkey, name, name_len, curve, flags); if (ret == HAL_OK) - check(rpc_encode_int(optr, olimit, pkey.handle)); + check(hal_xdr_encode_int(optr, olimit, pkey.handle)); return ret; } @@ -378,7 +395,7 @@ static hal_error_t pkey_close(uint8_t **iptr, const uint8_t * const ilimit, hal_pkey_handle_t pkey; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &pkey.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle)); /* call the local function */ ret = hal_rpc_local_pkey_dispatch.close(pkey); @@ -391,7 +408,7 @@ static hal_error_t pkey_delete(uint8_t **iptr, const uint8_t * const ilimit, hal_pkey_handle_t pkey; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &pkey.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle)); /* call the local function */ ret = hal_rpc_local_pkey_dispatch.delete(pkey); @@ -405,12 +422,12 @@ static hal_error_t pkey_get_key_type(uint8_t **iptr, const uint8_t * const ilimi hal_key_type_t type; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &pkey.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle)); /* call the local function */ ret = hal_rpc_local_pkey_dispatch.get_key_type(pkey, &type); if (ret == HAL_OK) - check(rpc_encode_int(optr, olimit, type)); + check(hal_xdr_encode_int(optr, olimit, type)); return ret; } @@ -421,12 +438,12 @@ static hal_error_t pkey_get_key_flags(uint8_t **iptr, const uint8_t * const ilim hal_key_flags_t flags; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &pkey.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle)); /* call the local function */ ret = hal_rpc_local_pkey_dispatch.get_key_flags(pkey, &flags); if (ret == HAL_OK) - check(rpc_encode_int(optr, olimit, flags)); + check(hal_xdr_encode_int(optr, olimit, flags)); return ret; } @@ -437,11 +454,11 @@ static hal_error_t pkey_get_public_key_len(uint8_t **iptr, const uint8_t * const size_t len; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &pkey.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle)); /* call the local function */ len = hal_rpc_local_pkey_dispatch.get_public_key_len(pkey); - check(rpc_encode_int(optr, olimit, len)); + check(hal_xdr_encode_int(optr, olimit, len)); return HAL_OK; } @@ -454,8 +471,8 @@ static hal_error_t pkey_get_public_key(uint8_t **iptr, const uint8_t * const ili uint8_t *optr_orig = *optr; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &pkey.handle)); - check(rpc_decode_int(iptr, ilimit, &len_max)); + check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &len_max)); /* sanity check len_max */ if (len_max > olimit - *optr - 4) return HAL_ERROR_IO_BAD_COUNT; /* need a better error */ @@ -466,7 +483,7 @@ static hal_error_t pkey_get_public_key(uint8_t **iptr, const uint8_t * const ili ret = hal_rpc_local_pkey_dispatch.get_public_key(pkey, *optr, &len, len_max); if (ret == HAL_OK) { *optr = optr_orig; - check(rpc_encode_int(optr, olimit, len)); + check(hal_xdr_encode_int(optr, olimit, len)); *optr += pad(len); } else { @@ -489,11 +506,11 @@ static hal_error_t pkey_remote_sign(uint8_t **iptr, const uint8_t * const ilimit uint8_t *optr_orig = *optr; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &session.handle)); - check(rpc_decode_int(iptr, ilimit, &pkey.handle)); - check(rpc_decode_int(iptr, ilimit, &hash.handle)); - check(rpc_decode_buffer_in_place(iptr, ilimit, &input, &input_len)); - check(rpc_decode_int(iptr, ilimit, &sig_max)); + check(hal_xdr_decode_int(iptr, ilimit, &session.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &hash.handle)); + check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &input, &input_len)); + check(hal_xdr_decode_int(iptr, ilimit, &sig_max)); /* sanity check sig_max */ if (sig_max > olimit - *optr - 4) return HAL_ERROR_IO_BAD_COUNT; /* need a better error */ @@ -504,7 +521,7 @@ static hal_error_t pkey_remote_sign(uint8_t **iptr, const uint8_t * const ilimit ret = hal_rpc_local_pkey_dispatch.sign(session, pkey, hash, input, input_len, *optr, &sig_len, sig_max); *optr = optr_orig; if (ret == HAL_OK) { - check(rpc_encode_int(optr, olimit, sig_len)); + check(hal_xdr_encode_int(optr, olimit, sig_len)); *optr += pad(sig_len); } return ret; @@ -522,26 +539,26 @@ static hal_error_t pkey_remote_verify(uint8_t **iptr, const uint8_t * const ilim uint32_t sig_len; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &session.handle)); - check(rpc_decode_int(iptr, ilimit, &pkey.handle)); - check(rpc_decode_int(iptr, ilimit, &hash.handle)); - check(rpc_decode_buffer_in_place(iptr, ilimit, &input, &input_len)); - check(rpc_decode_buffer_in_place(iptr, ilimit, &sig, &sig_len)); + check(hal_xdr_decode_int(iptr, ilimit, &session.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle)); + check(hal_xdr_decode_int(iptr, ilimit, &hash.handle)); + check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &input, &input_len)); + check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &sig, &sig_len)); /* call the local function */ ret = hal_rpc_local_pkey_dispatch.verify(session, pkey, hash, input, input_len, sig, sig_len); return ret; } -static hal_error_t rpc_encode_pkey_info(uint8_t **optr, const uint8_t * const olimit, const hal_pkey_info_t *info) +static hal_error_t hal_xdr_encode_pkey_info(uint8_t **optr, const uint8_t * const olimit, const hal_pkey_info_t *info) { uint8_t *optr_orig = *optr; hal_error_t ret; - if ((ret = rpc_encode_int(optr, olimit, info->type)) != HAL_OK || - (ret = rpc_encode_int(optr, olimit, info->curve)) != HAL_OK || - (ret = rpc_encode_int(optr, olimit, info->flags)) != HAL_OK || - (ret = rpc_encode_buffer(optr, olimit, (uint8_t *)&info->name[0], info->name_len)) != HAL_OK) + if ((ret = hal_xdr_encode_int(optr, olimit, info->type)) != HAL_OK || + (ret = hal_xdr_encode_int(optr, olimit, info->curve)) != HAL_OK || + (ret = hal_xdr_encode_int(optr, olimit, info->flags)) != HAL_OK || + (ret = hal_xdr_encode_buffer(optr, olimit, (uint8_t *)&info->name[0], info->name_len)) != HAL_OK) *optr = optr_orig; return ret; } @@ -554,7 +571,7 @@ static hal_error_t pkey_list(uint8_t **iptr, const uint8_t * const ilimit, uint32_t result_max; hal_error_t ret; - check(rpc_decode_int(iptr, ilimit, &result_max)); + check(hal_xdr_decode_int(iptr, ilimit, &result_max)); hal_pkey_info_t result[result_max]; unsigned result_len; @@ -563,9 +580,9 @@ static hal_error_t pkey_list(uint8_t **iptr, const uint8_t * const ilimit, ret = hal_rpc_local_pkey_dispatch.list(result, &result_len, result_max); if (ret == HAL_OK) { int i; - check(rpc_encode_int(optr, olimit, result_len)); + check(hal_xdr_encode_int(optr, olimit, result_len)); for (i = 0; i < result_len; ++i) { - if ((ret = rpc_encode_pkey_info(optr, olimit, &result[i])) != HAL_OK) { + if ((ret = hal_xdr_encode_pkey_info(optr, olimit, &result[i])) != HAL_OK) { *optr = optr_orig; break; } @@ -577,24 +594,27 @@ static hal_error_t pkey_list(uint8_t **iptr, const uint8_t * const ilimit, #define MAX_PKT_SIZE 1024 #define interrupt 0 -void rpc_server_main(void) +void hal_rpc_server_main(void) { uint8_t inbuf[MAX_PKT_SIZE], outbuf[MAX_PKT_SIZE]; uint8_t *iptr, *ilimit, *optr, *olimit; size_t ilen, olen; - rpc_func_num_t rpc_func_num; + uint32_t rpc_func_num; void *opaque; hal_error_t ret; while (!interrupt) { ilen = sizeof(inbuf); - if (rpc_recvfrom(inbuf, &ilen, &opaque) == HAL_OK) { + if (hal_rpc_recvfrom(inbuf, &ilen, &opaque) == HAL_OK) { iptr = inbuf; ilimit = inbuf + ilen; optr = outbuf + 4; /* reserve 4 bytes for return code */ olimit = outbuf + sizeof(outbuf); - rpc_decode_int(&iptr, ilimit, &rpc_func_num); + hal_xdr_decode_int(&iptr, ilimit, &rpc_func_num); switch (rpc_func_num) { + case RPC_FUNC_GET_VERSION: + ret = get_version(&iptr, ilimit, &optr, olimit); + break; case RPC_FUNC_GET_RANDOM: ret = get_random(&iptr, ilimit, &optr, olimit); break; @@ -677,8 +697,8 @@ void rpc_server_main(void) /* encode the return code at the beginning of the payload */ olen = optr - outbuf; optr = outbuf; - rpc_encode_int(&optr, olimit, ret); - rpc_sendto(outbuf, olen, opaque); + hal_xdr_encode_int(&optr, olimit, ret); + hal_rpc_sendto(outbuf, olen, opaque); } } } @@ -691,14 +711,14 @@ const hal_rpc_misc_dispatch_t *hal_rpc_misc_dispatch = &hal_rpc_local_misc_dispa 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; -hal_error_t rpc_server_init(void) +hal_error_t hal_rpc_server_init(void) { - return rpc_server_transport_init(); + return hal_rpc_server_transport_init(); } -hal_error_t rpc_server_close(void) +hal_error_t hal_rpc_server_close(void) { - return rpc_server_transport_close(); + return hal_rpc_server_transport_close(); } diff --git a/rpc_server_loopback.c b/rpc_server_loopback.c index a39e12b..4ca7467 100644 --- a/rpc_server_loopback.c +++ b/rpc_server_loopback.c @@ -41,47 +41,47 @@ #include "hal.h" #include "hal_internal.h" -static int sock; +static int fd; -hal_error_t rpc_server_transport_init(void) +hal_error_t hal_rpc_server_transport_init(void) { struct sockaddr_in sin; - sock = socket(AF_INET, SOCK_DGRAM, 0); - if (sock == -1) + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd == -1) return perror("socket"), HAL_ERROR_RPC_TRANSPORT; sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); sin.sin_port = 17425; - if (bind(sock, (const struct sockaddr *)&sin, sizeof(sin)) != 0) + if (bind(fd, (const struct sockaddr *)&sin, sizeof(sin)) != 0) return perror("bind"), HAL_ERROR_RPC_TRANSPORT; return HAL_OK; } -hal_error_t rpc_server_transport_close(void) +hal_error_t hal_rpc_server_transport_close(void) { - if (close(sock) != 0) + if (close(fd) != 0) return perror("close"), HAL_ERROR_RPC_TRANSPORT; return HAL_OK; } -hal_error_t rpc_sendto(const uint8_t * const buf, const size_t len, void *opaque) +hal_error_t hal_rpc_sendto(const uint8_t * const buf, const size_t len, void *opaque) { struct sockaddr_in *sin = (struct sockaddr_in *)opaque; int ret; - if ((ret = sendto(sock, buf, len, 0, (struct sockaddr *)sin, sizeof(*sin))) == -1) + if ((ret = sendto(fd, buf, len, 0, (struct sockaddr *)sin, sizeof(*sin))) == -1) return perror("sendto"), HAL_ERROR_RPC_TRANSPORT; return HAL_OK; } -hal_error_t rpc_recvfrom(uint8_t * const buf, size_t * const len, void **opaque) +hal_error_t hal_rpc_recvfrom(uint8_t * const buf, size_t * const len, void **opaque) { static struct sockaddr_in sin; socklen_t sin_len = sizeof(sin); int ret; - if ((ret = recvfrom(sock, buf, *len, 0, (struct sockaddr *)&sin, &sin_len)) == -1) + if ((ret = recvfrom(fd, buf, *len, 0, (struct sockaddr *)&sin, &sin_len)) == -1) return HAL_ERROR_RPC_TRANSPORT; *opaque = (void *)&sin; *len = ret; diff --git a/rpc_server_serial.c b/rpc_server_serial.c new file mode 100644 index 0000000..d896700 --- /dev/null +++ b/rpc_server_serial.c @@ -0,0 +1,79 @@ +/* + * rpc_server_serial.c + * ------------------- + * Remote procedure call transport over serial line with SLIP framing. + * + * Copyright (c) 2016, 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 "hal.h" +#include "hal_internal.h" +#include "slip_internal.h" + +/* Don't include stm-uart.h to avoid conflicting definitions of HAL_OK. + */ +extern int uart_send_char(uint8_t ch); +extern int uart_recv_char(uint8_t *cp); + +hal_error_t hal_rpc_server_transport_init(void) +{ + return HAL_OK; +} + +hal_error_t hal_rpc_server_transport_close(void) +{ + return HAL_OK; +} + +hal_error_t hal_rpc_sendto(const uint8_t * const buf, const size_t len, void *opaque) +{ + if (hal_slip_send(buf, len) == -1) + return HAL_ERROR_RPC_TRANSPORT; + return HAL_OK; +} + +hal_error_t hal_rpc_recvfrom(uint8_t * const buf, size_t * const len, void **opaque) +{ + int ret; + + if ((ret = hal_slip_recv(buf, *len)) == -1) + return HAL_ERROR_RPC_TRANSPORT; + *len = ret; + return HAL_OK; +} + +int hal_slip_send_char(uint8_t c) +{ + return (uart_send_char(c) == 0) ? 0 : -1; +} + +int hal_slip_recv_char(uint8_t *c) +{ + return (uart_recv_char(c) == 0) ? 0 : -1; +} diff --git a/rpc_xdr.c b/rpc_xdr.c deleted file mode 100644 index 69b8482..0000000 --- a/rpc_xdr.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * rpc_xdr.c - * --------- - * Serialization/deserialization routines, using XDR (RFC 4506) encoding. - * - * Copyright (c) 2016, NORDUnet A/S All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the NORDUnet nor the names of its contributors may - * be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include /* memcpy */ -#include /* bzero */ -#include /* htonl/ntohl */ - -#include "hal.h" - -/* encode/decode_int. This covers int, unsigned int, enum, and bool types, - * which are all encoded as 32-bit big-endian fields. Signed integers are - * defined to use two's complement, but that's universal these days, yes? - */ - -hal_error_t rpc_encode_int(uint8_t ** const outbuf, const uint8_t * const limit, const uint32_t value) -{ - /* arg checks */ - if (outbuf == NULL || *outbuf == NULL || limit == NULL) - return HAL_ERROR_BAD_ARGUMENTS; - - /* buffer overflow check */ - if (limit - *outbuf < sizeof(value)) - return HAL_ERROR_IO_BAD_COUNT; - - **(uint32_t **)outbuf = htonl(value); - *outbuf += sizeof(value); - return HAL_OK; -} - -hal_error_t rpc_decode_int(uint8_t **inbuf, const uint8_t * const limit, uint32_t *value) -{ - /* arg checks */ - if (inbuf == NULL || *inbuf == NULL || limit == NULL || value == NULL) - return HAL_ERROR_BAD_ARGUMENTS; - - /* buffer overflow check */ - if (limit - *inbuf < sizeof(*value)) - return HAL_ERROR_IO_BAD_COUNT; - - *value = ntohl(**(uint32_t **)inbuf); - *inbuf += sizeof(*value); - return HAL_OK; -} - -/* encode/decode_buffer. This covers variable-length string and opaque types. - * The data is preceded by a 4-byte length word (encoded as above), and padded - * to a multiple of 4 bytes as necessary. - */ - -hal_error_t rpc_encode_buffer(uint8_t **outbuf, const uint8_t * const limit, const uint8_t *value, const uint32_t len) -{ - hal_error_t ret; - - /* arg checks */ - if (outbuf == NULL || *outbuf == NULL || limit == NULL || - (value == NULL && len != 0)) - return HAL_ERROR_BAD_ARGUMENTS; - - /* buffer overflow check */ - if ((limit - *outbuf) < (((len + 3) & ~3) + sizeof(len))) - return HAL_ERROR_IO_BAD_COUNT; - - /* encode length */ - if ((ret = rpc_encode_int(outbuf, limit, len)) != HAL_OK) - return ret; - - /* write the string or opaque data */ - memcpy(*outbuf, value, len); - *outbuf += len; - - /* pad if necessary */ - if (len & 3) { - size_t n = 4 - (len & 3); - bzero(*outbuf, n); - *outbuf += n; - } - - return HAL_OK; -} - -/* This version returns a pointer to the data in the input buffer. - * It is used in the rpc server. - */ -hal_error_t rpc_decode_buffer_in_place(uint8_t **inbuf, const uint8_t * const limit, uint8_t ** const value, uint32_t * const len) -{ - hal_error_t ret; - uint32_t xdr_len; - uint8_t *orig_inbuf = *inbuf; - - /* arg checks */ - if (inbuf == NULL || *inbuf == NULL || limit == NULL || value == NULL || len == NULL) - return HAL_ERROR_BAD_ARGUMENTS; - - /* decode the length */ - if ((ret = rpc_decode_int(inbuf, limit, &xdr_len)) != HAL_OK) - return ret; - - /* input and output buffer overflow checks vs decoded length */ - - /* decoded length is past the end of the input buffer; - * we're probably out of sync, but nothing we can do now - */ - if (limit - *inbuf < xdr_len) { - /* undo read of length */ - *inbuf = orig_inbuf; - return HAL_ERROR_IO_BAD_COUNT; - } - - /* user buffer is too small, update *len - */ - if (*len < xdr_len) { - *len = xdr_len; - /* undo read of length */ - *inbuf = orig_inbuf; - return HAL_ERROR_IO_BAD_COUNT; - } - - /* return a pointer to the string or opaque data */ - *value = *inbuf; - *len = xdr_len; - - /* update the buffer pointer, skipping any padding bytes */ - *inbuf += (xdr_len + 3) & ~3; - - return HAL_OK; -} - -/* This version copies the data to the user-supplied buffer. - * It is used in the rpc client. - */ -hal_error_t rpc_decode_buffer(uint8_t **inbuf, const uint8_t * const limit, uint8_t * const value, uint32_t * const len) -{ - hal_error_t ret; - uint8_t *vptr; - - if ((ret = rpc_decode_buffer_in_place(inbuf, limit, &vptr, len)) == HAL_OK) - memcpy(value, vptr, *len); - return ret; -} - -#ifdef TEST -void hexdump(uint8_t *buf, uint32_t len) -{ - int i; - - for (i = 0; i < len; ++i) { - uint8_t c = buf[i]; - printf("%02x ", c); - if ((i & 0x07) == 0x07) - printf("\n"); - } - if ((len & 0x07) != 0) - printf("\n"); -} - -int main(int argc, char *argv[]) -{ - uint32_t i; - uint8_t buf[64] = {0}; - uint8_t *bufptr = buf, *readptr; - uint8_t *limit = buf + sizeof(buf); - hal_error_t ret; - uint8_t alphabet[] = "abcdefghijklmnopqrstuvwxyz"; - uint8_t readbuf[64] = {0}; - - printf("rpc_encode_int: work to failure\n"); - for (i = 1; i < 100; ++i) { - if ((ret = rpc_encode_int(&bufptr, limit, i)) != HAL_OK) { - printf("%d: %s\n", i, hal_error_string(ret)); - break; - } - } - hexdump(buf, ((uint8_t *)bufptr - buf)); - - printf("\nrpc_decode_int:\n"); - readptr = buf; - while (readptr < bufptr) { - if ((ret = rpc_decode_int(&readptr, limit, &i)) != HAL_OK) { - printf("%s\n", hal_error_string(ret)); - break; - } - printf("%u ", i); - } - printf("\n"); - - printf("\nrpc_encode_buffer: work to failure\n"); - bzero(buf, sizeof(buf)); - bufptr = buf; - for (i = 1; i < 10; ++i) { - if ((ret = rpc_encode_buffer(&bufptr, limit, alphabet, i)) != HAL_OK) { - printf("%d: %s\n", i, hal_error_string(ret)); - break; - } - } - hexdump(buf, ((uint8_t *)bufptr - buf)); - - printf("\nrpc_decode_buffer:\n"); - readptr = buf; - i = sizeof(readbuf); - while (readptr < bufptr) { - if ((ret = rpc_decode_buffer(&readptr, limit, readbuf, &i)) != HAL_OK) { - printf("%s\n", hal_error_string(ret)); - break; - } - printf("%u: ", i); for (int j = 0; j < i; ++j) putchar(readbuf[j]); putchar('\n'); - i = sizeof(readbuf); - bzero(readbuf, sizeof(readbuf)); - } - - return 0; -} -#endif diff --git a/slip.c b/slip.c new file mode 100644 index 0000000..3b448f4 --- /dev/null +++ b/slip.c @@ -0,0 +1,141 @@ +/* SLIP send/recv code, from RFC 1055 */ + +#include /* perror */ + +#include "slip_internal.h" + +/* SLIP special character codes + */ +#define END 0300 /* indicates end of packet */ +#define ESC 0333 /* indicates byte stuffing */ +#define ESC_END 0334 /* ESC ESC_END means END data byte */ +#define ESC_ESC 0335 /* ESC ESC_ESC means ESC data byte */ + +/* SLIP_SEND: sends a packet of length "len", starting at + * location "p". + */ +int hal_slip_send(const uint8_t * const ptr, const size_t len) +{ + int i; + uint8_t *p = (uint8_t *)ptr; + +#define check_send_char(c) if (hal_slip_send_char(c) == -1) return perror("write"), -1; + + /* 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); + + /* for each byte in the packet, send the appropriate character + * sequence + */ + for (i = 0; i < len; ++i) { + switch (*p) { + /* if it's the same code as an END character, we send a + * special two character code so as not to make the + * receiver think we sent an END + */ + case END: + check_send_char(ESC); + check_send_char(ESC_END); + break; + + /* if it's the same code as an ESC character, + * we send a special two character code so as not + * to make the receiver think we sent an ESC + */ + case ESC: + check_send_char(ESC); + check_send_char(ESC_ESC); + break; + + /* otherwise, we just send the character + */ + default: + check_send_char(*p); + } + + p++; + } + + /* tell the receiver that we're done sending the packet + */ + check_send_char(END); + + return 0; +#undef check_send_char +} + +/* SLIP_RECV: receives a packet into the buffer located at "p". + * If more than len bytes are received, the packet will + * be truncated. + * Returns the number of bytes stored in the buffer. + */ +int hal_slip_recv(uint8_t * const p, const size_t len) +{ + uint8_t c; + size_t received = 0; + +#define check_recv_char(c) if (hal_slip_recv_char(&c) == -1) return perror("read"), -1; + + /* sit in a loop reading bytes until we put together + * a whole packet. + * Make sure not to copy them into the packet if we + * run out of room. + */ + while (1) { + /* get a character to process + */ + check_recv_char(c); + + /* handle bytestuffing if necessary + */ + switch (c) { + + /* if it's an END character then we're done with + * the packet + */ + case END: + /* a minor optimization: if there is no + * data in the packet, ignore it. This is + * meant to avoid bothering IP with all + * the empty packets generated by the + * duplicate END characters which are in + * turn sent to try to detect line noise. + */ + if (received) + return received; + else + break; + + /* if it's the same code as an ESC character, wait + * and get another character and then figure out + * what to store in the packet based on that. + */ + case ESC: + check_recv_char(c); + + /* if "c" is not one of these two, then we + * have a protocol violation. The best bet + * seems to be to leave the byte alone and + * just stuff it into the packet + */ + switch(c) { + case ESC_END: + c = END; + break; + case ESC_ESC: + c = ESC; + break; + } + + /* here we fall into the default handler and let + * it store the character for us + */ + default: + if (received < len) + p[received++] = c; + } + } +#undef check_recv_char +} diff --git a/slip_internal.h b/slip_internal.h new file mode 100644 index 0000000..103f72d --- /dev/null +++ b/slip_internal.h @@ -0,0 +1,51 @@ +/* + * slip_internal.h + * --------------- + * Send/recv data over a serial connection with SLIP framing + * + * Copyright (c) 2016, 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. + */ + +#ifndef _HAL_SLIP_INTERNAL_H +#define _HAL_SLIP_INTERNAL_H + +#include "hal_internal.h" + +/* Defined in slip.c - send/recv a block of data with SLIP framing. + */ +extern int hal_slip_send(const uint8_t * const p, const size_t len); +extern int hal_slip_recv(uint8_t * const p, const size_t len); + +/* Defined in rpc_[client|server]_serial.c - send/recv one byte over a + * serial connection. + */ +extern int hal_slip_send_char(const uint8_t c); +extern int hal_slip_recv_char(uint8_t * const c); + +#endif /* _HAL_SLIP_INTERNAL_H */ diff --git a/tests/GNUmakefile b/tests/GNUmakefile index 2f026a1..b4d006d 100644 --- a/tests/GNUmakefile +++ b/tests/GNUmakefile @@ -29,8 +29,22 @@ INC = ../hal.h LIB = ../libhal.a -BIN = test-aes-key-wrap test-hash test-pbkdf2 test-ecdsa test-bus test-trng test-rsa -BIN += test-rpc_hash test-rpc_server +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 +endif +ifdef RPC_SERVER + BIN += test-rpc_server +endif CFLAGS = -g3 -Wall -fPIC -std=c99 -I.. diff --git a/tests/test-rpc_hash.c b/tests/test-rpc_hash.c index d59e341..38bb793 100644 --- a/tests/test-rpc_hash.c +++ b/tests/test-rpc_hash.c @@ -636,11 +636,10 @@ static int _test_hmac(const hal_digest_algorithm_t alg, int main (int argc, char *argv[]) { -// rpc_client_init(RPC_LOCAL); - rpc_client_init(RPC_REMOTE); - int ok = 1; + ok &= hal_rpc_client_init(); + ok &= test_hash(hal_digest_algorithm_sha1, nist_512_single, sha1_single_digest, "SHA-1 single block"); ok &= test_hash(hal_digest_algorithm_sha1, nist_512_double, sha1_double_digest, "SHA-1 double block"); @@ -688,6 +687,8 @@ int main (int argc, char *argv[]) ok &= test_hmac(hal_digest_algorithm_sha512, hmac_sha2_tc_6_key, hmac_sha2_tc_6_data, hmac_sha2_tc_6_result_sha512, "HMAC-SHA-512 test case 6"); ok &= test_hmac(hal_digest_algorithm_sha512, hmac_sha2_tc_7_key, hmac_sha2_tc_7_data, hmac_sha2_tc_7_result_sha512, "HMAC-SHA-512 test case 7"); + ok &= hal_rpc_client_close(); + return !ok; } diff --git a/tests/test-rpc_server.c b/tests/test-rpc_server.c index 6eff755..eb11f6d 100644 --- a/tests/test-rpc_server.c +++ b/tests/test-rpc_server.c @@ -1,16 +1,10 @@ -#include -#include -#include -#include - #include -#include int main (int argc, char *argv[]) { - if (rpc_server_init() != HAL_OK) + if (hal_rpc_server_init() != HAL_OK) return 1; - rpc_server_main(); + hal_rpc_server_main(); return 0; } diff --git a/xdr.c b/xdr.c new file mode 100644 index 0000000..2741752 --- /dev/null +++ b/xdr.c @@ -0,0 +1,265 @@ +/* + * xdr.c + * ----- + * Serialization/deserialization routines, using XDR (RFC 4506) encoding. + * + * Copyright (c) 2016, NORDUnet A/S All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include /* memcpy, memset */ + +#ifndef STM32F4XX +#include /* htonl/ntohl */ +#else +/* htonl is not available in arm-none-eabi headers or libc */ +#ifdef __ARMEL__ /* little endian */ +static inline uint32_t htonl(uint32_t w) +{ + return + ((w & 0x000000ff) << 24) + + ((w & 0x0000ff00) << 8) + + ((w & 0x00ff0000) >> 8) + + ((w & 0xff000000) >> 24); +} +#else +#define htonl(x) (x) +#endif +#define ntohl htonl +#endif + +#include "hal.h" +#include "xdr_internal.h" + +/* encode/decode_int. This covers int, unsigned int, enum, and bool types, + * which are all encoded as 32-bit big-endian fields. Signed integers are + * defined to use two's complement, but that's universal these days, yes? + */ + +hal_error_t hal_xdr_encode_int(uint8_t ** const outbuf, const uint8_t * const limit, const uint32_t value) +{ + /* arg checks */ + if (outbuf == NULL || *outbuf == NULL || limit == NULL) + return HAL_ERROR_BAD_ARGUMENTS; + + /* buffer overflow check */ + if (limit - *outbuf < sizeof(value)) + return HAL_ERROR_IO_BAD_COUNT; + + **(uint32_t **)outbuf = htonl(value); + *outbuf += sizeof(value); + return HAL_OK; +} + +hal_error_t hal_xdr_decode_int(uint8_t **inbuf, const uint8_t * const limit, uint32_t *value) +{ + /* arg checks */ + if (inbuf == NULL || *inbuf == NULL || limit == NULL || value == NULL) + return HAL_ERROR_BAD_ARGUMENTS; + + /* buffer overflow check */ + if (limit - *inbuf < sizeof(*value)) + return HAL_ERROR_IO_BAD_COUNT; + + *value = ntohl(**(uint32_t **)inbuf); + *inbuf += sizeof(*value); + return HAL_OK; +} + +/* encode/decode_buffer. This covers variable-length string and opaque types. + * The data is preceded by a 4-byte length word (encoded as above), and padded + * to a multiple of 4 bytes as necessary. + */ + +hal_error_t hal_xdr_encode_buffer(uint8_t **outbuf, const uint8_t * const limit, const uint8_t *value, const uint32_t len) +{ + hal_error_t ret; + + /* arg checks */ + if (outbuf == NULL || *outbuf == NULL || limit == NULL || + (value == NULL && len != 0)) + return HAL_ERROR_BAD_ARGUMENTS; + + /* buffer overflow check */ + if ((limit - *outbuf) < (((len + 3) & ~3) + sizeof(len))) + return HAL_ERROR_IO_BAD_COUNT; + + /* encode length */ + if ((ret = hal_xdr_encode_int(outbuf, limit, len)) != HAL_OK) + return ret; + + /* write the string or opaque data */ + memcpy(*outbuf, value, len); + *outbuf += len; + + /* pad if necessary */ + if (len & 3) { + size_t n = 4 - (len & 3); + memset(*outbuf, 0, n); + *outbuf += n; + } + + return HAL_OK; +} + +/* This version returns a pointer to the data in the input buffer. + * It is used in the rpc server. + */ +hal_error_t hal_xdr_decode_buffer_in_place(uint8_t **inbuf, const uint8_t * const limit, uint8_t ** const value, uint32_t * const len) +{ + hal_error_t ret; + uint32_t xdr_len; + uint8_t *orig_inbuf = *inbuf; + + /* arg checks */ + if (inbuf == NULL || *inbuf == NULL || limit == NULL || value == NULL || len == NULL) + return HAL_ERROR_BAD_ARGUMENTS; + + /* decode the length */ + if ((ret = hal_xdr_decode_int(inbuf, limit, &xdr_len)) != HAL_OK) + return ret; + + /* input and output buffer overflow checks vs decoded length */ + + /* decoded length is past the end of the input buffer; + * we're probably out of sync, but nothing we can do now + */ + if (limit - *inbuf < xdr_len) { + /* undo read of length */ + *inbuf = orig_inbuf; + return HAL_ERROR_IO_BAD_COUNT; + } + + /* user buffer is too small, update *len + */ + if (*len < xdr_len) { + *len = xdr_len; + /* undo read of length */ + *inbuf = orig_inbuf; + return HAL_ERROR_IO_BAD_COUNT; + } + + /* return a pointer to the string or opaque data */ + *value = *inbuf; + *len = xdr_len; + + /* update the buffer pointer, skipping any padding bytes */ + *inbuf += (xdr_len + 3) & ~3; + + return HAL_OK; +} + +/* This version copies the data to the user-supplied buffer. + * It is used in the rpc client. + */ +hal_error_t hal_xdr_decode_buffer(uint8_t **inbuf, const uint8_t * const limit, uint8_t * const value, uint32_t * const len) +{ + hal_error_t ret; + uint8_t *vptr; + + if ((ret = hal_xdr_decode_buffer_in_place(inbuf, limit, &vptr, len)) == HAL_OK) + memcpy(value, vptr, *len); + return ret; +} + +/* ---------------------------------------------------------------- */ + +#ifdef TEST +void hexdump(uint8_t *buf, uint32_t len) +{ + int i; + + for (i = 0; i < len; ++i) { + uint8_t c = buf[i]; + printf("%02x ", c); + if ((i & 0x07) == 0x07) + printf("\n"); + } + if ((len & 0x07) != 0) + printf("\n"); +} + +int main(int argc, char *argv[]) +{ + uint32_t i; + uint8_t buf[64] = {0}; + uint8_t *bufptr = buf, *readptr; + uint8_t *limit = buf + sizeof(buf); + hal_error_t ret; + uint8_t alphabet[] = "abcdefghijklmnopqrstuvwxyz"; + uint8_t readbuf[64] = {0}; + + printf("hal_xdr_encode_int: work to failure\n"); + for (i = 1; i < 100; ++i) { + if ((ret = hal_xdr_encode_int(&bufptr, limit, i)) != HAL_OK) { + printf("%d: %s\n", i, hal_error_string(ret)); + break; + } + } + hexdump(buf, ((uint8_t *)bufptr - buf)); + + printf("\nhal_xdr_decode_int:\n"); + readptr = buf; + while (readptr < bufptr) { + if ((ret = hal_xdr_decode_int(&readptr, limit, &i)) != HAL_OK) { + printf("%s\n", hal_error_string(ret)); + break; + } + printf("%u ", i); + } + printf("\n"); + + printf("\nhal_xdr_encode_buffer: work to failure\n"); + memset(buf, 0, sizeof(buf)); + bufptr = buf; + for (i = 1; i < 10; ++i) { + if ((ret = hal_xdr_encode_buffer(&bufptr, limit, alphabet, i)) != HAL_OK) { + printf("%d: %s\n", i, hal_error_string(ret)); + break; + } + } + hexdump(buf, ((uint8_t *)bufptr - buf)); + + printf("\nhal_xdr_decode_buffer:\n"); + readptr = buf; + i = sizeof(readbuf); + while (readptr < bufptr) { + if ((ret = hal_xdr_decode_buffer(&readptr, limit, readbuf, &i)) != HAL_OK) { + printf("%s\n", hal_error_string(ret)); + break; + } + printf("%u: ", i); for (int j = 0; j < i; ++j) putchar(readbuf[j]); putchar('\n'); + i = sizeof(readbuf); + memset(readbuf, 0, sizeof(readbuf)); + } + + return 0; +} +#endif diff --git a/xdr_internal.h b/xdr_internal.h new file mode 100644 index 0000000..00793b0 --- /dev/null +++ b/xdr_internal.h @@ -0,0 +1,66 @@ +/* + * xdr_internal.h + * -------------- + * Serialization/deserialization routines, using XDR (RFC 4506) encoding. + * + * Copyright (c) 2016, 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. + */ + +#ifndef _XDR_INTERNAL_H +#define _XDR_INTERNAL_H + + /* + * RPC serialization/deserialization routines, using XDR (RFC 4506) encoding. + */ + +hal_error_t hal_xdr_encode_int(uint8_t ** const outbuf, + const uint8_t * const limit, + const uint32_t value); + +hal_error_t hal_xdr_decode_int(uint8_t ** const inbuf, + const uint8_t * const limit, + uint32_t * const value); + +hal_error_t hal_xdr_encode_buffer(uint8_t ** const outbuf, + const uint8_t * const limit, + const uint8_t * const value, + const uint32_t len); + +hal_error_t hal_xdr_decode_buffer_in_place(uint8_t ** const inbuf, + const uint8_t * const limit, + uint8_t ** const vptr, + uint32_t * const len); + +hal_error_t hal_xdr_decode_buffer(uint8_t ** const inbuf, + const uint8_t * const limit, + uint8_t * const value, + uint32_t * const len); + + +#endif /* _XDR_INTERNAL_H*/ -- cgit v1.2.3