diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt new file mode 100644 index 0000000..02b3d87 --- /dev/null +++ b/zephyr/CMakeLists.txt @@ -0,0 +1,130 @@ +# Copyright (c) 2022 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_UOSCORE OR CONFIG_UEDHOC) + + set(UOSCORE_UEDHOC_SRC_DIR ${ZEPHYR_CURRENT_MODULE_DIR}/src) + set(UOSCORE_UEDHOC_INCLUDE_DIR ${ZEPHYR_CURRENT_MODULE_DIR}/inc) + + zephyr_include_directories(${UOSCORE_UEDHOC_INCLUDE_DIR}) + +# Common part used by both libraries + + zephyr_library_named(uoscore_uedhoc_common) + + zephyr_library_compile_definitions(MBEDTLS) + + if(CONFIG_UOSCORE_DEBUG OR CONFIG_UEDHOC_DEBUG) + zephyr_library_compile_definitions(DEBUG_PRINT) + endif() + + zephyr_library_sources( + ${UOSCORE_UEDHOC_SRC_DIR}/common/byte_array.c + ${UOSCORE_UEDHOC_SRC_DIR}/common/crypto_wrapper.c + ${UOSCORE_UEDHOC_SRC_DIR}/common/memcpy_s.c + ${UOSCORE_UEDHOC_SRC_DIR}/common/print_util.c + ) + + zephyr_library_link_libraries(mbedTLS) + + if(CONFIG_BUILD_WITH_TFM) + zephyr_library_include_directories( + $/api_ns/interface/include + ) + endif() + +# UOSCORE + + if(CONFIG_UOSCORE) + + zephyr_library_named(uoscore) + + zephyr_library_compile_definitions(MBEDTLS) + + if(CONFIG_UOSCORE_DEBUG) + zephyr_library_compile_definitions(DEBUG_PRINT) + endif() + + zephyr_library_sources( + ${UOSCORE_UEDHOC_SRC_DIR}/oscore/aad.c + ${UOSCORE_UEDHOC_SRC_DIR}/oscore/coap2oscore.c + ${UOSCORE_UEDHOC_SRC_DIR}/oscore/nonce.c + ${UOSCORE_UEDHOC_SRC_DIR}/oscore/nvm.c + ${UOSCORE_UEDHOC_SRC_DIR}/oscore/option.c + ${UOSCORE_UEDHOC_SRC_DIR}/oscore/oscore_coap.c + ${UOSCORE_UEDHOC_SRC_DIR}/oscore/oscore_cose.c + ${UOSCORE_UEDHOC_SRC_DIR}/oscore/oscore_hkdf_info.c + ${UOSCORE_UEDHOC_SRC_DIR}/oscore/oscore_interactions.c + ${UOSCORE_UEDHOC_SRC_DIR}/oscore/oscore2coap.c + ${UOSCORE_UEDHOC_SRC_DIR}/oscore/replay_protection.c + ${UOSCORE_UEDHOC_SRC_DIR}/oscore/security_context.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/oscore_aad_array.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/oscore_enc_structure.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/oscore_info.c + ) + + zephyr_library_link_libraries(mbedTLS) + + endif() # CONFIG_UOSCORE + +# UEDHOC + + if(CONFIG_UEDHOC) + + zephyr_library_named(uedhoc) + + zephyr_library_compile_definitions(MBEDTLS) + + if(CONFIG_UEDHOC_DEBUG) + zephyr_library_compile_definitions(DEBUG_PRINT) + endif() + + zephyr_library_sources( + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/associated_data_encode.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/bstr_encode_decode.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/cert.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/ciphertext.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/edhoc_cose.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/edhoc_exporter.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/edhoc_method_type.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/hkdf_info.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/initiator.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/int_encode_decode.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/okm.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/plaintext_decode.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/plaintext_encode.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/prk.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/responder.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/retrieve_cred.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/runtime_context.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/signature_or_mac_msg.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/suites.c + ${UOSCORE_UEDHOC_SRC_DIR}/edhoc/th.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_decode_bstr_type.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_decode_cert.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_decode_id_cred_x.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_decode_int_type.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_decode_message_1.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_decode_message_2.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_decode_message_3.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_decode_plaintext2.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_decode_plaintext3.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_encode_bstr_type.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_encode_data_2.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_encode_enc_structure.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_encode_id_cred_x.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_encode_info.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_encode_int_type.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_encode_message_1.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_encode_message_2.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_encode_message_3.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_encode_message_error.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_encode_sig_structure.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_encode_th2.c + ) + + zephyr_library_link_libraries(mbedTLS) + + endif() # CONFIG_UEDHOC + +endif() # CONFIG_UOSCORE OR CONFIG_UEDHOC diff --git a/zephyr/Kconfig b/zephyr/Kconfig new file mode 100644 index 0000000..7662495 --- /dev/null +++ b/zephyr/Kconfig @@ -0,0 +1,58 @@ +# Copyright (c) 2022 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +menuconfig UOSCORE + bool "UOSCORE library" + depends on ZCBOR + depends on ZCBOR_CANONICAL + select UOSCORE_UEDHOC_CRYPTO_COMMON + + help + This option enables the UOSCORE library. + +if UOSCORE + +config UOSCORE_DEBUG + bool "Debug logs in the uoscore library" + +endif # UOSCORE + +menuconfig UEDHOC + bool "UEDHOC library" + depends on ZCBOR + depends on ZCBOR_CANONICAL + select UOSCORE_UEDHOC_CRYPTO_COMMON + help + This option enables the UEDHOC library. + +if UEDHOC + +config UEDHOC_DEBUG + bool "Debug logs in the uedhoc library" + +endif # UEDHOC + +if UOSCORE || UEDHOC + +config UOSCORE_UEDHOC_CRYPTO_COMMON + bool + select PSA_CRYPTO + select PSA_WANT_ALG_ECDH + select PSA_WANT_ALG_ECDSA + select PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT + select PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT + select PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE + select PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY + select PSA_WANT_ECC_SECP_R1_256 + select PSA_WANT_KEY_TYPE_AES + select PSA_WANT_ALG_CCM + select PSA_WANT_KEY_TYPE_HMAC + select PSA_WANT_ALG_HMAC + select PSA_WANT_ALG_SHA_256 + # On TF-M platforms the PSA_WANT_xxx above do not enable the legacy + # MBEDTLS_ECP_C build symbol which is required to enable the + # mbedtls_pk_ec() function used in uOSCORE/uEDHOC. + select MBEDTLS_ECP_C if BUILD_WITH_TFM + select MBEDTLS_ECP_DP_SECP256R1_ENABLED if BUILD_WITH_TFM + +endif # UOSCORE || UEDHOC diff --git a/zephyr/module.yml b/zephyr/module.yml index 01b7244..6cedab6 100644 --- a/zephyr/module.yml +++ b/zephyr/module.yml @@ -1,4 +1,4 @@ name: uoscore-uedhoc build: - cmake-ext: True - kconfig-ext: True + cmake: zephyr + kconfig: zephyr/Kconfig \ No newline at end of file diff --git a/zephyr/tests/uoscore/CMakeLists.txt b/zephyr/tests/uoscore/CMakeLists.txt new file mode 100644 index 0000000..9a97348 --- /dev/null +++ b/zephyr/tests/uoscore/CMakeLists.txt @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(uoscore) + +FILE(GLOB + app_sources + src/*.c + src/oscore_testvector_tests/*.c +) + +target_sources(app PRIVATE ${app_sources}) +target_include_directories(app PRIVATE + src/oscore_testvector_tests +) diff --git a/zephyr/tests/uoscore/prj.conf b/zephyr/tests/uoscore/prj.conf new file mode 100644 index 0000000..e46f0dc --- /dev/null +++ b/zephyr/tests/uoscore/prj.conf @@ -0,0 +1,14 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_STACK_SIZE=16384 +CONFIG_MAIN_STACK_SIZE=4096 + +CONFIG_ENTROPY_GENERATOR=y +CONFIG_TEST_RANDOM_GENERATOR=y + +CONFIG_ZCBOR=y +CONFIG_ZCBOR_CANONICAL=y +CONFIG_UOSCORE=y + +CONFIG_MBEDTLS=y +CONFIG_MBEDTLS_ENABLE_HEAP=y +CONFIG_MBEDTLS_HEAP_SIZE=2048 diff --git a/zephyr/tests/uoscore/src/main.c b/zephyr/tests/uoscore/src/main.c new file mode 100644 index 0000000..bd32232 --- /dev/null +++ b/zephyr/tests/uoscore/src/main.c @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2021 Fraunhofer AISEC. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* OSCORE testvector tests */ +ZTEST_SUITE(oscore_tests, NULL, NULL, NULL, NULL, NULL); diff --git a/zephyr/tests/uoscore/src/oscore_testvector_tests/oscore_test_vectors.h b/zephyr/tests/uoscore/src/oscore_testvector_tests/oscore_test_vectors.h new file mode 100644 index 0000000..84773f6 --- /dev/null +++ b/zephyr/tests/uoscore/src/oscore_testvector_tests/oscore_test_vectors.h @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2021 Fraunhofer AISEC. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/** + * Test 1: + * - Client Key derivation with master salt see RFC8613 Appendix C.1.1 + * - Generating OSCORE request with key form C.1.1 see RFC8613 Appendix C.4 + */ + +/* Test vector C1.1: Key derivation with Master Salt */ +const uint8_t T1__MASTER_SECRET[16] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10 }; +uint8_t T1__MASTER_SECRET_LEN = sizeof(T1__MASTER_SECRET); + +const uint8_t *T1__SENDER_ID; +uint8_t T1__SENDER_ID_LEN; + +const uint8_t T1__RECIPIENT_ID[1] = { 0x01 }; +uint8_t T1__RECIPIENT_ID_LEN = sizeof(T1__RECIPIENT_ID); + +const uint8_t T1__MASTER_SALT[8] = { 0x9e, 0x7c, 0xa9, 0x22, + 0x23, 0x78, 0x63, 0x40 }; +uint8_t T1__MASTER_SALT_LEN = sizeof(T1__MASTER_SALT); + +const uint8_t *T1__ID_CONTEXT; +uint8_t T1__ID_CONTEXT_LEN; + +/* Test vector C4: Generating a OSCORE Packet with key material form test vector + * C.1 + */ +const uint8_t T1__COAP_REQ[] = { 0x44, 0x01, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74, + 0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, + 0x73, 0x74, 0x83, 0x74, 0x76, 0x31 }; +uint16_t T1__COAP_REQ_LEN = sizeof(T1__COAP_REQ); + +/* Expected result */ +const uint8_t T1__SENDER_KEY[] = { 0xf0, 0x91, 0x0e, 0xd7, 0x29, 0x5e, + 0x6a, 0xd4, 0xb5, 0x4f, 0xc7, 0x93, + 0x15, 0x43, 0x02, 0xff }; +uint8_t T1__SENDER_KEY_LEN = sizeof(T1__SENDER_KEY); + +const uint8_t T1__RECIPIENT_KEY[] = { 0xff, 0xb1, 0x4e, 0x09, 0x3c, 0x94, + 0xc9, 0xca, 0xc9, 0x47, 0x16, 0x48, + 0xb4, 0xf9, 0x87, 0x10 }; +uint8_t T1__RECIPIENT_KEY_LEN = sizeof(T1__RECIPIENT_KEY); + +const uint8_t T1__COMMON_IV[] = { 0x46, 0x22, 0xd4, 0xdd, 0x6d, 0x94, 0x41, + 0x68, 0xee, 0xfb, 0x54, 0x98, 0x7c }; +uint8_t T1__COMMON_IV_LEN = sizeof(T1__COMMON_IV); + +const uint8_t T1__OSCORE_REQ[] = { 0x44, 0x02, 0x5d, 0x1f, 0x00, 0x00, 0x39, + 0x74, 0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x68, 0x6f, 0x73, 0x74, 0x62, 0x09, 0x14, + 0xff, 0x61, 0x2f, 0x10, 0x92, 0xf1, 0x77, + 0x6f, 0x1c, 0x16, 0x68, 0xb3, 0x82, 0x5e }; +uint8_t T1__OSCORE_REQ_LEN = sizeof(T1__OSCORE_REQ); + +/** + * Test 2: + * - Server Key derivation with master salt see RFC8613 Appendix C.1.2 + * - Generating OSCORE response with key form C.1.2 see RFC8613 Appendix C.7 + */ +const uint8_t T2__MASTER_SECRET[16] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10 }; +uint8_t T2__MASTER_SECRET_LEN = sizeof(T2__MASTER_SECRET); + +uint8_t T2__SENDER_ID[] = { 0x01 }; +uint8_t T2__SENDER_ID_LEN = sizeof(T2__SENDER_ID); + +uint8_t *T2__RECIPIENT_ID; +uint8_t T2__RECIPIENT_ID_LEN; + +const uint8_t T2__MASTER_SALT[8] = { 0x9e, 0x7c, 0xa9, 0x22, + 0x23, 0x78, 0x63, 0x40 }; +uint8_t T2__MASTER_SALT_LEN = sizeof(T2__MASTER_SALT); + +uint8_t *T2__ID_CONTEXT; +uint8_t T2__ID_CONTEXT_LEN; + +/* The OSCORE message created in C4 (35 Byte). Constructed from a CoAP request + * of length 22. This request contains no payload. The request contains only + * Uri-host (locahost) and Uri-path option (tv1). In the OSCORE packet Uri-host + * option is transferred as plain normal option, The Uri-path is contained in + * the ciphertext. + */ +const uint8_t T2__OSCORE_REQ[] = { 0x44, 0x02, 0x5d, 0x1f, 0x00, 0x00, 0x39, + 0x74, 0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x68, 0x6f, 0x73, 0x74, 0x62, 0x09, 0x14, + 0xff, 0x61, 0x2f, 0x10, 0x92, 0xf1, 0x77, + 0x6f, 0x1c, 0x16, 0x68, 0xb3, 0x82, 0x5e }; +uint8_t T2__OSCORE_REQ_LEN = sizeof(T2__OSCORE_REQ); + +/* Unprotected CoAP response (21 bytes) */ +/* Contains the payload "Hello World!" */ +const uint8_t T2__COAP_RESPONSE[] = { + 0x64, 0x45, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74, 0xff, 0x48, 0x65, + 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21 +}; +uint8_t T2__COAP_RESPONSE_LEN = sizeof(T2__COAP_RESPONSE); + +/* Expected result */ +/* the reconstructed coap request see Appendix C4 */ +const uint8_t T2__COAP_REQ[] = { 0x44, 0x01, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74, + 0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, + 0x73, 0x74, 0x83, 0x74, 0x76, 0x31 }; +uint8_t T2__COAP_REQ_LEN = sizeof(T2__COAP_REQ); + +const uint8_t T2__OSCORE_RESP[] = { 0x64, 0x44, 0x5D, 0x1F, 0x00, 0x00, 0x39, + 0x74, 0x90, 0xFF, 0xDB, 0xAA, 0xD1, 0xE9, + 0xA7, 0xE7, 0xB2, 0xA8, 0x13, 0xD3, 0xC3, + 0x15, 0x24, 0x37, 0x83, 0x03, 0xCD, 0xAF, + 0xAE, 0x11, 0x91, 0x06 }; +uint8_t T2__OSCORE_RESP_LEN = sizeof(T2__OSCORE_RESP); + +/** + * Test 3: + * - Client Key derivation without master salt see RFC8613 Appendix C.2.1 + * - Generating OSCORE request with key form C.2.1 see RFC8613 Appendix C.5 + */ +/* Test vector C2.1: Key derivation without Master Salt */ +const uint8_t T3__MASTER_SECRET[16] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10 }; +uint8_t T3__MASTER_SECRET_LEN = sizeof(T3__MASTER_SECRET); + +const uint8_t T3__SENDER_ID[1] = { 0x00 }; +uint8_t T3__SENDER_ID_LEN = sizeof(T3__SENDER_ID); + +const uint8_t T3__RECIPIENT_ID[1] = { 0x01 }; +uint8_t T3__RECIPIENT_ID_LEN = sizeof(T3__RECIPIENT_ID); + +const uint8_t *T3__MASTER_SALT; +uint8_t T3__MASTER_SALT_LEN; + +const uint8_t *T3__ID_CONTEXT; +uint8_t T3__ID_CONTEXT_LEN; + +/* Test vector C5: Generating a OSCORE Packet with key material form test vector + * C.2.1 + */ +const uint8_t T3__COAP_REQ[] = { 0x44, 0x01, 0x71, 0xc3, 0x00, 0x00, 0xb9, 0x32, + 0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, + 0x73, 0x74, 0x83, 0x74, 0x76, 0x31 }; +uint16_t T3__COAP_REQ_LEN = sizeof(T3__COAP_REQ); + +/* expected result */ +const uint8_t T3__OSCORE_REQ[] = { + 0x44, 0x02, 0x71, 0xc3, 0x00, 0x00, 0xb9, 0x32, 0x39, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x63, 0x09, 0x14, 0x00, 0xff, 0x4e, + 0xd3, 0x39, 0xa5, 0xa3, 0x79, 0xb0, 0xb8, 0xbc, 0x73, 0x1f, 0xff, 0xb0 +}; +uint8_t T3__OSCORE_REQ_LEN = sizeof(T3__OSCORE_REQ); + +/** + * Test 4: + * - Server Key derivation without master salt see RFC8613 Appendix C.2.2 + */ +/*Test vector C2.2: Key derivation without Master Salt*/ +const uint8_t T4__MASTER_SECRET[16] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10 }; +uint8_t T4__MASTER_SECRET_LEN = sizeof(T4__MASTER_SECRET); + +const uint8_t T4__SENDER_ID[1] = { 0x01 }; +uint8_t T4__SENDER_ID_LEN = sizeof(T4__SENDER_ID); + +const uint8_t T4__RECIPIENT_ID[1] = { 0x00 }; +uint8_t T4__RECIPIENT_ID_LEN = sizeof(T4__RECIPIENT_ID); + +const uint8_t *T4__MASTER_SALT; +uint8_t T4__MASTER_SALT_LEN; + +const uint8_t *T4__ID_CONTEXT; +uint8_t T4__ID_CONTEXT_LEN; + +/* expected result */ +const uint8_t T4__SENDER_KEY[] = { 0xe5, 0x7b, 0x56, 0x35, 0x81, 0x51, + 0x77, 0xcd, 0x67, 0x9a, 0xb4, 0xbc, + 0xec, 0x9d, 0x7d, 0xda }; +uint8_t T4__SENDER_KEY_LEN = sizeof(T4__SENDER_KEY); + +const uint8_t T4__RECIPIENT_KEY[] = { 0x32, 0x1b, 0x26, 0x94, 0x32, 0x53, + 0xc7, 0xff, 0xb6, 0x00, 0x3b, 0x0b, + 0x64, 0xd7, 0x40, 0x41 }; +uint8_t T4__RECIPIENT_KEY_LEN = sizeof(T4__RECIPIENT_KEY); + +const uint8_t T4__COMMON_IV[] = { 0xbe, 0x35, 0xae, 0x29, 0x7d, 0x2d, 0xac, + 0xe9, 0x10, 0xc5, 0x2e, 0x99, 0xf9 }; +uint8_t T4__COMMON_IV_LEN = sizeof(T4__COMMON_IV); + +/** + * Test 5 : + * - Client Key derivation with ID Context see Appendix 3.1 + * - OSCORE request generation see Appendix C6 + */ +/* Test vector C3.1: Key derivation with ID Context */ +const uint8_t T5__MASTER_SECRET[16] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10 }; +uint8_t T5__MASTER_SECRET_LEN = sizeof(T5__MASTER_SECRET); + +const uint8_t *T5__SENDER_ID; +uint8_t T5__SENDER_ID_LEN; + +const uint8_t T5__RECIPIENT_ID[1] = { 0x01 }; +uint8_t T5__RECIPIENT_ID_LEN = sizeof(T5__RECIPIENT_ID); + +const uint8_t T5__MASTER_SALT[8] = { 0x9e, 0x7c, 0xa9, 0x22, + 0x23, 0x78, 0x63, 0x40 }; +uint8_t T5__MASTER_SALT_LEN = sizeof(T5__MASTER_SALT); + +const uint8_t T5__ID_CONTEXT[8] = { 0x37, 0xcb, 0xf3, 0x21, + 0x00, 0x17, 0xa2, 0xd3 }; +uint8_t T5__ID_CONTEXT_LEN = sizeof(T5__ID_CONTEXT); + +/* Test vector C6: Generating a OSCORE Packet with key material form test vector + * C.2.1 + */ +const uint8_t T5__COAP_REQ[] = { 0x44, 0x01, 0x2f, 0x8e, 0xef, 0x9b, 0xbf, 0x7a, + 0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, + 0x73, 0x74, 0x83, 0x74, 0x76, 0x31 }; +uint16_t T5__COAP_REQ_LEN = sizeof(T5__COAP_REQ); + +/* Expected result */ +const uint8_t T5__OSCORE_REQ[] = { + 0x44, 0x02, 0x2f, 0x8e, 0xef, 0x9b, 0xbf, 0x7a, 0x39, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x6b, 0x19, 0x14, 0x08, + 0x37, 0xcb, 0xf3, 0x21, 0x00, 0x17, 0xa2, 0xd3, 0xff, 0x72, 0xcd, + 0x72, 0x73, 0xfd, 0x33, 0x1a, 0xc4, 0x5c, 0xff, 0xbe, 0x55, 0xc3 +}; +uint8_t T5__OSCORE_REQ_LEN = sizeof(T5__OSCORE_REQ); + +/** + * Test 6: + * - Server Key derivation with ID context see RFC8613 Appendix C.3.2 + */ +const uint8_t T6__MASTER_SECRET[16] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10 }; +uint8_t T6__MASTER_SECRET_LEN = sizeof(T6__MASTER_SECRET); + +const uint8_t T6__SENDER_ID[1] = { 0x01 }; +uint8_t T6__SENDER_ID_LEN = sizeof(T6__SENDER_ID); + +const uint8_t *T6__RECIPIENT_ID; +uint8_t T6__RECIPIENT_ID_LEN; + +const uint8_t T6__MASTER_SALT[8] = { 0x9e, 0x7c, 0xa9, 0x22, + 0x23, 0x78, 0x63, 0x40 }; +uint8_t T6__MASTER_SALT_LEN = sizeof(T5__MASTER_SALT); + +const uint8_t T6__ID_CONTEXT[8] = { 0x37, 0xcb, 0xf3, 0x21, + 0x00, 0x17, 0xa2, 0xd3 }; +uint8_t T6__ID_CONTEXT_LEN = sizeof(T5__ID_CONTEXT); + +/* expected result */ +const uint8_t T6__SENDER_KEY[] = { 0xe3, 0x9a, 0x0c, 0x7c, 0x77, 0xb4, + 0x3f, 0x03, 0xb4, 0xb3, 0x9a, 0xb9, + 0xa2, 0x68, 0x69, 0x9f }; +uint8_t T6__SENDER_KEY_LEN = sizeof(T6__SENDER_KEY); + +const uint8_t T6__RECIPIENT_KEY[] = { 0xaf, 0x2a, 0x13, 0x00, 0xa5, 0xe9, + 0x57, 0x88, 0xb3, 0x56, 0x33, 0x6e, + 0xee, 0xcd, 0x2b, 0x92 }; +uint8_t T6__RECIPIENT_KEY_LEN = sizeof(T6__RECIPIENT_KEY); + +const uint8_t T6__COMMON_IV[] = { 0x2c, 0xa5, 0x8f, 0xb8, 0x5f, 0xf1, 0xb8, + 0x1c, 0x0b, 0x71, 0x81, 0xb8, 0x5e }; +uint8_t T6__COMMON_IV_LEN = sizeof(T6__COMMON_IV); + +/** + * Test 7: + * - Server with partial IV see Appendix C8 + * - currently not supported + */ +const uint8_t T7__MASTER_SECRET[16] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10 }; +uint8_t T7__MASTER_SECRET_LEN = sizeof(T7__MASTER_SECRET); + +const uint8_t T7__SENDER_ID[] = { 0x01 }; +uint8_t T7__SENDER_ID_LEN = sizeof(T7__SENDER_ID); + +const uint8_t *T7__RECIPIENT_ID; +uint8_t T7__RECIPIENT_ID_LEN; + +const uint8_t T7__MASTER_SALT[8] = { 0x9e, 0x7c, 0xa9, 0x22, + 0x23, 0x78, 0x63, 0x40 }; +uint8_t T7__MASTER_SALT_LEN = sizeof(T7__MASTER_SALT); + +const uint8_t *T7__ID_CONTEXT; +uint8_t T7__ID_CONTEXT_LEN; + +/* Test vector C4: Generating a OSCORE Packet with key material form test vector + * C.1 + */ +/* the OSCORE message created in C4 */ +const uint8_t T7__OSCORE_REQ[] = { 0x44, 0x02, 0x5d, 0x1f, 0x00, 0x00, 0x39, + 0x74, 0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x68, 0x6f, 0x73, 0x74, 0x62, 0x09, 0x14, + 0xff, 0x61, 0x2f, 0x10, 0x92, 0xf1, 0x77, + 0x6f, 0x1c, 0x16, 0x68, 0xb3, 0x82, 0x5e }; +uint8_t T7__OSCORE_REQ_LEN = sizeof(T7__OSCORE_REQ); + +/* unprotected CoAP response */ +const uint8_t T7__COAP_RESPONSE[] = { + 0x64, 0x45, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74, 0xff, 0x48, 0x65, + 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21 +}; +uint8_t T7__COAP_RESPONSE_LEN = sizeof(T7__COAP_RESPONSE); + +/* expected result */ +const uint8_t T7__OSCORE_RES[] = { 0x64, 0x44, 0x5d, 0x1f, 0x00, 0x00, 0x39, + 0x74, 0x92, 0x01, 0x00, 0xff, 0x4d, 0x4c, + 0x13, 0x66, 0x93, 0x84, 0xb6, 0x73, 0x54, + 0xb2, 0xb6, 0x17, 0x5f, 0xf4, 0xb8, 0x65, + 0x8c, 0x66, 0x6a, 0x6c, 0xf8, 0x8e }; +uint8_t T7__OSCORE_RES_LEN = sizeof(T7__OSCORE_RES); + +/** + * Test 8: + * - Simple ACK packet should not be encrypted and result should be the same as + * input buffer (see RFC8613 Section 4.2) + */ +const uint8_t T8__MASTER_SECRET[16] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10 }; +uint8_t T8__MASTER_SECRET_LEN = sizeof(T2__MASTER_SECRET); + +const uint8_t T8__SENDER_ID[] = { 0x01 }; +uint8_t T8__SENDER_ID_LEN = sizeof(T2__SENDER_ID); + +const uint8_t T8__MASTER_SALT[8] = { 0x9e, 0x7c, 0xa9, 0x22, + 0x23, 0x78, 0x63, 0x40 }; +uint8_t T8__MASTER_SALT_LEN = sizeof(T2__MASTER_SALT); + +/* Simple ACK message (code 0=EMPTY, type 2=ACK, no payload). */ +const uint8_t T8__COAP_ACK[] = { 0x60, 0x00, 0x45, 0x69 }; +uint8_t T8__COAP_ACK_LEN = sizeof(T8__COAP_ACK); diff --git a/zephyr/tests/uoscore/src/oscore_testvector_tests/oscore_tests.c b/zephyr/tests/uoscore/src/oscore_testvector_tests/oscore_tests.c new file mode 100644 index 0000000..be6e2dd --- /dev/null +++ b/zephyr/tests/uoscore/src/oscore_testvector_tests/oscore_tests.c @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2021 Fraunhofer AISEC. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include "oscore_test_vectors.h" + +/** + * Test 1: + * - Client Key derivation with master salt see RFC8613 Appendix C.1.1 + * - Generating OSCORE request with key form C.1.1 see RFC8613 Appendix C.4 + */ +ZTEST(oscore_tests, test_oscore_client_test1) +{ + enum err r; + struct context c_client; + struct oscore_init_params params = { + .master_secret.ptr = (uint8_t *)T1__MASTER_SECRET, + .master_secret.len = T1__MASTER_SECRET_LEN, + .sender_id.ptr = (uint8_t *)T1__SENDER_ID, + .sender_id.len = T1__SENDER_ID_LEN, + .recipient_id.ptr = (uint8_t *)T1__RECIPIENT_ID, + .recipient_id.len = T1__RECIPIENT_ID_LEN, + .master_salt.ptr = (uint8_t *)T1__MASTER_SALT, + .master_salt.len = T1__MASTER_SALT_LEN, + .id_context.ptr = (uint8_t *)T1__ID_CONTEXT, + .id_context.len = T1__ID_CONTEXT_LEN, + .aead_alg = OSCORE_AES_CCM_16_64_128, + .hkdf = OSCORE_SHA_256, + .fresh_master_secret_salt = true, + }; + + r = oscore_context_init(¶ms, &c_client); + + zassert_equal(r, ok, "Error in oscore_context_init"); + + /* + * required only for the test vector. + * during normal operation the sender sequence number is + * increased automatically after every sending + */ + c_client.sc.ssn = 20; + + uint8_t buf_oscore[256]; + uint32_t buf_oscore_len = sizeof(buf_oscore); + + r = coap2oscore((uint8_t *)T1__COAP_REQ, T1__COAP_REQ_LEN, + (uint8_t *)&buf_oscore, &buf_oscore_len, &c_client); + zassert_equal(r, ok, "Error in coap2oscore!"); + + zassert_mem_equal__(c_client.sc.sender_key.ptr, T1__SENDER_KEY, + c_client.sc.sender_key.len, + "T1 sender key derivation failed"); + + zassert_mem_equal__(c_client.rc.recipient_key.ptr, T1__RECIPIENT_KEY, + c_client.rc.recipient_key.len, + "T1 recipient key derivation failed"); + + zassert_mem_equal__(c_client.cc.common_iv.ptr, T1__COMMON_IV, + c_client.cc.common_iv.len, + "T1 common IV derivation failed"); + + zassert_mem_equal__(&buf_oscore, T1__OSCORE_REQ, T1__OSCORE_REQ_LEN, + "coap2oscore failed"); +} + +/** + * Test 3: + * - Client Key derivation without master salt see RFC8613 Appendix C.2.1 + * - Generating OSCORE request with key form C.2.1 see RFC8613 Appendix C.5 + */ +ZTEST(oscore_tests, test_oscore_client_test3) +{ + enum err r; + struct context c_client; + struct oscore_init_params params = { + .master_secret.ptr = (uint8_t *)T3__MASTER_SECRET, + .master_secret.len = T3__MASTER_SECRET_LEN, + .sender_id.ptr = (uint8_t *)T3__SENDER_ID, + .sender_id.len = T3__SENDER_ID_LEN, + .recipient_id.ptr = (uint8_t *)T3__RECIPIENT_ID, + .recipient_id.len = T3__RECIPIENT_ID_LEN, + .master_salt.ptr = (uint8_t *)T3__MASTER_SALT, + .master_salt.len = T3__MASTER_SALT_LEN, + .id_context.ptr = (uint8_t *)T3__ID_CONTEXT, + .id_context.len = T3__ID_CONTEXT_LEN, + .aead_alg = OSCORE_AES_CCM_16_64_128, + .hkdf = OSCORE_SHA_256, + .fresh_master_secret_salt = true, + }; + + r = oscore_context_init(¶ms, &c_client); + + zassert_equal(r, ok, "Error in oscore_context_init"); + + /* + * required only for the test vector. + * during normal operation the sender sequence number is + * increased automatically after every sending + */ + c_client.sc.ssn = 20; + + uint8_t buf_oscore[256]; + uint32_t buf_oscore_len = sizeof(buf_oscore); + + r = coap2oscore((uint8_t *)T3__COAP_REQ, T3__COAP_REQ_LEN, + (uint8_t *)&buf_oscore, &buf_oscore_len, &c_client); + + zassert_equal(r, ok, "Error in coap2oscore!"); + + zassert_mem_equal__(&buf_oscore, T3__OSCORE_REQ, T3__OSCORE_REQ_LEN, + "coap2oscore failed"); +} + +/** + * Test 5 : + * - Client Key derivation with ID Context see Appendix 3.1 + * - OSCORE request generation see Appendix C6 + */ +ZTEST(oscore_tests, test_oscore_client_test5) +{ + enum err r; + struct context c_client; + struct oscore_init_params params = { + .master_secret.ptr = (uint8_t *)T5__MASTER_SECRET, + .master_secret.len = T5__MASTER_SECRET_LEN, + .sender_id.ptr = (uint8_t *)T5__SENDER_ID, + .sender_id.len = T5__SENDER_ID_LEN, + .recipient_id.ptr = (uint8_t *)T5__RECIPIENT_ID, + .recipient_id.len = T5__RECIPIENT_ID_LEN, + .master_salt.ptr = (uint8_t *)T5__MASTER_SALT, + .master_salt.len = T5__MASTER_SALT_LEN, + .id_context.ptr = (uint8_t *)T5__ID_CONTEXT, + .id_context.len = T5__ID_CONTEXT_LEN, + .aead_alg = OSCORE_AES_CCM_16_64_128, + .hkdf = OSCORE_SHA_256, + .fresh_master_secret_salt = true, + }; + + r = oscore_context_init(¶ms, &c_client); + + zassert_equal(r, ok, "Error in oscore_context_init"); + + /* + * required only for the test vector. + * during normal operation the sender sequence number is + * increased automatically after every sending + */ + c_client.sc.ssn = 20; + + uint8_t buf_oscore[256]; + uint32_t buf_oscore_len = sizeof(buf_oscore); + + r = coap2oscore((uint8_t *)T5__COAP_REQ, T5__COAP_REQ_LEN, + (uint8_t *)&buf_oscore, &buf_oscore_len, &c_client); + + zassert_equal(r, ok, "Error in coap2oscore!"); + + zassert_mem_equal__(&buf_oscore, T5__OSCORE_REQ, buf_oscore_len, + "coap2oscore failed"); +} + +/** + * Test 2: + * - Server Key derivation with master salt see RFC8613 Appendix C.1.2 + * - Generating OSCORE response with key form C.1.2 see RFC8613 Appendix C.7 + */ +ZTEST(oscore_tests, test_oscore_server_test2) +{ + enum err r; + struct context c_server; + struct oscore_init_params params_server = { + .master_secret.ptr = (uint8_t *)T2__MASTER_SECRET, + .master_secret.len = T2__MASTER_SECRET_LEN, + .sender_id.ptr = (uint8_t *)T2__SENDER_ID, + .sender_id.len = T2__SENDER_ID_LEN, + .recipient_id.ptr = (uint8_t *)T2__RECIPIENT_ID, + .recipient_id.len = T2__RECIPIENT_ID_LEN, + .master_salt.ptr = (uint8_t *)T2__MASTER_SALT, + .master_salt.len = T2__MASTER_SALT_LEN, + .id_context.ptr = (uint8_t *)T2__ID_CONTEXT, + .id_context.len = T2__ID_CONTEXT_LEN, + .aead_alg = OSCORE_AES_CCM_16_64_128, + .hkdf = OSCORE_SHA_256, + .fresh_master_secret_salt = true, + }; + + r = oscore_context_init(¶ms_server, &c_server); + + zassert_equal(r, ok, "Error in oscore_context_init"); + + /* Test decrypting of an incoming request */ + uint8_t buf_coap[256]; + uint32_t buf_coap_len = sizeof(buf_coap); + + r = oscore2coap((uint8_t *)T2__OSCORE_REQ, T2__OSCORE_REQ_LEN, buf_coap, + &buf_coap_len, &c_server); + + zassert_equal(r, ok, "Error in oscore2coap!"); + zassert_mem_equal__(&buf_coap, T2__COAP_REQ, buf_coap_len, + "oscore2coap failed"); + + /* Test generating an encrypted response, see Appendix C7 */ + uint8_t buf_oscore[256]; + uint32_t buf_oscore_len = sizeof(buf_oscore); + + r = coap2oscore((uint8_t *)T2__COAP_RESPONSE, T2__COAP_RESPONSE_LEN, + (uint8_t *)&buf_oscore, &buf_oscore_len, &c_server); + + zassert_equal(r, ok, "Error in coap2oscore"); + + zassert_mem_equal__(&buf_oscore, T2__OSCORE_RESP, buf_oscore_len, + "coap2oscore failed"); +} + +ZTEST(oscore_tests, test_oscore_server_test4) +{ + enum err r; + struct context c_server; + struct oscore_init_params params_server = { + .master_secret.ptr = (uint8_t *)T4__MASTER_SECRET, + .master_secret.len = T4__MASTER_SECRET_LEN, + .sender_id.ptr = (uint8_t *)T4__SENDER_ID, + .sender_id.len = T4__SENDER_ID_LEN, + .recipient_id.ptr = (uint8_t *)T4__RECIPIENT_ID, + .recipient_id.len = T4__RECIPIENT_ID_LEN, + .master_salt.ptr = (uint8_t *)T4__MASTER_SALT, + .master_salt.len = T4__MASTER_SALT_LEN, + .id_context.ptr = (uint8_t *)T4__ID_CONTEXT, + .id_context.len = T4__ID_CONTEXT_LEN, + .aead_alg = OSCORE_AES_CCM_16_64_128, + .hkdf = OSCORE_SHA_256, + .fresh_master_secret_salt = true, + }; + + r = oscore_context_init(¶ms_server, &c_server); + + zassert_equal(r, ok, "Error in oscore_context_init"); + + zassert_mem_equal__(c_server.sc.sender_key.ptr, T4__SENDER_KEY, + c_server.sc.sender_key.len, + "T4 sender key derivation failed"); + + zassert_mem_equal__(c_server.rc.recipient_key.ptr, T4__RECIPIENT_KEY, + c_server.rc.recipient_key.len, + "T4 recipient key derivation failed"); + + zassert_mem_equal__(c_server.cc.common_iv.ptr, T4__COMMON_IV, + c_server.cc.common_iv.len, + "T4 common IV derivation failed"); +} + +/** + * Test 6: + * - Server Key derivation with ID context see RFC8613 Appendix C.3.2 + */ +ZTEST(oscore_tests, test_oscore_server_test6) +{ + enum err r; + struct context c_server; + struct oscore_init_params params_server = { + .master_secret.ptr = (uint8_t *)T6__MASTER_SECRET, + .master_secret.len = T6__MASTER_SECRET_LEN, + .sender_id.ptr = (uint8_t *)T6__SENDER_ID, + .sender_id.len = T6__SENDER_ID_LEN, + .recipient_id.ptr = (uint8_t *)T6__RECIPIENT_ID, + .recipient_id.len = T6__RECIPIENT_ID_LEN, + .master_salt.ptr = (uint8_t *)T6__MASTER_SALT, + .master_salt.len = T6__MASTER_SALT_LEN, + .id_context.ptr = (uint8_t *)T6__ID_CONTEXT, + .id_context.len = T6__ID_CONTEXT_LEN, + .aead_alg = OSCORE_AES_CCM_16_64_128, + .hkdf = OSCORE_SHA_256, + .fresh_master_secret_salt = true, + }; + + r = oscore_context_init(¶ms_server, &c_server); + + zassert_equal(r, ok, "Error in oscore_context_init"); + + zassert_mem_equal__(c_server.sc.sender_key.ptr, T6__SENDER_KEY, + c_server.sc.sender_key.len, + "T6 sender key derivation failed"); + + zassert_mem_equal__(c_server.rc.recipient_key.ptr, T6__RECIPIENT_KEY, + c_server.rc.recipient_key.len, + "T6 recipient key derivation failed"); + + zassert_mem_equal__(c_server.cc.common_iv.ptr, T6__COMMON_IV, + c_server.cc.common_iv.len, + "T6 common IV derivation failed"); +} + +/** + * Test 8: + * - Simple ACK packet should not be encrypted and result should be the same as + * input buffer (see RFC8613 Section 4.2) + */ +ZTEST(oscore_tests, test_oscore_misc_test8) +{ + enum err r; + struct context c; + struct oscore_init_params params = { + .master_secret.ptr = (uint8_t *)T7__MASTER_SECRET, + .master_secret.len = T7__MASTER_SECRET_LEN, + .sender_id.ptr = (uint8_t *)T7__SENDER_ID, + .sender_id.len = T7__SENDER_ID_LEN, + .recipient_id.ptr = (uint8_t *)T7__RECIPIENT_ID, + .recipient_id.len = T7__RECIPIENT_ID_LEN, + .master_salt.ptr = (uint8_t *)T7__MASTER_SALT, + .master_salt.len = T7__MASTER_SALT_LEN, + .id_context.ptr = (uint8_t *)T7__ID_CONTEXT, + .id_context.len = T7__ID_CONTEXT_LEN, + .aead_alg = OSCORE_AES_CCM_16_64_128, + .hkdf = OSCORE_SHA_256, + .fresh_master_secret_salt = true, + }; + + r = oscore_context_init(¶ms, &c); + + zassert_equal(r, ok, "Error in oscore_context_init"); + + /* Test if encrypting simple ACK message results in valid unencrypted + * message, see Section 4.2 + */ + uint8_t buf_oscore[256]; + uint32_t buf_oscore_len = sizeof(buf_oscore); + + r = coap2oscore((uint8_t *)T8__COAP_ACK, T8__COAP_ACK_LEN, + (uint8_t *)&buf_oscore, &buf_oscore_len, &c); + + zassert_equal(r, ok, "Error in coap2oscore"); + + zassert_mem_equal__(&buf_oscore, T8__COAP_ACK, T8__COAP_ACK_LEN, + "coap2oscore failed"); + + zassert_equal(buf_oscore_len, T8__COAP_ACK_LEN, "coap2oscore failed"); +} diff --git a/zephyr/tests/uoscore/testcase.yaml b/zephyr/tests/uoscore/testcase.yaml new file mode 100644 index 0000000..686fe05 --- /dev/null +++ b/zephyr/tests/uoscore/testcase.yaml @@ -0,0 +1,12 @@ +tests: + libraries.uoscore: + min_flash: 240 + modules: + - uoscore-uedhoc + tags: + - net + - crypto + - uoscore + - uoscore-uedhoc + integration_platforms: + - qemu_x86