[Cryptech-Commits] [sw/libhal] branch master updated: RPC wire format now includes client handle in all requests, and opcode and client handle in all responses.

git at cryptech.is git at cryptech.is
Fri Jul 1 02:10:50 UTC 2016


This is an automated email from the git hooks/post-receive script.

paul at psgd.org pushed a commit to branch master
in repository sw/libhal.

The following commit(s) were added to refs/heads/master by this push:
       new  3ba7ca4   RPC wire format now includes client handle in all requests, and opcode and client handle in all responses.
3ba7ca4 is described below

commit 3ba7ca4155c7be439108b174a3b49a508923d378
Author: Paul Selkirk <paul at psgd.org>
AuthorDate: Thu Jun 30 21:52:59 2016 -0400

    RPC wire format now includes client handle in all requests, and opcode and
    client handle in all responses.
    
    This simplies the daemon a little, and means that the directly-connected
    serial client uses the same wire format as the daemon. The expense is some
    redundant code in rpc_client and rpc_server to process (and throw away)
    this extra stuff.
---
 Makefile            |   4 +-
 daemon.c            |  40 +++-----
 hal_internal.h      |   2 +-
 rpc_client.c        | 273 +++++++++++++++++++++++++++++++++++++++++++---------
 rpc_client_serial.c |  12 ++-
 rpc_server.c        |  51 +++++++++-
 xdr.c               |  11 +++
 xdr_internal.h      |   2 +
 8 files changed, 310 insertions(+), 85 deletions(-)

diff --git a/Makefile b/Makefile
index 13b43d5..d3182af 100644
--- a/Makefile
+++ b/Makefile
@@ -44,7 +44,7 @@ USAGE := "usage: ${MAKE} [IO_BUS=eim|i2c|fmc] [RPC_MODE=none|server|client-simpl
 IO_BUS		?= eim
 KS		?= volatile
 RPC_MODE	?= none
