From 0dd7cc4a21e6f12c61fa46e92b1d0f193acd0982 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Wed, 9 Jul 2025 13:54:25 -0400 Subject: [PATCH 1/8] libtock-sync: make: add crypto syscalls --- libtock-sync/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/libtock-sync/Makefile b/libtock-sync/Makefile index 13d62e794..cdd1b301f 100644 --- a/libtock-sync/Makefile +++ b/libtock-sync/Makefile @@ -10,6 +10,7 @@ $(LIBNAME)_SRC_ROOT := $(TOCK_USERLAND_BASE_DIR) # List all C and Assembly files $(LIBNAME)_SRCS := $(wildcard $($(LIBNAME)_DIR)/*.c) $(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/crypto/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/crypto/syscalls/*.c) $(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/display/*.c) $(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/interface/*.c) $(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/kernel/*.c) From 565d65320db4843471b7d30238db79778005608c Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Wed, 9 Jul 2025 13:55:02 -0400 Subject: [PATCH 2/8] libtock: hmac: correct buffer arg name --- libtock/crypto/hmac.c | 4 ++-- libtock/crypto/hmac.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libtock/crypto/hmac.c b/libtock/crypto/hmac.c index 0984b1e81..0f4790cf4 100644 --- a/libtock/crypto/hmac.c +++ b/libtock/crypto/hmac.c @@ -11,7 +11,7 @@ static void hmac_upcall(int ret, returncode_t libtock_hmac_simple(libtock_hmac_algorithm_t hmac_type, uint8_t* key_buffer, uint32_t key_length, uint8_t* input_buffer, uint32_t input_length, - uint8_t* hash_buffer, uint32_t hash_length, + uint8_t* hmac_buffer, uint32_t hmac_length, libtock_hmac_callback_hmac cb) { returncode_t ret; @@ -25,7 +25,7 @@ returncode_t libtock_hmac_simple(libtock_hmac_algorithm_t hmac_type, ret = libtock_hmac_set_readonly_allow_data_buffer(input_buffer, input_length); if (ret != RETURNCODE_SUCCESS) return ret; - ret = libtock_hmac_set_readwrite_allow_destination_buffer(hash_buffer, hash_length); + ret = libtock_hmac_set_readwrite_allow_destination_buffer(hmac_buffer, hmac_length); if (ret != RETURNCODE_SUCCESS) return ret; ret = libtock_hmac_set_upcall(hmac_upcall, cb); diff --git a/libtock/crypto/hmac.h b/libtock/crypto/hmac.h index b9e496b25..6c6b87ae4 100644 --- a/libtock/crypto/hmac.h +++ b/libtock/crypto/hmac.h @@ -27,7 +27,7 @@ typedef enum { returncode_t libtock_hmac_simple(libtock_hmac_algorithm_t hmac_type, uint8_t* key_buffer, uint32_t key_length, uint8_t* input_buffer, uint32_t input_length, - uint8_t* hash_buffer, uint32_t hash_length, + uint8_t* hmac_buffer, uint32_t hmac_length, libtock_hmac_callback_hmac cb); #ifdef __cplusplus From 248d5b732833d6e39e956d884d4aa537721936c9 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Wed, 9 Jul 2025 13:55:24 -0400 Subject: [PATCH 3/8] libtock-sync: hmac: use ywf --- libtock-sync/crypto/hmac.c | 46 +++++++++----------- libtock-sync/crypto/hmac.h | 4 +- libtock-sync/crypto/syscalls/hmac_syscalls.c | 8 ++++ libtock-sync/crypto/syscalls/hmac_syscalls.h | 15 +++++++ libtock/crypto/hmac.h | 8 +--- libtock/crypto/hmac_types.h | 17 ++++++++ 6 files changed, 65 insertions(+), 33 deletions(-) create mode 100644 libtock-sync/crypto/syscalls/hmac_syscalls.c create mode 100644 libtock-sync/crypto/syscalls/hmac_syscalls.h create mode 100644 libtock/crypto/hmac_types.h diff --git a/libtock-sync/crypto/hmac.c b/libtock-sync/crypto/hmac.c index e38f188c9..0c673fa08 100644 --- a/libtock-sync/crypto/hmac.c +++ b/libtock-sync/crypto/hmac.c @@ -1,41 +1,37 @@ #include "hmac.h" -struct hmac_data { - bool fired; - returncode_t ret; -}; - -static struct hmac_data result = {.fired = false}; - -static void hmac_cb_hmac(returncode_t ret) { - result.fired = true; - result.ret = ret; -} - returncode_t libtocksync_hmac_simple(libtock_hmac_algorithm_t hmac_type, uint8_t* key_buffer, uint32_t key_length, uint8_t* input_buffer, uint32_t input_length, uint8_t* hmac_buffer, uint32_t hmac_length) { returncode_t ret; - result.fired = false; + ret = libtock_hmac_command_set_algorithm((uint32_t) hmac_type); + if (ret != RETURNCODE_SUCCESS) return ret; - ret = libtock_hmac_simple(hmac_type, key_buffer, key_length, input_buffer, input_length, hmac_buffer, hmac_length, - hmac_cb_hmac); + ret = libtock_hmac_set_readonly_allow_key_buffer(key_buffer, key_length); if (ret != RETURNCODE_SUCCESS) return ret; - // Wait for the callback. - yield_for(&result.fired); - if (result.ret != RETURNCODE_SUCCESS) return result.ret; + ret = libtock_hmac_set_readonly_allow_data_buffer(input_buffer, input_length); + if (ret != RETURNCODE_SUCCESS) goto exit1; - ret = libtock_hmac_set_readonly_allow_key_buffer(NULL, 0); - if (ret != RETURNCODE_SUCCESS) return ret; + ret = libtock_hmac_set_readwrite_allow_destination_buffer(hmac_buffer, hmac_length); + if (ret != RETURNCODE_SUCCESS) goto exit2; - ret = libtock_hmac_set_readonly_allow_data_buffer(NULL, 0); - if (ret != RETURNCODE_SUCCESS) return ret; + ret = libtock_hmac_command_run(); + if (ret != RETURNCODE_SUCCESS) goto exit3; - ret = libtock_hmac_set_readwrite_allow_destination_buffer(NULL, 0); - if (ret != RETURNCODE_SUCCESS) return ret; + // Wait for the operation. + ret = libtocksync_hmac_yield_wait_for(); + +exit3: + libtock_hmac_set_readwrite_allow_destination_buffer(NULL, 0); + +exit2: + libtock_hmac_set_readonly_allow_data_buffer(NULL, 0); + +exit1: + libtock_hmac_set_readonly_allow_key_buffer(NULL, 0); - return RETURNCODE_SUCCESS; + return ret; } diff --git a/libtock-sync/crypto/hmac.h b/libtock-sync/crypto/hmac.h index 5655b0a62..7139896ec 100644 --- a/libtock-sync/crypto/hmac.h +++ b/libtock-sync/crypto/hmac.h @@ -1,8 +1,10 @@ #pragma once -#include +#include #include +#include "syscalls/hmac_syscalls.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/libtock-sync/crypto/syscalls/hmac_syscalls.c b/libtock-sync/crypto/syscalls/hmac_syscalls.c new file mode 100644 index 000000000..7bdf3a468 --- /dev/null +++ b/libtock-sync/crypto/syscalls/hmac_syscalls.c @@ -0,0 +1,8 @@ +#include "hmac_syscalls.h" + +returncode_t libtocksync_hmac_yield_wait_for(void) { + yield_waitfor_return_t ret; + ret = yield_wait_for(DRIVER_NUM_HMAC, 0); + + return (returncode_t) ret.data0; +} diff --git a/libtock-sync/crypto/syscalls/hmac_syscalls.h b/libtock-sync/crypto/syscalls/hmac_syscalls.h new file mode 100644 index 000000000..b8a47274d --- /dev/null +++ b/libtock-sync/crypto/syscalls/hmac_syscalls.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Wait for an HMAC operation to finish. +returncode_t libtocksync_hmac_yield_wait_for(void); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/crypto/hmac.h b/libtock/crypto/hmac.h index 6c6b87ae4..4a7c9881f 100644 --- a/libtock/crypto/hmac.h +++ b/libtock/crypto/hmac.h @@ -1,6 +1,7 @@ #pragma once #include "../tock.h" +#include "hmac_types.h" #include "syscalls/hmac_syscalls.h" #ifdef __cplusplus @@ -12,13 +13,6 @@ extern "C" { // - `arg1` (`returncode_t`): Status from computing the HMAC. typedef void (*libtock_hmac_callback_hmac)(returncode_t); -typedef enum { - LIBTOCK_HMAC_SHA256 = 0, - LIBTOCK_HMAC_SHA384 = 1, - LIBTOCK_HMAC_SHA512 = 2, -} libtock_hmac_algorithm_t; - - // Compute an HMAC using `keyb_buffer` over `input_buffer` and store the result // in `hash_buffer`. diff --git a/libtock/crypto/hmac_types.h b/libtock/crypto/hmac_types.h new file mode 100644 index 000000000..b31a7e765 --- /dev/null +++ b/libtock/crypto/hmac_types.h @@ -0,0 +1,17 @@ +#pragma once + +#include "../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + LIBTOCK_HMAC_SHA256 = 0, + LIBTOCK_HMAC_SHA384 = 1, + LIBTOCK_HMAC_SHA512 = 2, +} libtock_hmac_algorithm_t; + +#ifdef __cplusplus +} +#endif From 9133bf95c2f2f8aa2274721ed3b4da3b2148f1f4 Mon Sep 17 00:00:00 2001 From: Pat Pannuto Date: Wed, 16 Jul 2025 12:45:35 -0700 Subject: [PATCH 4/8] PoC: scoped allow for hmac --- libtock-sync/crypto/hmac.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/libtock-sync/crypto/hmac.c b/libtock-sync/crypto/hmac.c index 0c673fa08..80605952a 100644 --- a/libtock-sync/crypto/hmac.c +++ b/libtock-sync/crypto/hmac.c @@ -1,5 +1,10 @@ #include "hmac.h" +// would be in a libtock-sync/support.h or internal.h or similar +#define SCOPED_ALLOW(method, buffer, length) \ + inline void unallow_##buffer(returncode_t* sentinel##buffer) { if (sentinel##buffer == RETURNCODE_SUCCESS) method(NULL, 0); } \ + returncode_t ret_##buffer __attribute__((cleanup(unallow_##buffer))) = method(buffer, length); \ + returncode_t libtocksync_hmac_simple(libtock_hmac_algorithm_t hmac_type, uint8_t* key_buffer, uint32_t key_length, uint8_t* input_buffer, uint32_t input_length, @@ -9,29 +14,25 @@ returncode_t libtocksync_hmac_simple(libtock_hmac_algorithm_t hmac_type, ret = libtock_hmac_command_set_algorithm((uint32_t) hmac_type); if (ret != RETURNCODE_SUCCESS) return ret; - ret = libtock_hmac_set_readonly_allow_key_buffer(key_buffer, key_length); - if (ret != RETURNCODE_SUCCESS) return ret; + // Macro expands to this: + // + // inline void unallow_key_buffer(returncode_t* sentinel_key_buffer) { if (sentinel_key_buffer == RETURNCODE_SUCCESS) libtock_hmac_set_readonly_allow_key_buffer(NULL, 0); } + // returncode_t ret_key_buffer __attribute__((cleanup(unallow_key_buffer))) = libtock_hmac_set_readonly_allow_key_buffer(key_buffer, key_length); - ret = libtock_hmac_set_readonly_allow_data_buffer(input_buffer, input_length); - if (ret != RETURNCODE_SUCCESS) goto exit1; + SCOPED_ALLOW(libtock_hmac_set_readonly_allow_key_buffer, key_buffer, key_length); + if (ret_key_buffer != RETURNCODE_SUCCESS) return ret_key_buffer; - ret = libtock_hmac_set_readwrite_allow_destination_buffer(hmac_buffer, hmac_length); - if (ret != RETURNCODE_SUCCESS) goto exit2; + SCOPED_ALLOW(libtock_hmac_set_readonly_allow_data_buffer, input_buffer, input_length); + if (ret_input_buffer != RETURNCODE_SUCCESS) return ret_input_buffer; + + SCOPED_ALLOW(libtock_hmac_set_readwrite_allow_destination_buffer, hmac_buffer, hmac_length); + if (ret_hmac_buffer != RETURNCODE_SUCCESS) return ret_hmac_buffer; ret = libtock_hmac_command_run(); - if (ret != RETURNCODE_SUCCESS) goto exit3; + if (ret != RETURNCODE_SUCCESS) return ret; // Wait for the operation. ret = libtocksync_hmac_yield_wait_for(); -exit3: - libtock_hmac_set_readwrite_allow_destination_buffer(NULL, 0); - -exit2: - libtock_hmac_set_readonly_allow_data_buffer(NULL, 0); - -exit1: - libtock_hmac_set_readonly_allow_key_buffer(NULL, 0); - return ret; } From 6a9f7dc26022f243e41d11580bbcccd16f7bfb9d Mon Sep 17 00:00:00 2001 From: Pat Pannuto Date: Wed, 16 Jul 2025 15:53:13 -0700 Subject: [PATCH 5/8] PoC: C25-preview defer approach Derived from https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/ --- libtock-sync/crypto/hmac.c | 25 ++++++++++--------------- libtock/defer.h | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 15 deletions(-) create mode 100644 libtock/defer.h diff --git a/libtock-sync/crypto/hmac.c b/libtock-sync/crypto/hmac.c index 80605952a..3fe0de0a7 100644 --- a/libtock-sync/crypto/hmac.c +++ b/libtock-sync/crypto/hmac.c @@ -1,9 +1,6 @@ #include "hmac.h" -// would be in a libtock-sync/support.h or internal.h or similar -#define SCOPED_ALLOW(method, buffer, length) \ - inline void unallow_##buffer(returncode_t* sentinel##buffer) { if (sentinel##buffer == RETURNCODE_SUCCESS) method(NULL, 0); } \ - returncode_t ret_##buffer __attribute__((cleanup(unallow_##buffer))) = method(buffer, length); \ +#include returncode_t libtocksync_hmac_simple(libtock_hmac_algorithm_t hmac_type, uint8_t* key_buffer, uint32_t key_length, @@ -14,19 +11,17 @@ returncode_t libtocksync_hmac_simple(libtock_hmac_algorithm_t hmac_type, ret = libtock_hmac_command_set_algorithm((uint32_t) hmac_type); if (ret != RETURNCODE_SUCCESS) return ret; - // Macro expands to this: - // - // inline void unallow_key_buffer(returncode_t* sentinel_key_buffer) { if (sentinel_key_buffer == RETURNCODE_SUCCESS) libtock_hmac_set_readonly_allow_key_buffer(NULL, 0); } - // returncode_t ret_key_buffer __attribute__((cleanup(unallow_key_buffer))) = libtock_hmac_set_readonly_allow_key_buffer(key_buffer, key_length); - - SCOPED_ALLOW(libtock_hmac_set_readonly_allow_key_buffer, key_buffer, key_length); - if (ret_key_buffer != RETURNCODE_SUCCESS) return ret_key_buffer; + ret = libtock_hmac_set_readonly_allow_key_buffer(key_buffer, key_length); + if (ret != RETURNCODE_SUCCESS) return ret; + defer { libtock_hmac_set_readonly_allow_key_buffer(NULL, 0); }; - SCOPED_ALLOW(libtock_hmac_set_readonly_allow_data_buffer, input_buffer, input_length); - if (ret_input_buffer != RETURNCODE_SUCCESS) return ret_input_buffer; + ret = libtock_hmac_set_readonly_allow_data_buffer(input_buffer, input_length); + if (ret != RETURNCODE_SUCCESS) return ret; + defer { libtock_hmac_set_readonly_allow_data_buffer(NULL, 0); }; - SCOPED_ALLOW(libtock_hmac_set_readwrite_allow_destination_buffer, hmac_buffer, hmac_length); - if (ret_hmac_buffer != RETURNCODE_SUCCESS) return ret_hmac_buffer; + ret = libtock_hmac_set_readwrite_allow_destination_buffer(hmac_buffer, hmac_length); + if (ret != RETURNCODE_SUCCESS) return ret; + defer { libtock_hmac_set_readwrite_allow_destination_buffer(NULL, 0); }; ret = libtock_hmac_command_run(); if (ret != RETURNCODE_SUCCESS) return ret; diff --git a/libtock/defer.h b/libtock/defer.h new file mode 100644 index 000000000..a916351d7 --- /dev/null +++ b/libtock/defer.h @@ -0,0 +1,18 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define __DEFER__(F, V) \ + auto void F(int*); \ + [[gnu::cleanup(F)]] int V; \ + auto void F(int*) + +#define defer __DEFER(__COUNTER__) +#define __DEFER(N) __DEFER_(N) +#define __DEFER_(N) __DEFER__(__DEFER_FUNCTION_ ## N, __DEFER_VARIABLE_ ## N) + +#ifdef __cplusplus +} +#endif From ede5ed8e26f26f7de0a34993853c215dd29444ea Mon Sep 17 00:00:00 2001 From: Pat Pannuto Date: Mon, 21 Jul 2025 15:46:59 -0700 Subject: [PATCH 6/8] defer: name parameter in macro to avoid warning --- libtock/defer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libtock/defer.h b/libtock/defer.h index a916351d7..a055a34bc 100644 --- a/libtock/defer.h +++ b/libtock/defer.h @@ -5,9 +5,9 @@ extern "C" { #endif #define __DEFER__(F, V) \ - auto void F(int*); \ + auto void F(int* V ## SENTINEL); \ [[gnu::cleanup(F)]] int V; \ - auto void F(int*) + auto void F(__attribute__ ((unused)) int* V ## SENTINEL) #define defer __DEFER(__COUNTER__) #define __DEFER(N) __DEFER_(N) From 8d7d488fd8b15c198e81e9ff2ee5d238ea43cb79 Mon Sep 17 00:00:00 2001 From: Pat Pannuto Date: Mon, 21 Jul 2025 15:53:35 -0700 Subject: [PATCH 7/8] defer: make fmt --- libtock-sync/crypto/hmac.c | 13 ++++++++----- libtock/defer.h | 10 +++++----- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/libtock-sync/crypto/hmac.c b/libtock-sync/crypto/hmac.c index 3fe0de0a7..ffe520b6a 100644 --- a/libtock-sync/crypto/hmac.c +++ b/libtock-sync/crypto/hmac.c @@ -1,7 +1,7 @@ -#include "hmac.h" - #include +#include "hmac.h" + returncode_t libtocksync_hmac_simple(libtock_hmac_algorithm_t hmac_type, uint8_t* key_buffer, uint32_t key_length, uint8_t* input_buffer, uint32_t input_length, @@ -13,15 +13,18 @@ returncode_t libtocksync_hmac_simple(libtock_hmac_algorithm_t hmac_type, ret = libtock_hmac_set_readonly_allow_key_buffer(key_buffer, key_length); if (ret != RETURNCODE_SUCCESS) return ret; - defer { libtock_hmac_set_readonly_allow_key_buffer(NULL, 0); }; + defer { libtock_hmac_set_readonly_allow_key_buffer(NULL, 0); + }; ret = libtock_hmac_set_readonly_allow_data_buffer(input_buffer, input_length); if (ret != RETURNCODE_SUCCESS) return ret; - defer { libtock_hmac_set_readonly_allow_data_buffer(NULL, 0); }; + defer { libtock_hmac_set_readonly_allow_data_buffer(NULL, 0); + }; ret = libtock_hmac_set_readwrite_allow_destination_buffer(hmac_buffer, hmac_length); if (ret != RETURNCODE_SUCCESS) return ret; - defer { libtock_hmac_set_readwrite_allow_destination_buffer(NULL, 0); }; + defer { libtock_hmac_set_readwrite_allow_destination_buffer(NULL, 0); + }; ret = libtock_hmac_command_run(); if (ret != RETURNCODE_SUCCESS) return ret; diff --git a/libtock/defer.h b/libtock/defer.h index a055a34bc..ad89c28ea 100644 --- a/libtock/defer.h +++ b/libtock/defer.h @@ -4,14 +4,14 @@ extern "C" { #endif -#define __DEFER__(F, V) \ - auto void F(int* V ## SENTINEL); \ - [[gnu::cleanup(F)]] int V; \ - auto void F(__attribute__ ((unused)) int* V ## SENTINEL) +#define __DEFER__(F, V) \ + auto void F(int* V##SENTINEL); \ + [[gnu::cleanup(F)]] int V; \ + auto void F(__attribute__ ((unused)) int* V##SENTINEL) #define defer __DEFER(__COUNTER__) #define __DEFER(N) __DEFER_(N) -#define __DEFER_(N) __DEFER__(__DEFER_FUNCTION_ ## N, __DEFER_VARIABLE_ ## N) +#define __DEFER_(N) __DEFER__(__DEFER_FUNCTION_##N, __DEFER_VARIABLE_##N) #ifdef __cplusplus } From bc7f0a166d1539c1535ceae5b55c051540248dbf Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Tue, 29 Jul 2025 13:53:58 -0400 Subject: [PATCH 8/8] libtock: comment defer --- libtock/defer.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libtock/defer.h b/libtock/defer.h index ad89c28ea..49b1c977b 100644 --- a/libtock/defer.h +++ b/libtock/defer.h @@ -1,5 +1,14 @@ #pragma once +// Implementation of the C `defer {}` feature. +// +// As of July 2025, upcoming versions of C will support `defer` as a way to run +// code when a value goes out of scope. See: +// https://thephd.dev/_vendor/future_cxx/technical%20specification/C%20-%20defer/C%20-%20defer%20Technical%20Specification.pdf +// +// This implements the same feature with a macro. This implementation used from +// https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/. + #ifdef __cplusplus extern "C" { #endif