diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | core.c | 62 | ||||
-rw-r--r-- | daemon.c | 15 | ||||
-rw-r--r-- | hal.h | 2 | ||||
-rw-r--r-- | hal_internal.h | 8 | ||||
-rw-r--r-- | hal_io_eim.c | 11 | ||||
-rw-r--r-- | hal_io_fmc.c | 11 | ||||
-rw-r--r-- | ks_flash.c | 10 | ||||
-rw-r--r-- | masterkey.c | 48 | ||||
-rw-r--r-- | pbkdf2.c | 9 | ||||
-rw-r--r-- | rpc_client.c | 288 | ||||
-rw-r--r-- | rpc_serial.c | 4 | ||||
-rw-r--r-- | rpc_server.c | 28 | ||||
-rw-r--r-- | tests/Makefile | 4 | ||||
-rw-r--r-- | tests/test-rpc_bighash.c | 131 | ||||
-rw-r--r-- | tests/test-rpc_login.c | 80 | ||||
-rw-r--r-- | xdr.c | 23 |
18 files changed, 430 insertions, 314 deletions
@@ -10,9 +10,11 @@ tests/test-ecdsa-*.der tests/test-hash tests/test-mkmif tests/test-pbkdf2 +tests/test-rpc_bighash tests/test-rpc_get_random tests/test-rpc_get_version tests/test-rpc_hash +tests/test-rpc_login tests/test-rpc_pkey tests/test-rpc_server tests/test-rsa @@ -30,6 +30,7 @@ # Number of static hash and HMAC state blocks to allocate. # Numbers pulled out of a hat, just testing. +STATIC_CORE_STATE_BLOCKS = 32 STATIC_HASH_STATE_BLOCKS = 10 STATIC_HMAC_STATE_BLOCKS = 4 STATIC_PKEY_STATE_BLOCKS = 6 @@ -185,12 +186,19 @@ LIBTFM_BLD ?= ${LIBTFM_SRC} # directory. CFLAGS += -g3 -Wall -std=c99 -Wno-strict-aliasing +CFLAGS += -DHAL_STATIC_CORE_STATE_BLOCKS=${STATIC_CORE_STATE_BLOCKS} 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 += -I${CRYPTECH_ROOT}/sw/libhal CFLAGS += -I${LIBTFM_BLD} +# Enable software hash cores everywhere for now. In theory, there might be situations +# where we don't want them on the HSM, but they're relatively harmless, and the bootstrap +# sequence on new hardware works a lot better when we can log in before loading the FPGA. + +CFLAGS += -DHAL_ENABLE_SOFTWARE_HASH_CORES=1 + export CFLAGS export RPC_MODE @@ -4,7 +4,7 @@ * This module contains code to probe the FPGA for its installed cores. * * Author: Paul Selkirk, Rob Austein - * Copyright (c) 2015, NORDUnet A/S All rights reserved. + * Copyright (c) 2015-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 @@ -42,35 +42,8 @@ #include "hal_internal.h" /* - * Each Cryptech core has a set of 4-byte registers, which are accessed - * through a 16-bit address. The address space is divided as follows: - * 3 bits segment selector | up to 8 segments - * 5 bits core selector | up to 32 cores/segment (see note below) - * 8 bits register selector | up to 256 registers/core (see modexp below) - * - * i.e, the address is structured as: - * sss ccccc rrrrrrrr - * - * The I2C and UART communication channels use this 16-bit address format - * directly in their read and write commands. - * - * The EIM communications channel translates this 16-bit address into a - * 32-bit memory-mapped address in the range 0x08000000..807FFFF: - * 00001000000000 sss 0 ccccc rrrrrrrr 00 - * - * EIM, as implemented on the Novena, uses a 19-bit address space: - * Bits 18..16 are the semgent selector. - * Bits 15..10 are the core selector. - * Bits 9..2 are the register selector. - * Bits 1..0 are zero, because reads and writes are always word aligned. - * - * Note that EIM can support 64 cores per segment, but we sacrifice one bit - * in order to map it into a 16-bit address space. - */ - -/* * Structure of our internal database is private, in case we want to - * be change representation (array, tree, list of lists, whatever) at + * change representation (array, tree, list of lists, whatever) at * some later date without having to change the public API. */ @@ -80,6 +53,14 @@ struct hal_core { struct hal_core *next; }; +#ifndef HAL_STATIC_CORE_STATE_BLOCKS +#define HAL_STATIC_CORE_STATE_BLOCKS 0 +#endif + +#if HAL_STATIC_CORE_STATE_BLOCKS > 0 +static hal_core_t core_table[HAL_STATIC_CORE_STATE_BLOCKS]; +#endif + /* * Check whether a core's name matches a particular string. This is a * bit nasty due to non-null-terminated fixed-length names. @@ -119,16 +100,23 @@ static hal_core_t *probe_cores(void) if (head != NULL) return head; - hal_core_t **tail = &head; hal_core_t *core = NULL; + hal_core_t **tail = &head; hal_error_t err = HAL_OK; +#if HAL_STATIC_CORE_STATE_BLOCKS > 0 + int n = 0; +#endif for (hal_addr_t addr = CORE_MIN; addr < CORE_MAX; addr += CORE_SIZE) { +#if HAL_STATIC_CORE_STATE_BLOCKS > 0 + core = &core_table[n]; +#else if (core == NULL && (core = malloc(sizeof(hal_core_t))) == NULL) { err = HAL_ERROR_ALLOCATION_FAILURE; goto fail; } +#endif memset(core, 0, sizeof(*core)); core->info.base = addr; @@ -137,7 +125,7 @@ static hal_core_t *probe_cores(void) (err = hal_io_read(core, ADDR_VERSION, (uint8_t *) core->info.version, 4)) != HAL_OK) goto fail; - if (core->info.name[0] == '\0') + if (core->info.name[0] == 0x00 || core->info.name[0] == 0xff) continue; for (int i = 0; i < sizeof(gaps)/sizeof(*gaps); i++) { @@ -150,20 +138,32 @@ static hal_core_t *probe_cores(void) *tail = core; tail = &core->next; core = NULL; + +#if HAL_STATIC_CORE_STATE_BLOCKS > 0 + if (++n >= HAL_STATIC_CORE_STATE_BLOCKS) + break; +#endif } +#if HAL_STATIC_CORE_STATE_BLOCKS > 0 +#else if (core != NULL) free(core); +#endif return head; fail: +#if HAL_STATIC_CORE_STATE_BLOCKS > 0 + memset(core_table, 0, sizeof(core_table)); +#else if (core != NULL) free(core); while ((core = head) != NULL) { head = core->next; free(core); } +#endif return NULL; } @@ -34,6 +34,7 @@ */ #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/un.h> @@ -143,8 +144,15 @@ int main(int argc, char *argv[]) int lsock; int dsock; int opt; - const char *device = HAL_CLIENT_SERIAL_DEFAULT_DEVICE; - uint32_t speed = HAL_CLIENT_SERIAL_DEFAULT_SPEED; + const char *device = getenv(HAL_CLIENT_SERIAL_DEVICE_ENVVAR); + const char *speed_ = getenv(HAL_CLIENT_SERIAL_SPEED_ENVVAR); + uint32_t speed = HAL_CLIENT_SERIAL_DEFAULT_SPEED; + + if (device == NULL) + device = HAL_CLIENT_SERIAL_DEFAULT_DEVICE; + + if (speed_ != NULL) + speed = (uint32_t) strtoul(speed_, NULL, 10); while ((opt = getopt(argc, argv, "hn:d:s:")) != -1) { switch (opt) { @@ -158,7 +166,8 @@ int main(int argc, char *argv[]) device = optarg; break; case 's': - switch (atoi(optarg)) { + speed = (uint32_t) strtoul(optarg, NULL, 10); + switch (speed) { case 115200: case 921600: break; @@ -764,7 +764,7 @@ 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_dispatch(const uint8_t * const ibuf, const size_t ilen, uint8_t * const obuf, size_t * const olen); +extern hal_error_t hal_rpc_server_dispatch(const uint8_t * const ibuf, const size_t ilen, uint8_t * const obuf, size_t * const olen); extern void hal_rpc_server_main(void); #endif /* _HAL_H_ */ diff --git a/hal_internal.h b/hal_internal.h index 5bdc83f..1c06494 100644 --- a/hal_internal.h +++ b/hal_internal.h @@ -432,8 +432,8 @@ typedef enum { RPC_FUNC_PKEY_GET_KEY_FLAGS, RPC_FUNC_PKEY_GET_PUBLIC_KEY_LEN, RPC_FUNC_PKEY_GET_PUBLIC_KEY, - RPC_FUNC_PKEY_REMOTE_SIGN, - RPC_FUNC_PKEY_REMOTE_VERIFY, + RPC_FUNC_PKEY_SIGN, + RPC_FUNC_PKEY_VERIFY, RPC_FUNC_PKEY_LIST, RPC_FUNC_PKEY_RENAME, } rpc_func_num_t; @@ -482,8 +482,8 @@ typedef enum { * Names of environment variables for setting the above in RPC clients. */ -#define HAL_CLIENT_SERIAL_DEVICE_ENVVAR "HAL_CLIENT_SERIAL_DEVICE" -#define HAL_CLIENT_SERIAL_SPEED_ENVVAR "HAL_CLIENT_SERIAL_SPEED" +#define HAL_CLIENT_SERIAL_DEVICE_ENVVAR "CRYPTECH_RPC_CLIENT_SERIAL_DEVICE" +#define HAL_CLIENT_SERIAL_SPEED_ENVVAR "CRYPTECH_RPC_CLIENT_SERIAL_SPEED" #endif /* _HAL_INTERNAL_H_ */ diff --git a/hal_io_eim.c b/hal_io_eim.c index 173490f..5824f5b 100644 --- a/hal_io_eim.c +++ b/hal_io_eim.c @@ -4,7 +4,7 @@ * This module contains common code to talk to the FPGA over the EIM bus. * * Author: Paul Selkirk - * Copyright (c) 2014-2015, NORDUnet A/S All rights reserved. + * Copyright (c) 2014-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 @@ -60,17 +60,10 @@ static hal_error_t init(void) } /* translate cryptech register number to EIM address - * - * register number format: - * 3 bits segment selector - * 5 bits core selector (6 bits in native eim) - * 8 bits register selector - * - * sss ccccc rrrrrrrr => 00001000000000 sss 0 ccccc rrrrrrrr 00 */ static hal_addr_t eim_offset(hal_addr_t offset) { - return EIM_BASE_ADDR + ((offset & ~0x1fff) << 3) + ((offset & 0x1fff) << 2); + return EIM_BASE_ADDR + (offset << 2); } void hal_io_set_debug(int onoff) diff --git a/hal_io_fmc.c b/hal_io_fmc.c index 5742e56..7aa4b19 100644 --- a/hal_io_fmc.c +++ b/hal_io_fmc.c @@ -4,7 +4,7 @@ * 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. + * Copyright (c) 2014-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 @@ -61,17 +61,10 @@ static hal_error_t init(void) } /* 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); + return offset << 2; } void hal_io_set_debug(int onoff) @@ -324,7 +324,8 @@ hal_error_t hal_ks_get_kek(uint8_t *kek, (kek_max < bitsToBytes(256)) ? bitsToBytes(192) : bitsToBytes(256)); - if (masterkey_volatile_read(kek, len) == LIBHAL_OK) { + hal_error_t err = masterkey_volatile_read(kek, len); + if (err == LIBHAL_OK) { *kek_len = len; return LIBHAL_OK; } @@ -333,7 +334,12 @@ hal_error_t hal_ks_get_kek(uint8_t *kek, return LIBHAL_OK; } - return HAL_ERROR_KEYSTORE_ACCESS; + /* Both keystores returned an error, probably HAL_ERROR_MASTERKEY_NOT_SET. + * I could try to be clever and compare the errors, but really the volatile + * keystore is the important one (you shouldn't store the master key in + * flash), so return that error. + */ + return err; } diff --git a/masterkey.c b/masterkey.c index ffae618..3c4f0d3 100644 --- a/masterkey.c +++ b/masterkey.c @@ -89,22 +89,19 @@ hal_error_t masterkey_volatile_init() return HAL_ERROR_CORE_NOT_FOUND; } - err = - hal_mkmif_set_clockspeed(core, MKM_VOLATILE_SCLK_DIV) || - hal_mkmif_init(core) || - hal_mkmif_read_word(core, MKM_VOLATILE_STATUS_ADDRESS, &status); - - if (err != LIBHAL_OK) return err; + if ((err = hal_mkmif_set_clockspeed(core, MKM_VOLATILE_SCLK_DIV)) != LIBHAL_OK || + (err = hal_mkmif_init(core)) != LIBHAL_OK || + (err = hal_mkmif_read_word(core, MKM_VOLATILE_STATUS_ADDRESS, &status)) != LIBHAL_OK) + return err; if (status != MKM_STATUS_SET && status != MKM_STATUS_NOT_SET) { /* XXX Something is a bit fishy here. If we just write the status word, it reads back wrong sometimes, * while if we write the full buf too it is consistently right afterwards. */ uint8_t buf[KEK_LENGTH] = {0}; - err = - hal_mkmif_write(core, MKM_VOLATILE_STATUS_ADDRESS + 4, buf, sizeof(buf)) || - hal_mkmif_write_word(core, MKM_VOLATILE_STATUS_ADDRESS, MKM_STATUS_NOT_SET); - if (err != LIBHAL_OK) return err; + if ((err = hal_mkmif_write(core, MKM_VOLATILE_STATUS_ADDRESS + 4, buf, sizeof(buf))) != LIBHAL_OK || + (err = hal_mkmif_write_word(core, MKM_VOLATILE_STATUS_ADDRESS, MKM_STATUS_NOT_SET)) != LIBHAL_OK) + return err; } volatile_init = 1; @@ -119,11 +116,9 @@ hal_error_t masterkey_volatile_read(uint8_t *buf, size_t len) if (len && len != KEK_LENGTH) return HAL_ERROR_MASTERKEY_BAD_LENGTH; - err = - masterkey_volatile_init() || - hal_mkmif_read_word(core, MKM_VOLATILE_STATUS_ADDRESS, &status); - - if (err != LIBHAL_OK) return err; + if ((err = masterkey_volatile_init()) != LIBHAL_OK || + (err = hal_mkmif_read_word(core, MKM_VOLATILE_STATUS_ADDRESS, &status)) != LIBHAL_OK) + return err; if (buf != NULL && len) { /* Don't return the random bytes in the RAM memory in case it isn't initialized. @@ -151,12 +146,12 @@ hal_error_t masterkey_volatile_write(uint8_t *buf, size_t len) if (len != KEK_LENGTH) return HAL_ERROR_MASTERKEY_BAD_LENGTH; if (! buf) return HAL_ERROR_MASTERKEY_FAIL; - err = - masterkey_volatile_init() || - hal_mkmif_write(core, MKM_VOLATILE_STATUS_ADDRESS + 4, buf, len) || - hal_mkmif_write_word(core, MKM_VOLATILE_STATUS_ADDRESS, MKM_STATUS_SET); + if ((err = masterkey_volatile_init()) != LIBHAL_OK || + (err = hal_mkmif_write(core, MKM_VOLATILE_STATUS_ADDRESS + 4, buf, len)) != LIBHAL_OK || + (err = hal_mkmif_write_word(core, MKM_VOLATILE_STATUS_ADDRESS, MKM_STATUS_SET)) != LIBHAL_OK) + return err; - return err; + return LIBHAL_OK; } hal_error_t masterkey_volatile_erase(size_t len) @@ -166,12 +161,12 @@ hal_error_t masterkey_volatile_erase(size_t len) if (len != KEK_LENGTH) return HAL_ERROR_MASTERKEY_BAD_LENGTH; - err = - masterkey_volatile_init() || - hal_mkmif_write(core, MKM_VOLATILE_STATUS_ADDRESS + 4, buf, sizeof(buf)) || - hal_mkmif_write_word(core, MKM_VOLATILE_STATUS_ADDRESS, MKM_STATUS_NOT_SET); + if ((err = masterkey_volatile_init()) != LIBHAL_OK || + (err = hal_mkmif_write(core, MKM_VOLATILE_STATUS_ADDRESS + 4, buf, sizeof(buf))) != LIBHAL_OK || + (err = hal_mkmif_write_word(core, MKM_VOLATILE_STATUS_ADDRESS, MKM_STATUS_NOT_SET)) != LIBHAL_OK) + return err; - return err; + return LIBHAL_OK; } hal_error_t masterkey_flash_init() @@ -187,10 +182,11 @@ hal_error_t masterkey_flash_read(uint8_t *buf, size_t len) { uint8_t page[KEYSTORE_PAGE_SIZE]; uint32_t *status = (uint32_t *) page; + hal_error_t err; if (len && len != KEK_LENGTH) return HAL_ERROR_MASTERKEY_BAD_LENGTH; - if (masterkey_flash_init() != LIBHAL_OK) return HAL_ERROR_MASTERKEY_FAIL; + if ((err = masterkey_flash_init()) != LIBHAL_OK) return err; if (! keystore_read_data(MKM_FLASH_STATUS_ADDRESS, page, sizeof(page))) { memset(page, 0, sizeof(page)); @@ -105,6 +105,15 @@ hal_error_t hal_pbkdf2(hal_core_t *core, if ((uint64_t) derived_key_length > ((uint64_t) 0xFFFFFFFF) * descriptor->block_length) return HAL_ERROR_UNSUPPORTED_KEY; +#if 1 + /* HACK - find the second sha256 core, to avoid interfering with rpc. + * If there isn't a second one, this will set core to NULL, and + * hal_hash_initialize will find the first one. + */ + core = hal_core_find(descriptor->core_name, NULL); + core = hal_core_find(descriptor->core_name, core); +#endif + memset(result, 0, sizeof(result)); memset(mac, 0, sizeof(mac)); diff --git a/rpc_client.c b/rpc_client.c index 4c2a6c7..a517528 100644 --- a/rpc_client.c +++ b/rpc_client.c @@ -39,12 +39,16 @@ #include "hal_internal.h" #include "xdr_internal.h" -/* - * RPC calls. - */ +#ifndef HAL_RPC_CLIENT_DEBUG +#define HAL_RPC_CLIENT_DEBUG 0 +#endif +#if HAL_RPC_CLIENT_DEBUG #include <stdio.h> #define check(op) do { const hal_error_t _err_ = (op); if (_err_ != HAL_OK) { printf("%s returned %d (%s)\n", #op, _err_, hal_error_string(_err_)); return _err_; } } while (0) +#else +#define check(op) do { const hal_error_t _err_ = (op); if (_err_ != HAL_OK) { return _err_; } } while (0) +#endif #define pad(n) (((n) + 3) & ~3) @@ -52,13 +56,58 @@ #if RPC_CLIENT != RPC_CLIENT_LOCAL +/* + * Consolidate a bit of the repetitive code from the packet receive loop. + * We're looking for a packet which is a response to the packet we sent, + * so if the opcode is wrong, we discard and wait for another packet. + */ + +static hal_error_t read_matching_packet(const rpc_func_num_t expected_func, + uint8_t *inbuf, + const size_t inbuf_max, + const uint8_t **iptr, + const uint8_t **ilimit) +{ + hal_client_handle_t dummy_client; + uint32_t received_func; + size_t ilen = inbuf_max; + hal_error_t err; + + assert(inbuf != NULL && iptr != NULL && ilimit != NULL); + + do { + + if ((err = hal_rpc_recv(inbuf, &ilen)) != HAL_OK) + return err; + + assert(ilen <= inbuf_max); + *iptr = inbuf; + *ilimit = inbuf + ilen; + + if ((err = hal_xdr_decode_int(iptr, *ilimit, &received_func)) == HAL_ERROR_XDR_BUFFER_OVERFLOW) + continue; + if (err != HAL_OK) + return err; + + if ((err = hal_xdr_decode_int(iptr, *ilimit, &dummy_client.handle)) == HAL_ERROR_XDR_BUFFER_OVERFLOW) + continue; + if (err != HAL_OK) + return err; + + } while (received_func != expected_func); + + return HAL_OK; +} + +/* + * RPC calls. + */ + static hal_error_t get_version(uint32_t *version) { uint8_t outbuf[nargs(2)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(4)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); - uint32_t rpc_func_num; hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; @@ -66,11 +115,7 @@ static hal_error_t get_version(uint32_t *version) check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_GET_VERSION, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { @@ -84,9 +129,7 @@ static hal_error_t get_random(void *buffer, const size_t length) uint8_t outbuf[nargs(3)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(4) + pad(length)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); uint32_t rcvlen = length; - uint32_t rpc_func_num; hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; @@ -95,11 +138,7 @@ static hal_error_t get_random(void *buffer, const size_t length) check(hal_xdr_encode_int(&optr, olimit, (uint32_t)length)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_GET_RANDOM, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { @@ -116,9 +155,6 @@ static hal_error_t set_pin(const hal_client_handle_t client, uint8_t outbuf[nargs(4) + pad(pin_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(3)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); - uint32_t rpc_func_num; - hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_SET_PIN)); @@ -127,11 +163,7 @@ static hal_error_t set_pin(const hal_client_handle_t client, check(hal_xdr_encode_buffer(&optr, olimit, (const uint8_t *)pin, pin_len)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_SET_PIN, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; @@ -158,9 +190,6 @@ static hal_error_t login(const hal_client_handle_t client, uint8_t outbuf[nargs(4) + pad(pin_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(3)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); - uint32_t rpc_func_num; - hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_LOGIN)); @@ -169,11 +198,7 @@ static hal_error_t login(const hal_client_handle_t client, check(hal_xdr_encode_buffer(&optr, olimit, (const uint8_t *)pin, pin_len)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_LOGIN, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; @@ -184,20 +209,13 @@ static hal_error_t logout(const hal_client_handle_t client) uint8_t outbuf[nargs(2)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(3)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); - uint32_t rpc_func_num; - hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; 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(hal_rpc_recv(inbuf, &ilen)); - assert(ilen <= sizeof(inbuf)); - - check(hal_xdr_decode_int(&iptr, ilimit, &rpc_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_LOGOUT, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; @@ -208,8 +226,6 @@ static hal_error_t logout_all(void) uint8_t outbuf[nargs(2)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(3)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); - uint32_t rpc_func_num; hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; @@ -217,11 +233,7 @@ static hal_error_t logout_all(void) check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_LOGOUT_ALL, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; @@ -233,9 +245,6 @@ static hal_error_t is_logged_in(const hal_client_handle_t client, uint8_t outbuf[nargs(3)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(3)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); - uint32_t rpc_func_num; - hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_IS_LOGGED_IN)); @@ -243,11 +252,7 @@ static hal_error_t is_logged_in(const hal_client_handle_t client, check(hal_xdr_encode_int(&optr, olimit, user)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_IS_LOGGED_IN, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; @@ -258,9 +263,7 @@ static hal_error_t hash_get_digest_len(const hal_digest_algorithm_t alg, size_t uint8_t outbuf[nargs(3)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(4)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); uint32_t len32; - uint32_t rpc_func_num; hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; @@ -269,11 +272,7 @@ static hal_error_t hash_get_digest_len(const hal_digest_algorithm_t alg, size_t check(hal_xdr_encode_int(&optr, olimit, alg)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_HASH_GET_DIGEST_LEN, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { @@ -289,9 +288,7 @@ static hal_error_t hash_get_digest_algorithm_id(const hal_digest_algorithm_t alg uint8_t outbuf[nargs(4)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(4) + pad(len_max)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); uint32_t len32 = len_max; - uint32_t rpc_func_num; hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; @@ -301,11 +298,7 @@ static hal_error_t hash_get_digest_algorithm_id(const hal_digest_algorithm_t alg check(hal_xdr_encode_int(&optr, olimit, len_max)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_HASH_GET_DIGEST_LEN, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { @@ -320,9 +313,7 @@ static hal_error_t hash_get_algorithm(const hal_hash_handle_t hash, hal_digest_a uint8_t outbuf[nargs(3)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(4)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); uint32_t alg32; - uint32_t rpc_func_num; hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; @@ -331,16 +322,12 @@ static hal_error_t hash_get_algorithm(const hal_hash_handle_t hash, hal_digest_a check(hal_xdr_encode_int(&optr, olimit, hash.handle)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_HASH_GET_ALGORITHM, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { check(hal_xdr_decode_int(&iptr, ilimit, &alg32)); - *alg = (hal_digest_algorithm_t)alg32; + *alg = (hal_digest_algorithm_t) alg32; } return rpc_ret; } @@ -354,9 +341,6 @@ static hal_error_t hash_initialize(const hal_client_handle_t client, uint8_t outbuf[nargs(5) + pad(key_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(4)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); - uint32_t rpc_func_num; - hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_HASH_INITIALIZE)); @@ -366,11 +350,7 @@ static hal_error_t hash_initialize(const hal_client_handle_t client, check(hal_xdr_encode_buffer(&optr, olimit, key, key_len)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_HASH_INITIALIZE, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { @@ -385,8 +365,6 @@ static hal_error_t hash_update(const hal_hash_handle_t hash, uint8_t outbuf[nargs(4) + pad(length)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(3)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); - uint32_t rpc_func_num; hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; @@ -396,11 +374,7 @@ static hal_error_t hash_update(const hal_hash_handle_t hash, check(hal_xdr_encode_buffer(&optr, olimit, data, length)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_HASH_UPDATE, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; @@ -412,9 +386,7 @@ static hal_error_t hash_finalize(const hal_hash_handle_t hash, uint8_t outbuf[nargs(4)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(4) + pad(length)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); uint32_t digest_len = length; - uint32_t rpc_func_num; hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; @@ -424,11 +396,7 @@ static hal_error_t hash_finalize(const hal_hash_handle_t hash, check(hal_xdr_encode_int(&optr, olimit, length)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_HASH_FINALIZE, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { @@ -450,9 +418,6 @@ static hal_error_t pkey_remote_load(const hal_client_handle_t client, uint8_t outbuf[nargs(8) + pad(name_len) + pad(der_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(4)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); - uint32_t rpc_func_num; - hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_LOAD)); @@ -465,11 +430,7 @@ static hal_error_t pkey_remote_load(const hal_client_handle_t client, 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(hal_xdr_decode_int(&iptr, ilimit, &rpc_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_PKEY_LOAD, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) @@ -488,9 +449,6 @@ static hal_error_t pkey_remote_find(const hal_client_handle_t client, uint8_t outbuf[nargs(6) + pad(name_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(4)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); - uint32_t rpc_func_num; - hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_FIND)); @@ -501,11 +459,7 @@ static hal_error_t pkey_remote_find(const hal_client_handle_t client, 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(hal_xdr_decode_int(&iptr, ilimit, &rpc_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_PKEY_FIND, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) @@ -525,9 +479,6 @@ static hal_error_t pkey_remote_generate_rsa(const hal_client_handle_t client, uint8_t outbuf[nargs(7) + pad(name_len) + pad(exp_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(4)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); - uint32_t rpc_func_num; - hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_GENERATE_RSA)); @@ -539,11 +490,7 @@ static hal_error_t pkey_remote_generate_rsa(const hal_client_handle_t client, 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(hal_xdr_decode_int(&iptr, ilimit, &rpc_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_PKEY_GENERATE_RSA, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) @@ -562,9 +509,6 @@ static hal_error_t pkey_remote_generate_ec(const hal_client_handle_t client, uint8_t outbuf[nargs(6) + pad(name_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(4)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); - uint32_t rpc_func_num; - hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_GENERATE_EC)); @@ -575,11 +519,7 @@ static hal_error_t pkey_remote_generate_ec(const hal_client_handle_t client, 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(hal_xdr_decode_int(&iptr, ilimit, &rpc_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_PKEY_GENERATE_EC, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) @@ -593,8 +533,6 @@ static hal_error_t pkey_remote_close(const hal_pkey_handle_t pkey) uint8_t outbuf[nargs(3)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(3)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); - uint32_t rpc_func_num; hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; @@ -603,11 +541,7 @@ static hal_error_t pkey_remote_close(const hal_pkey_handle_t pkey) check(hal_xdr_encode_int(&optr, olimit, pkey.handle)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_PKEY_CLOSE, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; @@ -618,8 +552,6 @@ static hal_error_t pkey_remote_delete(const hal_pkey_handle_t pkey) uint8_t outbuf[nargs(3)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(3)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); - uint32_t rpc_func_num; hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; @@ -628,11 +560,7 @@ static hal_error_t pkey_remote_delete(const hal_pkey_handle_t pkey) check(hal_xdr_encode_int(&optr, olimit, pkey.handle)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_PKEY_DELETE, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; @@ -644,8 +572,6 @@ static hal_error_t pkey_remote_rename(const hal_pkey_handle_t pkey, uint8_t outbuf[nargs(4) + pad(name_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(3)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); - uint32_t rpc_func_num; hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; @@ -655,11 +581,7 @@ static hal_error_t pkey_remote_rename(const hal_pkey_handle_t pkey, check(hal_xdr_encode_buffer(&optr, olimit, name, name_len)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_PKEY_RENAME, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; @@ -672,9 +594,7 @@ static hal_error_t pkey_remote_get_key_type(const hal_pkey_handle_t pkey, uint8_t outbuf[nargs(3)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(4)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); uint32_t type32; - uint32_t rpc_func_num; hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; @@ -683,11 +603,7 @@ static hal_error_t pkey_remote_get_key_type(const hal_pkey_handle_t pkey, check(hal_xdr_encode_int(&optr, olimit, pkey.handle)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_PKEY_GET_KEY_TYPE, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { @@ -703,9 +619,7 @@ static hal_error_t pkey_remote_get_key_flags(const hal_pkey_handle_t pkey, uint8_t outbuf[nargs(3)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(4)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); uint32_t flags32; - uint32_t rpc_func_num; hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; @@ -714,11 +628,7 @@ static hal_error_t pkey_remote_get_key_flags(const hal_pkey_handle_t pkey, check(hal_xdr_encode_int(&optr, olimit, pkey.handle)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_PKEY_GET_KEY_FLAGS, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { @@ -733,9 +643,7 @@ static size_t pkey_remote_get_public_key_len(const hal_pkey_handle_t pkey) uint8_t outbuf[nargs(3)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(4)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); uint32_t len32; - uint32_t rpc_func_num; hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; @@ -744,11 +652,7 @@ static size_t pkey_remote_get_public_key_len(const hal_pkey_handle_t pkey) check(hal_xdr_encode_int(&optr, olimit, pkey.handle)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_PKEY_GET_PUBLIC_KEY_LEN, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { @@ -765,9 +669,7 @@ static hal_error_t pkey_remote_get_public_key(const hal_pkey_handle_t pkey, uint8_t outbuf[nargs(4)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(4) + pad(der_max)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); uint32_t dlen32 = der_max; - uint32_t rpc_func_num; hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; @@ -777,11 +679,7 @@ static hal_error_t pkey_remote_get_public_key(const hal_pkey_handle_t pkey, check(hal_xdr_encode_int(&optr, olimit, der_max)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_PKEY_GET_PUBLIC_KEY, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { @@ -800,13 +698,11 @@ static hal_error_t pkey_remote_sign(const hal_session_handle_t session, uint8_t outbuf[nargs(7) + pad(input_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(4) + pad(signature_max)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); uint32_t slen32 = signature_max; - uint32_t rpc_func_num; hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; - check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_REMOTE_SIGN)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_SIGN)); check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle)); check(hal_xdr_encode_int(&optr, olimit, session.handle)); check(hal_xdr_encode_int(&optr, olimit, pkey.handle)); @@ -815,11 +711,7 @@ static hal_error_t pkey_remote_sign(const hal_session_handle_t session, check(hal_xdr_encode_int(&optr, olimit, signature_max)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_PKEY_SIGN, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { @@ -838,12 +730,10 @@ static hal_error_t pkey_remote_verify(const hal_session_handle_t session, uint8_t outbuf[nargs(7) + pad(input_len) + pad(signature_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(3)]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); - uint32_t rpc_func_num; hal_client_handle_t dummy_client = {0}; hal_error_t rpc_ret; - check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_REMOTE_VERIFY)); + check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_VERIFY)); check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle)); check(hal_xdr_encode_int(&optr, olimit, session.handle)); check(hal_xdr_encode_int(&optr, olimit, pkey.handle)); @@ -852,11 +742,7 @@ static hal_error_t pkey_remote_verify(const hal_session_handle_t session, check(hal_xdr_encode_buffer(&optr, olimit, signature, signature_len)); 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_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_PKEY_VERIFY, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); return rpc_ret; @@ -881,9 +767,7 @@ static hal_error_t pkey_remote_list(hal_pkey_info_t *result, uint8_t outbuf[nargs(4)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf); uint8_t inbuf[nargs(4) + pad(result_max * sizeof(hal_pkey_info_t))]; const uint8_t *iptr = inbuf, *ilimit = inbuf + sizeof(inbuf); - size_t ilen = sizeof(inbuf); uint32_t len; - uint32_t rpc_func_num; hal_client_handle_t dummy_client = {0}; hal_error_t ret, rpc_ret; @@ -893,11 +777,7 @@ static hal_error_t pkey_remote_list(hal_pkey_info_t *result, 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(hal_xdr_decode_int(&iptr, ilimit, &rpc_func_num)); - check(hal_xdr_decode_int(&iptr, ilimit, &dummy_client.handle)); + check(read_matching_packet(RPC_FUNC_PKEY_LIST, inbuf, sizeof(inbuf), &iptr, &ilimit)); check(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret)); if (rpc_ret == HAL_OK) { diff --git a/rpc_serial.c b/rpc_serial.c index 5dc659e..728bbd8 100644 --- a/rpc_serial.c +++ b/rpc_serial.c @@ -89,8 +89,8 @@ hal_error_t hal_serial_init(const char * const device, const uint32_t speed) return HAL_ERROR_RPC_TRANSPORT; } - cfsetospeed (&tty, speed); - cfsetispeed (&tty, speed); + cfsetospeed (&tty, termios_speed); + cfsetispeed (&tty, termios_speed); #endif diff --git a/rpc_server.c b/rpc_server.c index 7b06780..a0de42d 100644 --- a/rpc_server.c +++ b/rpc_server.c @@ -40,7 +40,7 @@ * RPC calls. */ -#define check(op) if ((ret = (op)) != HAL_OK) return ret; +#define check(op) do { hal_error_t _err = (op); if (_err != HAL_OK) return _err; } while (0) #define pad(n) (((n) + 3) & ~3) @@ -497,7 +497,6 @@ static hal_error_t pkey_get_public_key_len(const uint8_t **iptr, const uint8_t * hal_client_handle_t client __attribute__((unused)); hal_pkey_handle_t pkey; size_t len; - hal_error_t ret; check(hal_xdr_decode_int(iptr, ilimit, &client.handle)); check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle)); @@ -647,8 +646,8 @@ static hal_error_t pkey_list(const uint8_t **iptr, const uint8_t * const ilimit, return ret; } -void hal_rpc_server_dispatch(const uint8_t * const ibuf, const size_t ilen, - uint8_t * const obuf, size_t * const olen) +hal_error_t hal_rpc_server_dispatch(const uint8_t * const ibuf, const size_t ilen, + uint8_t * const obuf, size_t * const olen) { const uint8_t * iptr = ibuf; const uint8_t * const ilimit = ibuf + ilen; @@ -658,9 +657,9 @@ void hal_rpc_server_dispatch(const uint8_t * const ibuf, const size_t ilen, uint32_t client_handle; hal_error_t ret; - hal_xdr_decode_int(&iptr, ilimit, &rpc_func_num); - hal_xdr_decode_int(&iptr, ilimit, &client_handle); - hal_xdr_undecode_int(&iptr); + check(hal_xdr_decode_int(&iptr, ilimit, &rpc_func_num)); + check(hal_xdr_decode_int(&iptr, ilimit, &client_handle)); + check(hal_xdr_undecode_int(&iptr)); switch (rpc_func_num) { case RPC_FUNC_GET_VERSION: ret = get_version(&iptr, ilimit, &optr, olimit); @@ -731,10 +730,10 @@ void hal_rpc_server_dispatch(const uint8_t * const ibuf, const size_t ilen, case RPC_FUNC_PKEY_GET_PUBLIC_KEY: ret = pkey_get_public_key(&iptr, ilimit, &optr, olimit); break; - case RPC_FUNC_PKEY_REMOTE_SIGN: + case RPC_FUNC_PKEY_SIGN: ret = pkey_remote_sign(&iptr, ilimit, &optr, olimit); break; - case RPC_FUNC_PKEY_REMOTE_VERIFY: + case RPC_FUNC_PKEY_VERIFY: ret = pkey_remote_verify(&iptr, ilimit, &optr, olimit); break; case RPC_FUNC_PKEY_LIST: @@ -750,9 +749,10 @@ void hal_rpc_server_dispatch(const uint8_t * const ibuf, const size_t ilen, /* Encode opcode, client ID, and response code at the beginning of the payload */ *olen = optr - obuf; optr = obuf; - hal_xdr_encode_int(&optr, olimit, rpc_func_num); - hal_xdr_encode_int(&optr, olimit, client_handle); - hal_xdr_encode_int(&optr, olimit, ret); + check(hal_xdr_encode_int(&optr, olimit, rpc_func_num)); + check(hal_xdr_encode_int(&optr, olimit, client_handle)); + check(hal_xdr_encode_int(&optr, olimit, ret)); + return HAL_OK; } #define interrupt 0 @@ -770,8 +770,8 @@ void hal_rpc_server_main(void) ret = hal_rpc_recvfrom(inbuf, &ilen, &opaque); if (ret == HAL_OK) { olen = sizeof(outbuf); - hal_rpc_server_dispatch(inbuf, ilen, outbuf, &olen); - hal_rpc_sendto(outbuf, olen, opaque); + if (hal_rpc_server_dispatch(inbuf, ilen, outbuf, &olen) == HAL_OK) + hal_rpc_sendto(outbuf, olen, opaque); } } } diff --git a/tests/Makefile b/tests/Makefile index 229ffcf..79cb3ff 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -45,7 +45,7 @@ CFLAGS ?= -g3 -Wall -fPIC -std=c99 -I${LIBHAL_SRC} -I${LIBTFM_BLD} CORE_TESTS = test-aes-key-wrap test-hash test-pbkdf2 test-ecdsa test-bus test-trng test-rsa test-mkmif SERVER_TESTS = test-rpc_server -CLIENT_TESTS = test-rpc_hash test-rpc_pkey test-rpc_get_version test-rpc_get_random +CLIENT_TESTS = test-rpc_hash test-rpc_pkey test-rpc_get_version test-rpc_get_random test-rpc_login test-rpc_bighash ALL_TESTS = ${CORE_TESTS} ${SERVER_TESTS} ${CLIENT_TESTS} @@ -63,6 +63,8 @@ else endif +$(info Building libhal with configuration IO_BUS=${IO_BUS} RPC_MODE=${RPC_MODE} KS=${KS} RPC_TRANSPORT=${RPC_TRANSPORT} MODEXP_CORE=${MODEXP_CORE}) + all: ${BIN} test: all diff --git a/tests/test-rpc_bighash.c b/tests/test-rpc_bighash.c new file mode 100644 index 0000000..e18d9b0 --- /dev/null +++ b/tests/test-rpc_bighash.c @@ -0,0 +1,131 @@ +/* + * test-rpc_bighash.c + * ------------------ + * Test code for RPC interface to Cryptech hash cores. + * + * 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. + */ + +/* + * Throw a large hashing operation at the RPC server. This was originally + * written to flush out an interaction between RPC and the CLI login + * process (which uses PBKDF2, which uses HMAC-256). It might be useful + * for other puposes? + */ + +#include <stdio.h> +#include <string.h> + +#include <hal.h> + +static uint8_t block[] = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + +/* some common numbers of iterations, and their digests */ +static uint8_t expected_5k[] = { + 0x28, 0xe6, 0x00, 0x2d, 0x7f, 0x18, 0x05, 0x42, + 0xdb, 0x89, 0xc9, 0x9f, 0xc1, 0x5f, 0x83, 0x16, + 0xe4, 0xc2, 0x15, 0x75, 0xad, 0xe5, 0x9f, 0xe7, + 0x22, 0x0a, 0x59, 0x72, 0x56, 0x28, 0x1f, 0xe8, +}; + +static uint8_t expected_10k[] = { + 0x2d, 0xb1, 0x9b, 0x83, 0x14, 0x86, 0x48, 0x18, + 0x76, 0x54, 0xec, 0xe0, 0xfc, 0x1a, 0x56, 0xfe, + 0xdc, 0xfa, 0x8f, 0x46, 0xfd, 0x9d, 0x88, 0x3a, + 0xcd, 0x59, 0x51, 0x92, 0x44, 0x89, 0xc8, 0x51, +}; + +static uint8_t expected_25k[] = { + 0xcb, 0xf2, 0x5c, 0x1d, 0x0a, 0xee, 0xfc, 0xf7, + 0xe7, 0x7f, 0xda, 0x9a, 0x81, 0x1f, 0x6c, 0xa9, + 0x80, 0x95, 0x04, 0x75, 0xdc, 0x3a, 0xc1, 0x18, + 0x68, 0x7b, 0xe7, 0x9e, 0xb4, 0x2e, 0x43, 0xe5, +}; + +static void hexdump(uint8_t *buf, uint32_t len) +{ + for (uint32_t i = 0; i < len; ++i) + printf("%02x%c", buf[i], ((i & 0x07) == 0x07) ? '\n' : ' '); + if ((len & 0x07) != 0) + printf("\n"); +} + +#define check(op) \ + do { \ + hal_error_t err = (op); \ + if (err) { \ + printf("%s: %s\n", #op, hal_error_string(err)); \ + return err; \ + } \ + } while (0) + +int main (int argc, char *argv[]) +{ + hal_client_handle_t client = {0}; + hal_session_handle_t session = {0}; + hal_hash_handle_t hash; + uint8_t digest[32]; + int iterations = 5000; + uint8_t *expected; + + if (argc > 1) + iterations = atoi(argv[1]); + + if (iterations == 5000) + expected = expected_5k; + else if (iterations == 10000) + expected = expected_10k; + else if (iterations == 25000) + expected = expected_25k; + else + expected = NULL; + + check(hal_rpc_client_init()); + check(hal_rpc_hash_initialize(client, session, &hash, hal_digest_algorithm_sha256, NULL, 0)); + + for (int i = 0; i < iterations; ++i) { + check(hal_rpc_hash_update(hash, block, sizeof(block))); + } + + check(hal_rpc_hash_finalize(hash, digest, sizeof(digest))); + + if (expected) { + if (memcmp(digest, expected, sizeof(digest)) != 0) { + printf("received:\n"); hexdump(digest, sizeof(digest)); + printf("\nexpected:\n"); hexdump(expected, sizeof(digest)); + } + } + else { + hexdump(digest, sizeof(digest)); + } + + check(hal_rpc_client_close()); + return 0; +} diff --git a/tests/test-rpc_login.c b/tests/test-rpc_login.c new file mode 100644 index 0000000..a95a5ed --- /dev/null +++ b/tests/test-rpc_login.c @@ -0,0 +1,80 @@ +/* + * test-rpc_login.c + * ---------------- + * Test code for RPC interface to Cryptech hash cores. + * + * 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 <stdio.h> +#include <string.h> +#include <strings.h> + +#include <hal.h> + +#define check(op) \ + do { \ + hal_error_t err = (op); \ + if (err) { \ + printf("%s: %s\n", #op, hal_error_string(err)); \ + return err; \ + } \ + } while (0) + +int main(int argc, char *argv[]) +{ + hal_client_handle_t client = {0}; + hal_user_t user = HAL_USER_WHEEL; + + if (argc < 3) { + printf("usage: %s user pin\n", argv[0]); + return 1; + } + + if (strcasecmp(argv[1], "wheel") == 0) + user = HAL_USER_WHEEL; + else if (strcasecmp(argv[1], "so") == 0) + user = HAL_USER_SO; + else if (strcasecmp(argv[1], "user") == 0) + user = HAL_USER_NORMAL; + else { + printf("user name must be one of 'wheel', 'so', or 'user'\n"); + return 1; + } + + check(hal_rpc_client_init()); + + check(hal_rpc_login(client, user, argv[2], strlen(argv[2]))); + check(hal_rpc_is_logged_in(client, user)); + check(hal_rpc_logout(client)); + + check(hal_rpc_client_close()); + return 0; +} @@ -165,21 +165,28 @@ hal_error_t hal_xdr_decode_buffer_in_place(const uint8_t **inbuf, const uint8_t */ hal_error_t hal_xdr_decode_buffer(const uint8_t **inbuf, const uint8_t * const limit, uint8_t * const value, uint32_t * const len) { + if (inbuf == NULL || value == NULL || len == NULL) + return HAL_ERROR_BAD_ARGUMENTS; + hal_error_t ret; const uint8_t *vptr; const uint8_t *orig_inbuf = *inbuf; uint32_t xdr_len; - if ((ret = hal_xdr_decode_buffer_in_place(inbuf, limit, &vptr, &xdr_len)) == HAL_OK) { - *len = xdr_len; - if (*len < xdr_len) { - /* user buffer is too small, undo read of length */ - *inbuf = orig_inbuf; - return HAL_ERROR_XDR_BUFFER_OVERFLOW; - } + if ((ret = hal_xdr_decode_buffer_in_place(inbuf, limit, &vptr, &xdr_len)) != HAL_OK) + return ret; - memcpy(value, vptr, *len); + if (*len < xdr_len) { + /* user buffer is too small, undo read of length */ + *inbuf = orig_inbuf; + ret = HAL_ERROR_XDR_BUFFER_OVERFLOW; } + else { + memcpy(value, vptr, xdr_len); + } + + *len = xdr_len; + return ret; } |