-RPC_TRANSPORT	?= daemon
+RPC_TRANSPORT	?= serial
 MODEXP_CORE	?= no
 
 ifeq (,$(and \
@@ -143,7 +143,7 @@ ifneq "${RPC_MODE}" "none"
 endif
 
 ifeq "${RPC_TRANSPORT}" "serial"
-  OBJ += slip.o
+  OBJ += slip.o rpc_serial.o
 endif
 
 RPC_CLIENT_OBJ = rpc_client.o
diff --git a/daemon.c b/daemon.c
index 00a55f6..7991710 100644
--- a/daemon.c
+++ b/daemon.c
@@ -262,13 +262,13 @@ int main(int argc, char *argv[])
                         hexdump(ibuf.buf, ibuf.len);
 #endif
                         /* We've got a complete rpc response packet. */
-                        const uint8_t *bufptr = ibuf.buf;
+                        const uint8_t *bufptr = ibuf.buf + 4;
                         const uint8_t * const limit = ibuf.buf + ibuf.len;
                         uint32_t sock;
-                        /* First word of the response is the client ID. */
+                        /* Second word of the response is the client ID. */
                         hal_xdr_decode_int(&bufptr, limit, &sock);
                         /* Pass response on to the client that requested it. */
-                        send(sock, bufptr, ibuf.len - 4, 0);
+                        send(sock, ibuf.buf, ibuf.len, 0);
                         /* Reinitialize the receive buffer. */
                         memset(&ibuf, 0, sizeof(ibuf));
                     }
@@ -290,43 +290,25 @@ int main(int argc, char *argv[])
 
                 /* client data socket */
                 else {
-                    uint8_t *bufptr = obuf.buf;
                     const uint8_t * const limit = obuf.buf + MAX_PKT_SIZE;
-                    /* First word of the request is the client ID. */
-                    hal_xdr_encode_int(&bufptr, limit, pollfds[i].fd);
                     /* Get the client's rpc request packet. */
-                    obuf.len = recv(pollfds[i].fd, bufptr, MAX_PKT_SIZE - 4, 0);
+                    obuf.len = recv(pollfds[i].fd, obuf.buf, MAX_PKT_SIZE, 0);
 #ifdef DEBUG
                     printf("data socket %d received request:\n", pollfds[i].fd);
-                    hexdump(obuf.buf, obuf.len + 4);
+                    hexdump(obuf.buf, obuf.len);
 #endif
 
-		    /* Fill in the client handle arg as needed. */
-		    uint32_t opcode;
-		    hal_xdr_decode_int((const uint8_t ** const)&bufptr, limit, &opcode);
-		    switch (opcode) {
-		    case RPC_FUNC_SET_PIN:
-		    case RPC_FUNC_LOGIN:
-		    case RPC_FUNC_LOGOUT:
-		    case RPC_FUNC_IS_LOGGED_IN:
-		    case RPC_FUNC_HASH_INITIALIZE:
-		    case RPC_FUNC_PKEY_LOAD:
-		    case RPC_FUNC_PKEY_FIND:
-		    case RPC_FUNC_PKEY_GENERATE_RSA:
-		    case RPC_FUNC_PKEY_GENERATE_EC:
-			/* first argument is client handle */
-			hal_xdr_encode_int(&bufptr, limit, pollfds[i].fd);
-			break;
-		    default:
-			break;
-		    }
+		    /* Fill in the client handle arg - first field after opcode. */
+                    uint8_t *bufptr = obuf.buf + 4;
+                    hal_xdr_encode_int(&bufptr, limit, pollfds[i].fd);
 
                     if (obuf.len > 0) {
 #ifdef DEBUG
-                        printf("passing to serial port\n");
+                        printf("passing to serial port:\n");
+                        hexdump(obuf.buf, obuf.len);
 #endif
                         /* Pass it on to the serial port. */
-                        hal_slip_send(obuf.buf, obuf.len + 4);
+                        hal_slip_send(obuf.buf, obuf.len);
                     }
                     else {
 #ifdef DEBUG
diff --git a/hal_internal.h b/hal_internal.h
index bd8e97d..e238bcf 100644
--- a/hal_internal.h
+++ b/hal_internal.h
@@ -438,7 +438,7 @@ typedef enum {
     RPC_FUNC_PKEY_RENAME,
 } rpc_func_num_t;
 
-#define RPC_VERSION 0x00010000          /* 0.1.0.0 */
+#define RPC_VERSION 0x01010000          /* 1.1.0.0 */
 
 /*
  * RPC client locality. These have to be defines rather than an enum,
diff --git a/rpc_client.c b/rpc_client.c
index c92571b..4c2a6c7 100644
--- a/rpc_client.c
+++ b/rpc_client.c
@@ -43,7 +43,8 @@
  * RPC calls.
  */
 
-#define check(op) do { const hal_error_t _err_ = (op); if (_err_ != HAL_OK) return _err_; } while (0)
+#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)
 
 #define pad(n) (((n) + 3) & ~3)
 
@@ -53,17 +54,24 @@
 
 static hal_error_t get_version(uint32_t *version)
 {
-  uint8_t outbuf[nargs(1)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(2)];
+  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;
 
   check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_GET_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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   if (rpc_ret == HAL_OK) {
     check(hal_xdr_decode_int(&iptr, ilimit, version));
@@ -73,19 +81,26 @@ static hal_error_t get_version(uint32_t *version)
 
 static hal_error_t get_random(void *buffer, const size_t length)
 {
-  uint8_t outbuf[nargs(2)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(2) + pad(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;
 
   check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_GET_RANDOM));
+  check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle));
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   if (rpc_ret == HAL_OK) {
     check(hal_xdr_decode_buffer(&iptr, ilimit, buffer, &rcvlen));
@@ -99,9 +114,11 @@ static hal_error_t set_pin(const hal_client_handle_t client,
                            const char * const pin, const size_t pin_len)
 {
   uint8_t outbuf[nargs(4) + pad(pin_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(1)];
+  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));
@@ -112,6 +129,10 @@ static hal_error_t set_pin(const hal_client_handle_t client,
 
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   return rpc_ret;
 }
@@ -135,9 +156,11 @@ static hal_error_t login(const hal_client_handle_t client,
                          const char * const pin, const size_t pin_len)
 {
   uint8_t outbuf[nargs(4) + pad(pin_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(1)];
+  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));
@@ -148,6 +171,10 @@ static hal_error_t login(const hal_client_handle_t client,
 
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   return rpc_ret;
 }
@@ -155,9 +182,11 @@ static hal_error_t login(const hal_client_handle_t client,
 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(1)];
+  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));
@@ -166,23 +195,34 @@ static hal_error_t logout(const hal_client_handle_t client)
 
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   return rpc_ret;
 }
 
 static hal_error_t logout_all(void)
 {
-  uint8_t outbuf[nargs(1)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(1)];
+  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_ALL));
+  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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   return rpc_ret;
 }
