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) diff --git a/libtock-sync/crypto/hmac.c b/libtock-sync/crypto/hmac.c index e38f188c9..ffe520b6a 100644 --- a/libtock-sync/crypto/hmac.c +++ b/libtock-sync/crypto/hmac.c @@ -1,16 +1,6 @@ -#include "hmac.h" - -struct hmac_data { - bool fired; - returncode_t ret; -}; +#include -static struct hmac_data result = {.fired = false}; - -static void hmac_cb_hmac(returncode_t ret) { - result.fired = true; - result.ret = ret; -} +#include "hmac.h" returncode_t libtocksync_hmac_simple(libtock_hmac_algorithm_t hmac_type, uint8_t* key_buffer, uint32_t key_length, @@ -18,24 +8,29 @@ returncode_t libtocksync_hmac_simple(libtock_hmac_algorithm_t hmac_type, uint8_t* hmac_buffer, uint32_t hmac_length) { returncode_t ret; - result.fired = false; - - ret = libtock_hmac_simple(hmac_type, key_buffer, key_length, input_buffer, input_length, hmac_buffer, hmac_length, - hmac_cb_hmac); + ret = libtock_hmac_command_set_algorithm((uint32_t) hmac_type); 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_key_buffer(key_buffer, key_length); + if (ret != RETURNCODE_SUCCESS) return ret; + defer { libtock_hmac_set_readonly_allow_key_buffer(NULL, 0); + }; - ret = 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); + }; - ret = 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); + }; - ret = libtock_hmac_set_readwrite_allow_destination_buffer(NULL, 0); + ret = libtock_hmac_command_run(); if (ret != RETURNCODE_SUCCESS) return ret; - return RETURNCODE_SUCCESS; + // Wait for the operation. + ret = libtocksync_hmac_yield_wait_for(); + + 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.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..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`. @@ -27,7 +21,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 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 diff --git a/libtock/defer.h b/libtock/defer.h new file mode 100644 index 000000000..49b1c977b --- /dev/null +++ b/libtock/defer.h @@ -0,0 +1,27 @@ +#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 + +#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) + +#ifdef __cplusplus +} +#endif