diff --git a/app/00sec_edhoc/main.c b/app/00sec_edhoc/main.c new file mode 100644 index 0000000..c91c28d --- /dev/null +++ b/app/00sec_edhoc/main.c @@ -0,0 +1,54 @@ +#include +#include +#include + +#include "bl_timer_hf.h" +#include "sec.h" + +//=========================== defines ========================================== + +#define BLINK_APP_TIMER_DEV 1 + +typedef struct { + uint8_t m1[MAX_MESSAGE_SIZE_LEN]; + uint8_t m1_len; +} edhoc_vars_t; + +//=========================== variables ======================================== + +edhoc_vars_t node_vars = { 0 }; + +//=========================== prototypes ======================================= + +//=========================== main ============================================= + +int main(void) +{ + printf("Hello Blink Node\n"); + int8_t res = 0; + uint32_t ts; + + bl_timer_hf_init(BLINK_APP_TIMER_DEV); + + bl_sec_init(); + + while (1) { + ts = bl_timer_hf_now(BLINK_APP_TIMER_DEV); + res = bl_sec_edhoc_init(); + printf("init time: %u\n", bl_timer_hf_now(BLINK_APP_TIMER_DEV)-ts); + if (res != 0) { + printf("Error sec: %d\n", res); + } + + ts = bl_timer_hf_now(BLINK_APP_TIMER_DEV); + res = bl_sec_edhoc_prepare_m1(node_vars.m1, &node_vars.m1_len); + printf("m1 time: %u\n", bl_timer_hf_now(BLINK_APP_TIMER_DEV)-ts); + if (res != 0) { + printf("Error sec: %d\n", res); + } + + __SEV(); + __WFE(); + __WFE(); + } +} diff --git a/app/03app_node/main.c b/app/03app_node/main.c index 84c0171..f612bdf 100644 --- a/app/03app_node/main.c +++ b/app/03app_node/main.c @@ -13,9 +13,12 @@ #include #include "bl_radio.h" +#include "sec.h" +#include "bl_device.h" #include "bl_timer_hf.h" -#include "blink.h" #include "packet.h" +#include "queue.h" +#include "blink.h" //=========================== defines ========================================== diff --git a/app/app-drv-blink.emProject b/app/app-drv-blink.emProject index 184e556..7143388 100644 --- a/app/app-drv-blink.emProject +++ b/app/app-drv-blink.emProject @@ -25,6 +25,33 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/app-node.emProject b/app/app-node.emProject index 80cfb6a..61f4e5a 100644 --- a/app/app-node.emProject +++ b/app/app-node.emProject @@ -5,6 +5,7 @@ Name="Common" project_dependencies="01blink(01blink);00drv_bl_timer_hf(00drv)" project_directory="03app_node" + linker_additional_files="$(ProjectDir)/../../sec/liblakers_c_dbg.a" project_type="Executable" /> diff --git a/blink/blink.c b/blink/blink.c index 13d97fc..1e07522 100644 --- a/blink/blink.c +++ b/blink/blink.c @@ -14,6 +14,7 @@ #include #include +#include "sec.h" #include "bl_device.h" #include "models.h" #include "packet.h" @@ -51,6 +52,7 @@ void blink_init(bl_node_type_t node_type, schedule_t *app_schedule, bl_event_cb_ _blink_vars.node_type = node_type; _blink_vars.app_event_callback = app_event_callback; + bl_sec_init(); bl_assoc_init(event_callback); bl_scheduler_init(node_type, app_schedule); bl_mac_init(node_type, event_callback); diff --git a/blink/blink.emProject b/blink/blink.emProject index 27d0876..4961808 100644 --- a/blink/blink.emProject +++ b/blink/blink.emProject @@ -4,11 +4,11 @@ Name="Common" build_output_directory="Output/$(BuildTarget)/$(Configuration)/Obj" build_output_file_name="$(OutDir)/$(ProjectName)-$(BuildTarget)$(LIB)" - c_user_include_directories="$(SolutionDir);$(SolutionDir)/../drv;$(PackagesDir)/nRF/Device/Include;$(PackagesDir)/CMSIS_5/CMSIS/Core/Include" /> + c_user_include_directories="$(SolutionDir);$(SolutionDir)/../drv;$(SolutionDir)/../sec;$(PackagesDir)/nRF/Device/Include;$(PackagesDir)/CMSIS_5/CMSIS/Core/Include" /> #include #include +#include #include "blink.h" #include "mac.h" diff --git a/blink/queue.c b/blink/queue.c index 0bb339a..db7357e 100644 --- a/blink/queue.c +++ b/blink/queue.c @@ -14,6 +14,7 @@ #include #include +#include "sec.h" #include "packet.h" #include "mac.h" #include "scheduler.h" @@ -122,7 +123,19 @@ bool bl_queue_pop(void) { } void bl_queue_set_join_request(uint64_t node_id) { - queue_vars.join_packet.length = bl_build_packet_join_request(queue_vars.join_packet.buffer, node_id); + uint8_t len = bl_build_packet_join_request(queue_vars.join_packet.buffer, node_id); + + // obtain and set edhoc message 1 + bl_sec_edhoc_init(); + uint8_t m1[MAX_MESSAGE_SIZE_LEN], m1_len; + int8_t res = bl_sec_edhoc_prepare_m1(m1, &m1_len); + if (res != 0) { + return; + } + memcpy(queue_vars.join_packet.buffer + len, m1, m1_len); + len += m1_len; + + queue_vars.join_packet.length = len; } void bl_queue_set_join_response(uint64_t node_id, uint8_t assigned_cell_id) { diff --git a/nrf52840dk.emProject b/nrf52840dk.emProject index 73a0ad2..9c115ae 100644 --- a/nrf52840dk.emProject +++ b/nrf52840dk.emProject @@ -29,7 +29,7 @@ build_treat_warnings_as_errors="Yes" c_additional_options="-Wno-missing-field-initializers" c_preprocessor_definitions="ARM_MATH_CM4;NRF52840_XXAA;__nRF_FAMILY;CONFIG_NFCT_PINS_AS_GPIOS;FLASH_PLACEMENT=1;BOARD_NRF52840DK" - c_user_include_directories="$(SolutionDir)/../drv;$(SolutionDir)/../blink;$(PackagesDir)/nRF/Device/Include;$(PackagesDir)/CMSIS_5/CMSIS/Core/Include" + c_user_include_directories="$(SolutionDir)/../drv;$(SolutionDir)/../sec;$(SolutionDir)/../blink;$(PackagesDir)/nRF/Device/Include;$(PackagesDir)/CMSIS_5/CMSIS/Core/Include" clang_machine_outliner="Yes" compiler_color_diagnostics="Yes" debug_register_definition_file="$(PackagesDir)/nRF/XML/nrf52840_Registers.xml" @@ -67,6 +67,7 @@ gcc_omit_frame_pointer="Yes" gcc_optimization_level="Level 2 balanced" /> + diff --git a/sec/lakers.h b/sec/lakers.h new file mode 120000 index 0000000..8a87236 --- /dev/null +++ b/sec/lakers.h @@ -0,0 +1 @@ +/home/gfedrech/Developer/inria/dev/lakers-FORK/target/include/lakers.h \ No newline at end of file diff --git a/sec/lakers_ead_authz.h b/sec/lakers_ead_authz.h new file mode 120000 index 0000000..d7872c5 --- /dev/null +++ b/sec/lakers_ead_authz.h @@ -0,0 +1 @@ +/home/gfedrech/Developer/inria/dev/lakers-FORK/target/include/lakers_ead_authz.h \ No newline at end of file diff --git a/sec/lakers_shared.h b/sec/lakers_shared.h new file mode 120000 index 0000000..2beabc5 --- /dev/null +++ b/sec/lakers_shared.h @@ -0,0 +1 @@ +/home/gfedrech/Developer/inria/dev/lakers-FORK/target/include/lakers_shared.h \ No newline at end of file diff --git a/sec/sec.c b/sec/sec.c new file mode 100644 index 0000000..bc704ed --- /dev/null +++ b/sec/sec.c @@ -0,0 +1,139 @@ +/** + * @file + * @ingroup sec + * + * @brief Security functions + * + * @author Geovane Fedrecheski + * + * @copyright Inria, 2025 + */ + +#include +#include +#include +#include +#include + +#include "sec.h" + +#ifdef LAKERS_PSA +extern void mbedtls_memory_buffer_alloc_init(uint8_t *buf, size_t len); +#endif + +//=========================== defines ========================================== + +typedef struct { + bl_edhoc_state_t state; + + CredentialC cred_i, fetched_cred_r; + IdCred id_cred_r; + EdhocInitiator initiator; + + // used during execution of EDHOC + EdhocMessageBuffer message_1; + uint8_t c_r; + EdhocMessageBuffer message_2; + EdhocMessageBuffer message_3; + uint8_t prk_out[SHA256_DIGEST_LEN]; + + // used during execution of authz + EadAuthzDevice device; + EADItemC ead_1, ead_2; + BytesP256ElemLen authz_secret; +} sec_vars_t; + +//=========================== variables ======================================== + +#define EDHOC_INITIATOR_INDEX 0 + +// -------- for EDHOC -------- +static const uint8_t CRED_I[2][100] = { + {0xA2, 0x02, 0x70, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x08, 0xA1, 0x01, 0xA5, 0x01, 0x02, 0x02, 0x41, 0x01, 0x20, 0x01, 0x21, 0x58, 0x20, 0x52, 0x7C, 0x4D, 0x4C, 0x08, 0x9F, 0x9F, 0xE3, 0x33, 0x56, 0xAA, 0x97, 0xA1, 0xD6, 0x72, 0xDA, 0x32, 0xC1, 0x60, 0x08, 0x24, 0x4F, 0xEF, 0x37, 0xF0, 0x71, 0x54, 0xE0, 0x70, 0xE6, 0x6D, 0x1F, 0x22, 0x58, 0x20, 0x32, 0xE4, 0x6C, 0x45, 0xC4, 0xDD, 0xCB, 0x6D, 0x6C, 0x52, 0x4F, 0x37, 0x9D, 0x57, 0x15, 0x9D, 0x64, 0x2D, 0xD7, 0xF0, 0x27, 0x9C, 0x45, 0x50, 0xE3, 0x44, 0x48, 0xDA, 0xC4, 0x19, 0x53, 0x2C}, + {0xa2, 0x02, 0x70, 0x31, 0x32, 0x33, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xa1, 0x01, 0xa5, 0x01, 0x02, 0x02, 0x41, 0x02, 0x20, 0x01, 0x21, 0x58, 0x20, 0xed, 0x47, 0xd7, 0xb6, 0xd0, 0x0c, 0x41, 0x4b, 0xa9, 0xfe, 0x1c, 0x9e, 0x6d, 0x2b, 0x07, 0x85, 0x45, 0x14, 0x36, 0x76, 0x6d, 0x5c, 0x0e, 0x65, 0xf3, 0xd7, 0xe3, 0x3b, 0x0d, 0x35, 0x4a, 0xd6, 0x22, 0x58, 0x20, 0x44, 0x3e, 0xda, 0x79, 0x2f, 0x81, 0x88, 0x44, 0xc8, 0x86, 0xbd, 0x1e, 0xc6, 0xfa, 0x0b, 0xd3, 0x61, 0xf8, 0xaa, 0xc9, 0xa8, 0xbc, 0xc2, 0x28, 0x65, 0x02, 0xaa, 0x9e, 0xb9, 0xea, 0xbb, 0xf4}, +}; +static const BytesP256ElemLen I[2] = { + {0x1f, 0x7e, 0x4a, 0xe4, 0x29, 0x3a, 0x34, 0x8b, 0xf2, 0xb1, 0x36, 0x5c, 0xe0, 0x98, 0xaa, 0x49, 0xc2, 0x07, 0xbd, 0x1b, 0xa7, 0xdd, 0xde, 0xcd, 0xfa, 0xd6, 0x0c, 0xad, 0xe8, 0x2e, 0x9e, 0xf5}, + {0x3c, 0xa8, 0x54, 0xbf, 0xaa, 0x90, 0xda, 0x16, 0xe1, 0xa8, 0xfa, 0xcc, 0x0c, 0xd8, 0x34, 0x92, 0x7e, 0xc0, 0xb3, 0x19, 0x74, 0x8b, 0xb4, 0x79, 0xf1, 0x31, 0x6b, 0x8d, 0x38, 0x30, 0x74, 0xa8}, +}; + +// --------for EAD authz ----- +static const uint8_t ID_U[2][4] = { + {0xa1, 0x04, 0x41, 0x01}, + {0xa1, 0x04, 0x41, 0x02}, +}; +static const size_t ID_U_LEN = sizeof(ID_U[EDHOC_INITIATOR_INDEX]) / sizeof(ID_U[EDHOC_INITIATOR_INDEX][0]); +static const BytesP256ElemLen G_W = {0xFF, 0xA4, 0xF1, 0x02, 0x13, 0x40, 0x29, 0xB3, 0xB1, 0x56, 0x89, 0x0B, 0x88, 0xC9, 0xD9, 0x61, 0x95, 0x01, 0x19, 0x65, 0x74, 0x17, 0x4D, 0xCB, 0x68, 0xA0, 0x7D, 0xB0, 0x58, 0x8E, 0x4D, 0x41}; +static const uint8_t LOC_W[] = "http://localhost:18000"; +static const uint8_t LOC_W_LEN = (sizeof(LOC_W) / sizeof(LOC_W[0])) - 1; // -1 to discard the \0 at the end +static const uint8_t SS = 2; + +// -------- crypto backend ----- +#ifdef LAKERS_PSA +uint8_t mbedtls_buffer[4096 * 2] = {0}; +#endif + +sec_vars_t sec_vars = { 0 }; + +//=========================== prototypes ======================================= + +//=========================== public =========================================== + +void bl_sec_init(void) { +#ifdef LAKERS_PSA + mbedtls_memory_buffer_alloc_init(mbedtls_buffer, 4096 * 2); +#endif +} + +void bl_sec_edhoc_set_state(bl_edhoc_state_t state) { + sec_vars.state = state; +} + +int8_t bl_sec_edhoc_init(void) { + int8_t res; + + res = credential_new(&sec_vars.cred_i, CRED_I[EDHOC_INITIATOR_INDEX], sizeof(CRED_I[EDHOC_INITIATOR_INDEX]) / sizeof(CRED_I[EDHOC_INITIATOR_INDEX][0])); + if (res != 0) { + return res; + } + + res = initiator_new(&sec_vars.initiator); + if (res != 0) { + return res; + } + + res = authz_device_new(&sec_vars.device, ID_U[EDHOC_INITIATOR_INDEX], ID_U_LEN, &G_W, LOC_W, LOC_W_LEN); + if (res != 0) { + return res; + } + + return 0; +} + +uint8_t bl_sec_edhoc_prepare_m1(uint8_t *msg_1, uint8_t *msg1_len) { + // prepare message_1 and ead_1 + int8_t res = initiator_compute_ephemeral_secret(&sec_vars.initiator, &G_W, &sec_vars.authz_secret); + if (res != 0) { + return res; + } + + res = authz_device_prepare_ead_1(&sec_vars.device, &sec_vars.authz_secret, SS, &sec_vars.ead_1); + if (res != 0) { + return res; + } + + res = initiator_prepare_message_1(&sec_vars.initiator, NULL, &sec_vars.ead_1, &sec_vars.message_1); + // res = initiator_prepare_message_1(&sec_vars.initiator, NULL, NULL, &sec_vars.message_1); + if (res != 0) { + return res; + } + + // save h_message_1 for later + memcpy(sec_vars.device.wait_ead2.h_message_1, sec_vars.initiator.wait_m2.h_message_1, SHA256_DIGEST_LEN); + + // copy message_1 out + memcpy(msg_1, sec_vars.message_1.content, sec_vars.message_1.len); + *msg1_len = sec_vars.message_1.len; + + return 0; +} diff --git a/sec/sec.emProject b/sec/sec.emProject new file mode 100644 index 0000000..6442896 --- /dev/null +++ b/sec/sec.emProject @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/sec/sec.h b/sec/sec.h new file mode 100644 index 0000000..8256d6e --- /dev/null +++ b/sec/sec.h @@ -0,0 +1,34 @@ +#ifndef __SEC_H +#define __SEC_H + +/** + * @defgroup sec security + * @ingroup security + * @brief Security module + * + * @{ + * @file + * @author Geovane Fedrecheski + * @copyright Inria, 2025-now + * @} + */ + +#include +#include +#include +#include + +#include "lakers.h" +#include "lakers_shared.h" +#include "lakers_ead_authz.h" + +typedef enum { + EDHOC_M1_SENT, +} bl_edhoc_state_t; + +void bl_sec_init(void); +void bl_sec_edhoc_set_state(bl_edhoc_state_t state); +int8_t bl_sec_edhoc_init(void); +uint8_t bl_sec_edhoc_prepare_m1(uint8_t *msg_1, uint8_t *msg1_len); + +#endif // __SEC_H