@@ -191,9 +231,11 @@ static hal_error_t is_logged_in(const hal_client_handle_t client,
                                 const hal_user_t user)
 {
   uint8_t outbuf[nargs(3)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(1)];
+  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));
@@ -203,25 +245,36 @@ static hal_error_t is_logged_in(const hal_client_handle_t client,
 
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   return rpc_ret;
 }
 
 static hal_error_t hash_get_digest_len(const hal_digest_algorithm_t alg, size_t *length)
 {
-  uint8_t outbuf[nargs(2)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(2)];
+  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;
 
   check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_HASH_GET_DIGEST_LEN));
+  check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle));
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   if (rpc_ret == HAL_OK) {
     check(hal_xdr_decode_int(&iptr, ilimit, &len32));
@@ -233,20 +286,27 @@ static hal_error_t hash_get_digest_len(const hal_digest_algorithm_t alg, size_t
 static hal_error_t hash_get_digest_algorithm_id(const hal_digest_algorithm_t alg,
                                                 uint8_t *id, size_t *len, const size_t len_max)
 {
-  uint8_t outbuf[nargs(3)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(2) + pad(len_max)];
+  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;
 
   check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_HASH_GET_DIGEST_LEN));
+  check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle));
   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(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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   if (rpc_ret == HAL_OK) {
     check(hal_xdr_decode_buffer(&iptr, ilimit, id, &len32));
@@ -257,19 +317,26 @@ static hal_error_t hash_get_digest_algorithm_id(const hal_digest_algorithm_t alg
 
 static hal_error_t hash_get_algorithm(const hal_hash_handle_t hash, hal_digest_algorithm_t *alg)
 {
-  uint8_t outbuf[nargs(2)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(2)];
+  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;
 
   check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_HASH_GET_ALGORITHM));
+  check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle));
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   if (rpc_ret == HAL_OK) {
     check(hal_xdr_decode_int(&iptr, ilimit, &alg32));
@@ -285,9 +352,11 @@ static hal_error_t hash_initialize(const hal_client_handle_t client,
                                    const uint8_t * const key, const size_t key_len)
 {
   uint8_t outbuf[nargs(5) + pad(key_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(2)];
+  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));
@@ -299,6 +368,10 @@ static hal_error_t hash_initialize(const hal_client_handle_t client,
 
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   if (rpc_ret == HAL_OK) {
     check(hal_xdr_decode_int(&iptr, ilimit, &hash->handle));
@@ -309,19 +382,26 @@ static hal_error_t hash_initialize(const hal_client_handle_t client,
 static hal_error_t hash_update(const hal_hash_handle_t hash,
                                const uint8_t * data, const size_t length)
 {
-  uint8_t outbuf[nargs(3) + pad(length)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(1)];
+  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;
 
   check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_HASH_UPDATE));
+  check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle));
   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(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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   return rpc_ret;
 }
@@ -329,20 +409,27 @@ static hal_error_t hash_update(const hal_hash_handle_t hash,
 static hal_error_t hash_finalize(const hal_hash_handle_t hash,
                                  uint8_t *digest, const size_t length)
 {
-  uint8_t outbuf[nargs(3)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(2) + pad(length)];
+  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;
 
   check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_HASH_FINALIZE));
+  check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle));
   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(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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   if (rpc_ret == HAL_OK) {
     check(hal_xdr_decode_buffer(&iptr, ilimit, digest, &digest_len));
@@ -361,9 +448,11 @@ static hal_error_t pkey_remote_load(const hal_client_handle_t client,
                                     const hal_key_flags_t flags)
 {
   uint8_t outbuf[nargs(8) + pad(name_len) + pad(der_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(2)];
+  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));
@@ -378,6 +467,10 @@ static hal_error_t pkey_remote_load(const hal_client_handle_t client,
 
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   if (rpc_ret == HAL_OK)
     check(hal_xdr_decode_int(&iptr, ilimit, &pkey->handle));
@@ -393,9 +486,11 @@ static hal_error_t pkey_remote_find(const hal_client_handle_t client,
                                     const hal_key_flags_t flags)
 {
   uint8_t outbuf[nargs(6) + pad(name_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(2)];
+  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));
@@ -408,6 +503,10 @@ static hal_error_t pkey_remote_find(const hal_client_handle_t client,
 
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   if (rpc_ret == HAL_OK)
     check(hal_xdr_decode_int(&iptr, ilimit, &pkey->handle));
@@ -424,9 +523,11 @@ static hal_error_t pkey_remote_generate_rsa(const hal_client_handle_t client,
                                             const hal_key_flags_t flags)
 {
   uint8_t outbuf[nargs(7) + pad(name_len) + pad(exp_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(2)];
+  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));
@@ -440,6 +541,10 @@ static hal_error_t pkey_remote_generate_rsa(const hal_client_handle_t client,
 
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   if (rpc_ret == HAL_OK)
     check(hal_xdr_decode_int(&iptr, ilimit, &pkey->handle));
@@ -455,9 +560,11 @@ static hal_error_t pkey_remote_generate_ec(const hal_client_handle_t client,
                                            const hal_key_flags_t flags)
 {
   uint8_t outbuf[nargs(6) + pad(name_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(2)];
+  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));
@@ -470,6 +577,10 @@ static hal_error_t pkey_remote_generate_ec(const hal_client_handle_t client,
 
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   if (rpc_ret == HAL_OK)
     check(hal_xdr_decode_int(&iptr, ilimit, &pkey->handle));
@@ -479,36 +590,50 @@ static hal_error_t pkey_remote_generate_ec(const hal_client_handle_t client,
 
 static hal_error_t pkey_remote_close(const hal_pkey_handle_t pkey)
 {
-  uint8_t outbuf[nargs(2)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(1)];
+  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_PKEY_CLOSE));
+  check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle));
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   return rpc_ret;
 }
 
 static hal_error_t pkey_remote_delete(const hal_pkey_handle_t pkey)
 {
-  uint8_t outbuf[nargs(2)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(1)];
+  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_PKEY_DELETE));
+  check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle));
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   return rpc_ret;
 }
@@ -516,19 +641,26 @@ static hal_error_t pkey_remote_delete(const hal_pkey_handle_t pkey)
 static hal_error_t pkey_remote_rename(const hal_pkey_handle_t pkey,
                                       const uint8_t * const name, const size_t name_len)
 {
-  uint8_t outbuf[nargs(3) + pad(name_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(1)];
+  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;
 
   check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_RENAME));
+  check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle));
   check(hal_xdr_encode_int(&optr, olimit, pkey.handle));
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   return rpc_ret;
 }
@@ -537,19 +669,26 @@ static hal_error_t pkey_remote_rename(const hal_pkey_handle_t pkey,
 static hal_error_t pkey_remote_get_key_type(const hal_pkey_handle_t pkey,
                                             hal_key_type_t *type)
 {
-  uint8_t outbuf[nargs(2)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(2)];
+  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;
 
   check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_GET_KEY_TYPE));
+  check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle));
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   if (rpc_ret == HAL_OK) {
     check(hal_xdr_decode_int(&iptr, ilimit, &type32));
@@ -561,19 +700,26 @@ static hal_error_t pkey_remote_get_key_type(const hal_pkey_handle_t pkey,
 static hal_error_t pkey_remote_get_key_flags(const hal_pkey_handle_t pkey,
                                              hal_key_flags_t *flags)
 {
-  uint8_t outbuf[nargs(2)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(2)];
+  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;
 
   check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_GET_KEY_FLAGS));
+  check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle));
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   if (rpc_ret == HAL_OK) {
     check(hal_xdr_decode_int(&iptr, ilimit, &flags32));
@@ -584,19 +730,26 @@ static hal_error_t pkey_remote_get_key_flags(const hal_pkey_handle_t pkey,
 
 static size_t pkey_remote_get_public_key_len(const hal_pkey_handle_t pkey)
 {
-  uint8_t outbuf[nargs(2)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(2)];
+  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;
 
   check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_GET_PUBLIC_KEY_LEN));
+  check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle));
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   if (rpc_ret == HAL_OK) {
     check(hal_xdr_decode_int(&iptr, ilimit, &len32));
@@ -609,20 +762,27 @@ static size_t pkey_remote_get_public_key_len(const hal_pkey_handle_t pkey)
 static hal_error_t pkey_remote_get_public_key(const hal_pkey_handle_t pkey,
                                               uint8_t *der, size_t *der_len, const size_t der_max)
 {
-  uint8_t outbuf[nargs(3)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(2) + pad(der_max)];
+  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;
 
   check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_GET_PUBLIC_KEY));
+  check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle));
   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(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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   if (rpc_ret == HAL_OK) {
     check(hal_xdr_decode_buffer(&iptr, ilimit, der, &dlen32));
@@ -637,14 +797,17 @@ static hal_error_t pkey_remote_sign(const hal_session_handle_t session,
                                     const uint8_t * const input,  const size_t input_len,
                                     uint8_t * signature, size_t *signature_len, const size_t signature_max)
 {
-  uint8_t outbuf[nargs(6) + pad(input_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(2) + pad(signature_max)];
+  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, dummy_client.handle));
   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));
@@ -654,6 +817,10 @@ static hal_error_t pkey_remote_sign(const hal_session_handle_t session,
 
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   if (rpc_ret == HAL_OK) {
     check(hal_xdr_decode_buffer(&iptr, ilimit, signature, &slen32));
@@ -668,13 +835,16 @@ static hal_error_t pkey_remote_verify(const hal_session_handle_t session,
                                       const uint8_t * const input, const size_t input_len,
                                       const uint8_t * const signature, const size_t signature_len)
 {
-  uint8_t outbuf[nargs(6) + pad(input_len) + pad(signature_len)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(1)];
+  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, dummy_client.handle));
   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));
@@ -684,6 +854,10 @@ static hal_error_t pkey_remote_verify(const hal_session_handle_t session,
 
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   return rpc_ret;
 }
@@ -704,20 +878,27 @@ static hal_error_t pkey_remote_list(hal_pkey_info_t *result,
                                     const unsigned result_max,
                                     hal_key_flags_t flags)
 {
-  uint8_t outbuf[nargs(3)], *optr = outbuf, *olimit = outbuf + sizeof(outbuf);
-  uint8_t inbuf[nargs(2) + pad(result_max * sizeof(hal_pkey_info_t))];
+  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;
 
   check(hal_xdr_encode_int(&optr, olimit, RPC_FUNC_PKEY_LIST));
+  check(hal_xdr_encode_int(&optr, olimit, dummy_client.handle));
   check(hal_xdr_encode_int(&optr, olimit, result_max));
   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(hal_xdr_decode_int(&iptr, ilimit, &rpc_ret));
   if (rpc_ret == HAL_OK) {
     int i;
diff --git a/rpc_client_serial.c b/rpc_client_serial.c
index ec53e05..b27c255 100644
--- a/rpc_client_serial.c
+++ b/rpc_client_serial.c
@@ -44,8 +44,11 @@
 #include "hal_internal.h"
 #include "slip_internal.h"
 
-#define DEVICE "/dev/ttyUSB0"
-#define SPEED B115200
+/* XXX These REALLY ought to be passed from the client app command line,
+ * rather than compiled into the library.
+ */
+#define DEVICE "/dev/ttyUSB1"
+#define SPEED B921600
 
 hal_error_t hal_rpc_client_transport_init(void)
 {
@@ -64,5 +67,8 @@ hal_error_t hal_rpc_send(const uint8_t * const buf, const size_t len)
 
 hal_error_t hal_rpc_recv(uint8_t * const buf, size_t * const len)
 {
-    return hal_slip_recv(buf, *len);
+    size_t maxlen = *len;
+    *len = 0;
+    hal_error_t err = hal_slip_recv(buf, len, maxlen);
+    return err;
 }
diff --git a/rpc_server.c b/rpc_server.c
index 65ba6bb..9089aea 100644
--- a/rpc_server.c
+++ b/rpc_server.c
@@ -47,9 +47,12 @@
 static hal_error_t get_version(const uint8_t **iptr, const uint8_t * const ilimit,
                                uint8_t **optr, const uint8_t * const olimit)
 {
+    hal_client_handle_t client __attribute__((unused));
     uint32_t version;
     hal_error_t ret;
 
+    check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
+
     /* call the local function */
     ret = hal_rpc_local_misc_dispatch.get_version(&version);
     if (ret == HAL_OK)
@@ -61,9 +64,11 @@ static hal_error_t get_version(const uint8_t **iptr, const uint8_t * const ilimi
 static hal_error_t get_random(const uint8_t **iptr, const uint8_t * const ilimit,
                               uint8_t **optr, const uint8_t * const olimit)
 {
+    hal_client_handle_t client __attribute__((unused));
     uint32_t length;
     hal_error_t ret;
 
+    check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
     check(hal_xdr_decode_int(iptr, ilimit, &length));
     /* sanity check length */
     if (length == 0 || length > olimit - *optr - 4)
@@ -134,8 +139,11 @@ static hal_error_t logout(const uint8_t **iptr, const uint8_t * const ilimit,
 static hal_error_t logout_all(const uint8_t **iptr, const uint8_t * const ilimit,
                               uint8_t **optr, const uint8_t * const olimit)
 {
+    hal_client_handle_t client __attribute__((unused));
     hal_error_t ret;
 
+    check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
+
     /* call the local function */
     ret = hal_rpc_local_misc_dispatch.logout_all();
     return ret;
@@ -159,10 +167,12 @@ static hal_error_t is_logged_in(const uint8_t **iptr, const uint8_t * const ilim
 static hal_error_t hash_get_digest_len(const uint8_t **iptr, const uint8_t * const ilimit,
                                        uint8_t **optr, const uint8_t * const olimit)
 {
+    hal_client_handle_t client __attribute__((unused));
     uint32_t alg;
     size_t length;
     hal_error_t ret;
 
+    check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
     check(hal_xdr_decode_int(iptr, ilimit, &alg));
 
     /* call the local function */
@@ -175,12 +185,14 @@ static hal_error_t hash_get_digest_len(const uint8_t **iptr, const uint8_t * con
 static hal_error_t hash_get_digest_algorithm_id(const uint8_t **iptr, const uint8_t * const ilimit,
                                                 uint8_t **optr, const uint8_t * const olimit)
 {
+    hal_client_handle_t client __attribute__((unused));
     uint32_t alg;
     size_t len;
     uint32_t len_max;
     uint8_t *optr_orig = *optr;
     hal_error_t ret;
 
+    check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
     check(hal_xdr_decode_int(iptr, ilimit, &alg));
     check(hal_xdr_decode_int(iptr, ilimit, &len_max));
     /* sanity check len_max */
@@ -206,10 +218,12 @@ static hal_error_t hash_get_digest_algorithm_id(const uint8_t **iptr, const uint
 static hal_error_t hash_get_algorithm(const uint8_t **iptr, const uint8_t * const ilimit,
                                       uint8_t **optr, const uint8_t * const olimit)
 {
+    hal_client_handle_t client __attribute__((unused));
     hal_hash_handle_t hash;
     hal_digest_algorithm_t alg;
     hal_error_t ret;
 
+    check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
     check(hal_xdr_decode_int(iptr, ilimit, &hash.handle));
 
     /* call the local function */
@@ -245,11 +259,13 @@ static hal_error_t hash_initialize(const uint8_t **iptr, const uint8_t * const i
 static hal_error_t hash_update(const uint8_t **iptr, const uint8_t * const ilimit,
                                uint8_t **optr, const uint8_t * const olimit)
 {
+    hal_client_handle_t client __attribute__((unused));
     hal_hash_handle_t hash;
     const uint8_t *data;
     uint32_t length;
     hal_error_t ret;
 
+    check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
     check(hal_xdr_decode_int(iptr, ilimit, &hash.handle));
     check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &data, &length));
 
@@ -261,10 +277,12 @@ static hal_error_t hash_update(const uint8_t **iptr, const uint8_t * const ilimi
 static hal_error_t hash_finalize(const uint8_t **iptr, const uint8_t * const ilimit,
                                  uint8_t **optr, const uint8_t * const olimit)
 {
+    hal_client_handle_t client __attribute__((unused));
     hal_hash_handle_t hash;
     uint32_t length;
     hal_error_t ret;
 
+    check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
     check(hal_xdr_decode_int(iptr, ilimit, &hash.handle));
     check(hal_xdr_decode_int(iptr, ilimit, &length));
     /* sanity check length */
@@ -392,9 +410,11 @@ static hal_error_t pkey_generate_ec(const uint8_t **iptr, const uint8_t * const
 static hal_error_t pkey_close(const uint8_t **iptr, const uint8_t * const ilimit,
                               uint8_t **optr, const uint8_t * const olimit)
 {
+    hal_client_handle_t client __attribute__((unused));
     hal_pkey_handle_t pkey;
     hal_error_t ret;
 
+    check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
     check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle));
 
     /* call the local function */
@@ -405,9 +425,11 @@ static hal_error_t pkey_close(const uint8_t **iptr, const uint8_t * const ilimit
 static hal_error_t pkey_delete(const uint8_t **iptr, const uint8_t * const ilimit,
                                uint8_t **optr, const uint8_t * const olimit)
 {
+    hal_client_handle_t client __attribute__((unused));
     hal_pkey_handle_t pkey;
     hal_error_t ret;
 
+    check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
     check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle));
 
     /* call the local function */
@@ -418,11 +440,13 @@ static hal_error_t pkey_delete(const uint8_t **iptr, const uint8_t * const ilimi
 static hal_error_t pkey_rename(const uint8_t **iptr, const uint8_t * const ilimit,
                                uint8_t **optr, const uint8_t * const olimit)
 {
+    hal_client_handle_t client __attribute__((unused));
     hal_pkey_handle_t pkey;
     const uint8_t *name;
     uint32_t name_len;
     hal_error_t ret;
 
+    check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
     check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle));
     check(hal_xdr_decode_buffer_in_place(iptr, ilimit, &name, &name_len));
 
@@ -434,10 +458,12 @@ static hal_error_t pkey_rename(const uint8_t **iptr, const uint8_t * const ilimi
 static hal_error_t pkey_get_key_type(const uint8_t **iptr, const uint8_t * const ilimit,
                                      uint8_t **optr, const uint8_t * const olimit)
 {
+    hal_client_handle_t client __attribute__((unused));
     hal_pkey_handle_t pkey;
     hal_key_type_t type;
     hal_error_t ret;
 
+    check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
     check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle));
 
     /* call the local function */
@@ -450,10 +476,12 @@ static hal_error_t pkey_get_key_type(const uint8_t **iptr, const uint8_t * const
 static hal_error_t pkey_get_key_flags(const uint8_t **iptr, const uint8_t * const ilimit,
                                       uint8_t **optr, const uint8_t * const olimit)
 {
+    hal_client_handle_t client __attribute__((unused));
     hal_pkey_handle_t pkey;
     hal_key_flags_t flags;
     hal_error_t ret;
 
+    check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
     check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle));
 
     /* call the local function */
@@ -466,10 +494,12 @@ static hal_error_t pkey_get_key_flags(const uint8_t **iptr, const uint8_t * cons
 static hal_error_t pkey_get_public_key_len(const uint8_t **iptr, const uint8_t * const ilimit,
                                            uint8_t **optr, const uint8_t * const olimit)
 {
+    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));
 
     /* call the local function */
@@ -481,12 +511,14 @@ static hal_error_t pkey_get_public_key_len(const uint8_t **iptr, const uint8_t *
 static hal_error_t pkey_get_public_key(const uint8_t **iptr, const uint8_t * const ilimit,
                                        uint8_t **optr, const uint8_t * const olimit)
 {
+    hal_client_handle_t client __attribute__((unused));
     hal_pkey_handle_t pkey;
     size_t len;
     uint32_t len_max;
     uint8_t *optr_orig = *optr;
     hal_error_t ret;
 
+    check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
     check(hal_xdr_decode_int(iptr, ilimit, &pkey.handle));
     check(hal_xdr_decode_int(iptr, ilimit, &len_max));
     /* sanity check len_max */
@@ -512,6 +544,7 @@ static hal_error_t pkey_get_public_key(const uint8_t **iptr, const uint8_t * con
 static hal_error_t pkey_remote_sign(const uint8_t **iptr, const uint8_t * const ilimit,
                                     uint8_t **optr, const uint8_t * const olimit)
 {
+    hal_client_handle_t client __attribute__((unused));
     hal_session_handle_t session;
     hal_pkey_handle_t pkey;
     hal_hash_handle_t hash;
@@ -522,6 +555,7 @@ static hal_error_t pkey_remote_sign(const uint8_t **iptr, const uint8_t * const
     uint8_t *optr_orig = *optr;
     hal_error_t ret;
 
+    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, &pkey.handle));
     check(hal_xdr_decode_int(iptr, ilimit, &hash.handle));
@@ -546,6 +580,7 @@ static hal_error_t pkey_remote_sign(const uint8_t **iptr, const uint8_t * const
 static hal_error_t pkey_remote_verify(const uint8_t **iptr, const uint8_t * const ilimit,
                                       uint8_t **optr, const uint8_t * const olimit)
 {
+    hal_client_handle_t client __attribute__((unused));
     hal_session_handle_t session;
     hal_pkey_handle_t pkey;
     hal_hash_handle_t hash;
@@ -555,6 +590,7 @@ static hal_error_t pkey_remote_verify(const uint8_t **iptr, const uint8_t * cons
     uint32_t sig_len;
     hal_error_t ret;
 
+    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, &pkey.handle));
     check(hal_xdr_decode_int(iptr, ilimit, &hash.handle));
@@ -583,11 +619,13 @@ static hal_error_t hal_xdr_encode_pkey_info(uint8_t **optr, const uint8_t * cons
 static hal_error_t pkey_list(const uint8_t **iptr, const uint8_t * const ilimit,
                              uint8_t **optr, const uint8_t * const olimit)
 {
+    hal_client_handle_t client __attribute__((unused));
     uint8_t *optr_orig = *optr;
     uint32_t result_max;
     hal_key_flags_t flags;
     hal_error_t ret;
 
+    check(hal_xdr_decode_int(iptr, ilimit, &client.handle));
     check(hal_xdr_decode_int(iptr, ilimit, &result_max));
     check(hal_xdr_decode_int(iptr, ilimit, &flags));
 
@@ -613,13 +651,16 @@ void 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 * ilimit = ibuf + ilen;
-    uint8_t * optr = obuf + 4;		/* reserve 4 bytes for return code */
-    uint8_t * olimit = obuf + *olen;
+    const uint8_t * const ilimit = ibuf + ilen;
+    uint8_t * optr = obuf + 12;	/* reserve space for opcode, client, and response code */
+    const uint8_t * const olimit = obuf + *olen;
     uint32_t rpc_func_num;
+    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);
     switch (rpc_func_num) {
     case RPC_FUNC_GET_VERSION:
         ret = get_version(&iptr, ilimit, &optr, olimit);
@@ -706,9 +747,11 @@ void hal_rpc_server_dispatch(const uint8_t * const ibuf, const size_t ilen,
         ret = HAL_ERROR_RPC_BAD_FUNCTION;
         break;
     }
-    /* encode the return code at the beginning of the payload */
+    /* 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);
 }
 
diff --git a/xdr.c b/xdr.c
index 6266d99..27b8593 100644
--- a/xdr.c
+++ b/xdr.c
@@ -75,6 +75,17 @@ hal_error_t hal_xdr_decode_int(const uint8_t ** const inbuf, const uint8_t * con
     return HAL_OK;
 }
 
+/* Undo the last decode_int - roll back the input pointer.
+ */
+hal_error_t hal_xdr_undecode_int(const uint8_t ** const inbuf)
+{
+    if (inbuf == NULL || *inbuf == NULL)
+        return HAL_ERROR_BAD_ARGUMENTS;
+
+    *inbuf -= sizeof(uint32_t);
+    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.
diff --git a/xdr_internal.h b/xdr_internal.h
index 921b991..9d02fd3 100644
--- a/xdr_internal.h
+++ b/xdr_internal.h
@@ -47,6 +47,8 @@ hal_error_t hal_xdr_decode_int(const uint8_t ** const inbuf,
                                const uint8_t * const limit,
                                uint32_t * const value);
 
+hal_error_t hal_xdr_undecode_int(const uint8_t ** const inbuf);
+
 hal_error_t hal_xdr_encode_buffer(uint8_t ** const outbuf,
                                   const uint8_t * const limit,
                                   const uint8_t * const value,

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Commits mailing list