From e772e20f0e3e0a08d5a58ff0240c50a1fe51e5cc Mon Sep 17 00:00:00 2001 From: Krzysztof Taborowski Date: Fri, 30 Aug 2024 11:08:32 +0200 Subject: [PATCH] pal: new mfg data processing flow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [KRKNWK-18440] Signed-off-by: Krzysztof Taborowski config: move mfg configs to kconfig [KRKNWK-18440] Signed-off-by: Krzysztof Taborowski pal: fix mfg module for sample tbd Signed-off-by: Krzysztof Taborowski pal: fix dut build tbd Signed-off-by: Krzysztof Taborowski tlv: fix flash write add test to parser Signed-off-by: Robert Gałat mfg: fix on_dev_cert on_dev_cert use tlv to store mfg Signed-off-by: Robert Gałat pal: add description review Signed-off-by: Krzysztof Taborowski pal: fix minor name issues review Signed-off-by: Krzysztof Taborowski pal: fix version check in mfg fix condition Signed-off-by: Krzysztof Taborowski tests: fix partition manager issues in tests rerevert - to be squashed Signed-off-by: Krzysztof Taborowski tests: fix pal validation tests psa storage isn't properly initlized in this test so it will fail on deinitlizaing Signed-off-by: Krzysztof Taborowski mfg: review mfg_storage finding fix fix findings Signed-off-by: Robert Gałat samples: add test config with no secure key storage [KRKNWK-19108] Signed-off-by: Krzysztof Taborowski pal: fix version check fix typo Signed-off-by: Krzysztof Taborowski pal: refactor mfg version get review Signed-off-by: Krzysztof Taborowski --- Kconfig | 24 +- Kconfig.dependencies | 21 +- samples/sid_end_device/sample.yaml | 7 + samples/sid_end_device/src/cli/app_dut.c | 2 +- samples/sid_end_device/src/sidewalk_events.c | 4 +- .../common/sid_on_dev_cert/sid_on_dev_cert.c | 22 +- .../sal/sid_pal}/include/app_mfg_config.h | 2 +- subsys/sal/sid_pal/include/sid_crypto_keys.h | 2 + .../sal/sid_pal/include/sid_mfg_hex_parsers.h | 43 + subsys/sal/sid_pal/src/CMakeLists.txt | 4 +- subsys/sal/sid_pal/src/sid_mfg_hex_v7.c | 174 ++++ subsys/sal/sid_pal/src/sid_mfg_hex_v8.c | 145 ++++ subsys/sal/sid_pal/src/sid_mfg_storage.c | 752 +++++------------- .../sid_pal/src/sid_mfg_storage_deprecated.c | 699 ++++++++++++++++ tests/functional/mfg_storage/Kconfig | 2 +- tests/functional/mfg_storage/testcase.yaml | 12 + tests/manual/ble/Kconfig | 3 + tests/manual/ble/sysbuild.conf | 2 +- tests/manual/log/Kconfig | 3 + tests/manual/log/sysbuild.conf | 2 +- tests/unit_tests/mfg_parsers/CMakeLists.txt | 33 + tests/unit_tests/mfg_parsers/Kconfig | 18 + .../nrf54l15pdk_nrf54l15_cpuapp.overlay | 11 + .../mfg_parsers/mocks/sid_crypto_keys.h | 100 +++ .../mfg_parsers}/pm_static.yml | 1 + .../pm_static_nrf54l15pdk_nrf54l15_cpuapp.yml | 5 + tests/unit_tests/mfg_parsers/prj.conf | 11 + tests/unit_tests/mfg_parsers/src/mfg_parser.c | 738 +++++++++++++++++ tests/unit_tests/mfg_parsers/src/mock_mem.c | 19 + .../mfg_parsers/src/sid_crypto_keys.c | 96 +++ tests/unit_tests/mfg_parsers/testcase.yaml | 23 + tests/unit_tests/pal_mfg_storage/Kconfig | 2 +- tests/unit_tests/tlv/src/ram_backend_tests.c | 186 ++++- tests/validation/crypto/Kconfig | 3 + tests/validation/crypto/sysbuild.conf | 2 +- tests/validation/storage_kv/Kconfig | 3 + tests/validation/storage_kv/prj.conf | 1 + tests/validation/storage_kv/src/main.c | 216 +++-- tests/validation/storage_kv/sysbuild.conf | 2 +- tests/validation/timer/Kconfig | 3 + tests/validation/timer/sysbuild.conf | 2 +- utils/include/tlv/tlv.h | 38 +- utils/include/tlv/tlv_storage_impl.h | 4 + utils/tlv/CMakeLists.txt | 4 +- utils/tlv/tlv.c | 81 +- utils/tlv/tlv_flash_storage_impl.c | 1 + 46 files changed, 2757 insertions(+), 771 deletions(-) rename {samples/sid_end_device => subsys/sal/sid_pal}/include/app_mfg_config.h (93%) create mode 100644 subsys/sal/sid_pal/include/sid_mfg_hex_parsers.h create mode 100644 subsys/sal/sid_pal/src/sid_mfg_hex_v7.c create mode 100644 subsys/sal/sid_pal/src/sid_mfg_hex_v8.c create mode 100644 subsys/sal/sid_pal/src/sid_mfg_storage_deprecated.c create mode 100644 tests/unit_tests/mfg_parsers/CMakeLists.txt create mode 100644 tests/unit_tests/mfg_parsers/Kconfig create mode 100644 tests/unit_tests/mfg_parsers/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay create mode 100644 tests/unit_tests/mfg_parsers/mocks/sid_crypto_keys.h rename tests/{functional/mfg_storage => unit_tests/mfg_parsers}/pm_static.yml (74%) create mode 100644 tests/unit_tests/mfg_parsers/pm_static_nrf54l15pdk_nrf54l15_cpuapp.yml create mode 100644 tests/unit_tests/mfg_parsers/prj.conf create mode 100644 tests/unit_tests/mfg_parsers/src/mfg_parser.c create mode 100644 tests/unit_tests/mfg_parsers/src/mock_mem.c create mode 100644 tests/unit_tests/mfg_parsers/src/sid_crypto_keys.c create mode 100644 tests/unit_tests/mfg_parsers/testcase.yaml diff --git a/Kconfig b/Kconfig index 2ea594c42b..a2c8496af9 100644 --- a/Kconfig +++ b/Kconfig @@ -11,6 +11,8 @@ menuconfig SIDEWALK if SIDEWALK # General +config MAIN_STACK_SIZE + default 2048 config SIDEWALK_SUBGHZ_SUPPORT bool "Enable Sub-GHz link type support in Sidewalk libraries" @@ -84,8 +86,8 @@ config SIDEWALK_THREAD_PRIORITY config SIDEWALK_HEAP_SIZE int "Heap size for Sidewalk utils" - default 1024 if SIDEWALK_ACE_OSAL_ZEPHYR - default 0 + default 5120 if SIDEWALK_ACE_OSAL_ZEPHYR + default 4096 help Set the heap size for dynamic memory alocation in Sidewalk. @@ -211,6 +213,20 @@ config SIDEWALK_ON_DEV_CERT bool "Enable Sidewalk on device certification" depends on SHELL +config DEPRECATED_SIDEWALK_MFG_STORAGE + bool "Enable previous implementation of manufacturing module [DEPREACATED]" + imply FLASH + help + Previous Sidewalk manufacturing storage module + This implementation is DEPRECATED + +config SIDEWALK_MFG_STORAGE_SUPPORT_HEX_v7 + bool "Enable support for old Sidewalk manufaturing hex format" + help + Sidewalk manifactuing module uses version 8, with tlv format + Old fromats - version7 and before, are based on memory offsets + and will be supported after enablig this configuration + config SIDEWALK_CRYPTO_PSA_KEY_STORAGE bool "Enable psa crypto storage for persistent Sidewalk keys [EXPERIMENTAL]" default SIDEWALK @@ -224,3 +240,7 @@ rsource "Kconfig.dependencies" rsource "utils/Kconfig" endif # SIDEWALK + +config SIDEWALK_MFG_PARSER_MAX_ELEMENT_SIZE + int "Max size of element in MFG" + default 64 diff --git a/Kconfig.dependencies b/Kconfig.dependencies index 68400dbc4c..fbc243731e 100644 --- a/Kconfig.dependencies +++ b/Kconfig.dependencies @@ -115,26 +115,23 @@ config SIDEWALK_LOG help Sidewalk log module -config SIDEWALK_GENERATE_VERSION_MINIMAL - bool - default SIDEWALK - help - Generate minimal information of application version (sidewalk, zephyr, nrf). - In order to generate full version report from all modules set this config to `N`. - config SIDEWALK_MFG_STORAGE bool - default SIDEWALK + default SIDEWALK && !DEPRECATED_SIDEWALK_MFG_STORAGE imply FLASH + imply FPROTECT + imply SIDEWALK_TLV + imply SIDEWALK_TLV_FLASH + imply SIDEWALK_TLV_RAM help Sidewalk manufacturing storage module + Supports: tlv parser, secure key storage and memory protection -config SIDEWALK_MFG_STORAGE_WRITE +config SIDEWALK_MFG_STORAGE_DIAGNOSTIC bool - default SIDEWALK_ON_DEV_CERT - depends on SIDEWALK_MFG_STORAGE + depends on SIDEWALK_MFG_STORAGE || DEPRECATED_SIDEWALK_MFG_STORAGE help - Enable write functionality to mfg storage + Enable mfg storage diagnostic functionalities config SIDEWALK_STORAGE bool diff --git a/samples/sid_end_device/sample.yaml b/samples/sid_end_device/sample.yaml index e4635fc85f..13745129fb 100644 --- a/samples/sid_end_device/sample.yaml +++ b/samples/sid_end_device/sample.yaml @@ -60,3 +60,10 @@ tests: extra_args: OVERLAY_CONFIG="overlay-dut.conf" tags: Sidewalk cli + + sample.sidewalk.dut.no_secure: + extra_args: + OVERLAY_CONFIG="overlay-dut.conf" + extra_configs: + - CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE=n + tags: Sidewalk cli no_secure diff --git a/samples/sid_end_device/src/cli/app_dut.c b/samples/sid_end_device/src/cli/app_dut.c index de2ec43177..835464eaf0 100644 --- a/samples/sid_end_device/src/cli/app_dut.c +++ b/samples/sid_end_device/src/cli/app_dut.c @@ -31,7 +31,7 @@ static uint32_t dut_ctx_get_uint32(void *ctx) void dut_event_init(sidewalk_ctx_t *sid, void *ctx) { sid->config.link_mask = dut_ctx_get_uint32(ctx); - if (app_mfg_cfg_is_valid()) { + if (app_mfg_cfg_is_empty()) { LOG_ERR("The mfg.hex version mismatch"); LOG_ERR("Check if the file has been generated and flashed properly"); LOG_ERR("START ADDRESS: 0x%08x", APP_MFG_CFG_FLASH_START); diff --git a/samples/sid_end_device/src/sidewalk_events.c b/samples/sid_end_device/src/sidewalk_events.c index 37373d3ede..16bd0bfb9d 100644 --- a/samples/sid_end_device/src/sidewalk_events.c +++ b/samples/sid_end_device/src/sidewalk_events.c @@ -86,7 +86,7 @@ void sidewalk_event_platform_init(sidewalk_ctx_t *sid, void *ctx) LOG_ERR("Sidewalk Platform Init err: %d (%s)", (int)e, SID_ERROR_T_STR(e)); return; } - if (app_mfg_cfg_is_valid()) { + if (app_mfg_cfg_is_empty()) { LOG_ERR("The mfg.hex version mismatch"); LOG_ERR("Check if the file has been generated and flashed properly"); LOG_ERR("START ADDRESS: 0x%08x", APP_MFG_CFG_FLASH_START); @@ -101,7 +101,7 @@ void sidewalk_event_autostart(sidewalk_ctx_t *sid, void *ctx) LOG_INF("Sidewlak is already running"); return; } - if (app_mfg_cfg_is_valid()) { + if (app_mfg_cfg_is_empty()) { LOG_ERR("The mfg.hex version mismatch"); LOG_ERR("Check if the file has been generated and flashed properly"); LOG_ERR("START ADDRESS: 0x%08x", APP_MFG_CFG_FLASH_START); diff --git a/subsys/sal/common/sid_on_dev_cert/sid_on_dev_cert.c b/subsys/sal/common/sid_on_dev_cert/sid_on_dev_cert.c index f80083f3dc..8d80d0efa3 100644 --- a/subsys/sal/common/sid_on_dev_cert/sid_on_dev_cert.c +++ b/subsys/sal/common/sid_on_dev_cert/sid_on_dev_cert.c @@ -25,7 +25,6 @@ #include #include -#include #include #include @@ -640,17 +639,7 @@ sid_error_t sid_on_dev_cert_verify_and_store(void) goto exit; } - /* - * First of all, we need to write the MFG version. - * This will determine the storage format: static offsets or TLV - */ - uint32_t mfg_version; - - if (sid_pal_mfg_store_is_tlv_support()) { - mfg_version = sid_htonl(SID_PAL_MFG_STORE_TLV_VERSION); - } else { - mfg_version = sid_htonl(SID_PAL_MFG_STORE_FIXED_OFFSETS_VERSION); - } + uint32_t mfg_version = sid_htonl(SID_PAL_MFG_STORE_TLV_VERSION); result = sid_pal_mfg_store_write(SID_PAL_MFG_STORE_VERSION, (uint8_t *)&mfg_version, SID_PAL_MFG_STORE_VERSION_SIZE); @@ -661,24 +650,23 @@ sid_error_t sid_on_dev_cert_verify_and_store(void) goto exit; } -#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE - memset(context->device_ed25519_prk, 0, SID_ODC_ED25519_PRK_SIZE); - memset(context->device_p256r1_prk, 0, SID_ODC_P256R1_PRK_SIZE); -#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */ - status = write_to_mfg_store(SID_PAL_MFG_STORE_SMSN, context->smsn, SID_ODC_SMSN_SIZE) && write_to_mfg_store(SID_PAL_MFG_STORE_APID, context->apid, SID_PAL_MFG_STORE_APID_SIZE) && write_to_mfg_store(SID_PAL_MFG_STORE_APP_PUB_ED25519, context->app_key, SID_ODC_ED25519_PUK_SIZE) && +#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE write_to_mfg_store(SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519, context->device_ed25519_prk, SID_ODC_ED25519_PRK_SIZE) && +#endif write_to_mfg_store(SID_PAL_MFG_STORE_DEVICE_PUB_ED25519, context->device_ed25519_puk, SID_ODC_ED25519_PUK_SIZE) && write_to_mfg_store(SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_SIGNATURE, context->device_ed25519_sig, SID_ODC_SIGNATURE_SIZE) && +#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE write_to_mfg_store(SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1, context->device_p256r1_prk, SID_ODC_P256R1_PRK_SIZE) && +#endif write_to_mfg_store(SID_PAL_MFG_STORE_DEVICE_PUB_P256R1, context->device_p256r1_puk, SID_ODC_P256R1_PUK_SIZE) && write_to_mfg_store(SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_SIGNATURE, diff --git a/samples/sid_end_device/include/app_mfg_config.h b/subsys/sal/sid_pal/include/app_mfg_config.h similarity index 93% rename from samples/sid_end_device/include/app_mfg_config.h rename to subsys/sal/sid_pal/include/app_mfg_config.h index ffd54e7c25..1abc8470fe 100644 --- a/samples/sid_end_device/include/app_mfg_config.h +++ b/subsys/sal/sid_pal/include/app_mfg_config.h @@ -18,7 +18,7 @@ #define EMPTY_MFG_HEX_PARTITION (0xFFFFFFFF) -static inline bool app_mfg_cfg_is_valid(void) +static inline bool app_mfg_cfg_is_empty(void) { return sid_pal_mfg_store_get_version() == EMPTY_MFG_HEX_PARTITION; } diff --git a/subsys/sal/sid_pal/include/sid_crypto_keys.h b/subsys/sal/sid_pal/include/sid_crypto_keys.h index 00b731e938..4b195e0007 100644 --- a/subsys/sal/sid_pal/include/sid_crypto_keys.h +++ b/subsys/sal/sid_pal/include/sid_crypto_keys.h @@ -49,6 +49,8 @@ int sid_crypto_keys_new_import(psa_key_id_t id, uint8_t *data, size_t size); * @note key value under given key id will be overwritten. * * @param id [in] Key id to generate new. + * @param puk [in] Buffer with raw key value. + * @param puk_size [in] Size of buffer with rew kay value. * @return 0 on success, or -errno on failure. */ int sid_crypto_keys_new_generate(psa_key_id_t id, uint8_t *puk, size_t puk_size); diff --git a/subsys/sal/sid_pal/include/sid_mfg_hex_parsers.h b/subsys/sal/sid_pal/include/sid_mfg_hex_parsers.h new file mode 100644 index 0000000000..0d4175abbb --- /dev/null +++ b/subsys/sal/sid_pal/include/sid_mfg_hex_parsers.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +#include +#include + +#define MFG_FLAGS_TYPE_ID SID_PAL_MFG_STORE_VALUE_MAX - 1 +struct mfg_flags { + uint8_t unused_bits : 6; + uint8_t keys_in_psa : 1; + uint8_t initialized : 1; + uint8_t unused[3]; +}; + +#define MFG_HEADER_MAGIC "SID0" +#define MFG_HEADER_MAGIC_SIZE sizeof(MFG_HEADER_MAGIC) - 1 +#define REPORTED_VERSION SID_PAL_MFG_STORE_TLV_VERSION + +#define INVALID_VERSION 0xFFFFFFFF +struct mfg_header { + uint8_t magic_string[MFG_HEADER_MAGIC_SIZE]; + uint8_t raw_version[SID_PAL_MFG_STORE_VERSION_SIZE]; +}; + +/** + * @brief Parse content of the manufacturing partition v8, and write it as tlv. + * The TLV will replace raw manufacturing partition + * + * @param tlv [IN/OUT] configuration for tlv + * @return int 0 on success, -ERRNO on error + */ +int parse_mfg_raw_tlv(tlv_ctx *tlv); + +/** + * @brief Parse content of the manufacturing partition v7, and write it as tlv. + * The TLV will replace raw manufacturing partition + * + * @param tlv [IN/OUT] configuration for tlv + * @return int 0 on success, -ERRNO on error + */ +int parse_mfg_const_offsets(tlv_ctx *tlv); diff --git a/subsys/sal/sid_pal/src/CMakeLists.txt b/subsys/sal/sid_pal/src/CMakeLists.txt index f80661eb0e..3b9f9cfb18 100644 --- a/subsys/sal/sid_pal/src/CMakeLists.txt +++ b/subsys/sal/sid_pal/src/CMakeLists.txt @@ -35,7 +35,9 @@ zephyr_library_sources_ifdef(CONFIG_SIDEWALK_LOGGING_SERVICE sid_ble_log_service zephyr_library_sources_ifdef(CONFIG_SIDEWALK_CRYPTO sid_crypto.c) zephyr_library_sources_ifdef(CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE sid_crypto_keys.c) -zephyr_library_sources_ifdef(CONFIG_SIDEWALK_MFG_STORAGE sid_mfg_storage.c) +zephyr_library_sources_ifdef(CONFIG_SIDEWALK_MFG_STORAGE sid_mfg_storage.c sid_mfg_hex_v8.c) +zephyr_library_sources_ifdef(CONFIG_SIDEWALK_MFG_STORAGE_SUPPORT_HEX_v7 sid_mfg_hex_v7.c) +zephyr_library_sources_ifdef(CONFIG_DEPRECATED_SIDEWALK_MFG_STORAGE sid_mfg_storage_deprecated.c) zephyr_library_sources_ifdef(CONFIG_SIDEWALK_STORAGE sid_storage.c) diff --git a/subsys/sal/sid_pal/src/sid_mfg_hex_v7.c b/subsys/sal/sid_pal/src/sid_mfg_hex_v7.c new file mode 100644 index 0000000000..6aad38b5a1 --- /dev/null +++ b/subsys/sal/sid_pal/src/sid_mfg_hex_v7.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE +#include +#endif +LOG_MODULE_REGISTER(sid_mfg_parser_v7, CONFIG_SIDEWALK_LOG_LEVEL); + +struct sid_pal_mfg_store_value_to_address_offset { + sid_pal_mfg_store_value_t value; + uint16_t size; + uint32_t offset; +}; + +// clang-format off +struct sid_pal_mfg_store_value_to_address_offset sid_pal_mfg_store_app_value_to_offset_table[] = { + {SID_PAL_MFG_STORE_SERIAL_NUM, SID_PAL_MFG_STORE_SERIAL_NUM_SIZE, SID_PAL_MFG_STORE_OFFSET_SERIAL_NUM}, + {SID_PAL_MFG_STORE_SMSN, SID_PAL_MFG_STORE_SMSN_SIZE, SID_PAL_MFG_STORE_OFFSET_SMSN}, + {SID_PAL_MFG_STORE_APP_PUB_ED25519, SID_PAL_MFG_STORE_APP_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_APP_PUB_ED25519}, + {SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519, SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVICE_PRIV_ED25519}, + {SID_PAL_MFG_STORE_DEVICE_PUB_ED25519, SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_ED25519}, + {SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_SIGNATURE, SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_ED25519_SIGNATURE}, + {SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1, SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVICE_PRIV_P256R1}, + {SID_PAL_MFG_STORE_DEVICE_PUB_P256R1, SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_P256R1}, + {SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_SIGNATURE, SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_P256R1_SIGNATURE}, + {SID_PAL_MFG_STORE_DAK_PUB_ED25519, SID_PAL_MFG_STORE_DAK_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_DAK_PUB_ED25519}, + {SID_PAL_MFG_STORE_DAK_PUB_ED25519_SIGNATURE, SID_PAL_MFG_STORE_DAK_PUB_ED25519_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_DAK_PUB_ED25519_SIGNATURE}, + {SID_PAL_MFG_STORE_DAK_ED25519_SERIAL, SID_PAL_MFG_STORE_DAK_ED25519_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_DAK_ED25519_SERIAL}, + {SID_PAL_MFG_STORE_DAK_PUB_P256R1, SID_PAL_MFG_STORE_DAK_PUB_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_DAK_PUB_P256R1}, + {SID_PAL_MFG_STORE_DAK_PUB_P256R1_SIGNATURE, SID_PAL_MFG_STORE_DAK_PUB_P256R1_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_DAK_PUB_P256R1_SIGNATURE}, + {SID_PAL_MFG_STORE_DAK_P256R1_SERIAL, SID_PAL_MFG_STORE_DAK_P256R1_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_DAK_P256R1_SERIAL}, + {SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519, SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_ED25519}, + {SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_SIGNATURE,SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_SIGNATURE_SIZE,SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_ED25519_SIGNATURE}, + {SID_PAL_MFG_STORE_PRODUCT_ED25519_SERIAL, SID_PAL_MFG_STORE_PRODUCT_ED25519_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_PRODUCT_ED25519_SERIAL}, + {SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1, SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_P256R1}, + {SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_SIGNATURE, SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_P256R1_SIGNATURE}, + {SID_PAL_MFG_STORE_PRODUCT_P256R1_SERIAL, SID_PAL_MFG_STORE_PRODUCT_P256R1_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_PRODUCT_P256R1_SERIAL}, + {SID_PAL_MFG_STORE_MAN_PUB_ED25519, SID_PAL_MFG_STORE_MAN_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_MAN_PUB_ED25519}, + {SID_PAL_MFG_STORE_MAN_PUB_ED25519_SIGNATURE, SID_PAL_MFG_STORE_MAN_PUB_ED25519_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_MAN_PUB_ED25519_SIGNATURE}, + {SID_PAL_MFG_STORE_MAN_ED25519_SERIAL, SID_PAL_MFG_STORE_MAN_ED25519_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_MAN_ED25519_SERIAL}, + {SID_PAL_MFG_STORE_MAN_PUB_P256R1, SID_PAL_MFG_STORE_MAN_PUB_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_MAN_PUB_P256R1}, + {SID_PAL_MFG_STORE_MAN_PUB_P256R1_SIGNATURE, SID_PAL_MFG_STORE_MAN_PUB_P256R1_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_MAN_PUB_P256R1_SIGNATURE}, + {SID_PAL_MFG_STORE_MAN_P256R1_SERIAL, SID_PAL_MFG_STORE_MAN_P256R1_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_MAN_P256R1_SERIAL}, + {SID_PAL_MFG_STORE_SW_PUB_ED25519, SID_PAL_MFG_STORE_SW_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_SW_PUB_ED25519}, + {SID_PAL_MFG_STORE_SW_PUB_ED25519_SIGNATURE, SID_PAL_MFG_STORE_SW_PUB_ED25519_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_SW_PUB_ED25519_SIGNATURE}, + {SID_PAL_MFG_STORE_SW_ED25519_SERIAL, SID_PAL_MFG_STORE_SW_ED25519_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_SW_ED25519_SERIAL}, + {SID_PAL_MFG_STORE_SW_PUB_P256R1, SID_PAL_MFG_STORE_SW_PUB_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_SW_PUB_P256R1}, + {SID_PAL_MFG_STORE_SW_PUB_P256R1_SIGNATURE, SID_PAL_MFG_STORE_SW_PUB_P256R1_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_SW_PUB_P256R1_SIGNATURE}, + {SID_PAL_MFG_STORE_SW_P256R1_SERIAL, SID_PAL_MFG_STORE_SW_P256R1_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_SW_P256R1_SERIAL}, + {SID_PAL_MFG_STORE_AMZN_PUB_ED25519, SID_PAL_MFG_STORE_AMZN_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_AMZN_PUB_ED25519}, + {SID_PAL_MFG_STORE_AMZN_PUB_P256R1, SID_PAL_MFG_STORE_AMZN_PUB_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_AMZN_PUB_P256R1}, + {SID_PAL_MFG_STORE_APID, SID_PAL_MFG_STORE_APID_SIZE, SID_PAL_MFG_STORE_OFFSET_APID}, +}; +// clang-format on + +int parse_mfg_const_offsets(tlv_ctx *tlv) +{ + if (tlv->end_offset <= tlv->start_offset) { + return -EINVAL; + } + + uint32_t size = tlv->end_offset - tlv->start_offset; + + uint8_t *ram_tlv_data = sid_hal_malloc(size); + if (ram_tlv_data == NULL) { + return -ENOMEM; + } + memset(ram_tlv_data, 0xff, size); + + tlv_ctx ram_tlv = { .start_offset = 0, + .end_offset = size, + .tlv_storage_start_marker_size = tlv->tlv_storage_start_marker_size, + .storage_impl = { .ctx = ram_tlv_data, + .read = tlv_storage_ram_read, + .write = tlv_storage_ram_write } }; + + struct mfg_header mfg_header = { .magic_string = MFG_HEADER_MAGIC, + .raw_version = { 0, 0, 0, REPORTED_VERSION } }; + + int ret = + tlv_write_start_marker(&ram_tlv, (uint8_t *)&mfg_header, sizeof(struct mfg_header)); + if (ret != 0) { + LOG_ERR("Failed to write marker before mfg data"); + sid_hal_free(ram_tlv_data); + return -EIO; + } + + uint8_t payload_buffer[CONFIG_SIDEWALK_MFG_PARSER_MAX_ELEMENT_SIZE] = { 0 }; + + for (int i = 0; i < ARRAY_SIZE(sid_pal_mfg_store_app_value_to_offset_table); i++) { + struct sid_pal_mfg_store_value_to_address_offset element = + sid_pal_mfg_store_app_value_to_offset_table[i]; + int ret = tlv->storage_impl.read(tlv->storage_impl.ctx, + tlv->start_offset + (element.offset * WORD_SIZE), + payload_buffer, element.size); + if (ret != 0) { + LOG_ERR("Failed to read data"); + sid_hal_free(ram_tlv_data); + return -EIO; + } + if (element.size > SID_PAL_MFG_STORE_MAX_FLASH_WRITE_LEN || + memcmp(payload_buffer, + (char[]){ [0 ...(SID_PAL_MFG_STORE_MAX_FLASH_WRITE_LEN - 1)] = 0xFF }, + element.size) == 0) { + // ignore empty values + continue; + } + +#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE + if (element.value == SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519) { + int err = sid_crypto_keys_new_import(SID_CRYPTO_MFG_ED25519_PRIV_KEY_ID, + payload_buffer, element.size); + LOG_INF("MFG_ED25519 import %s", (0 == err) ? "success" : "failure"); + + if (err != 0) { + sid_hal_free(ram_tlv_data); + return -EACCES; + } + continue; + } else if (element.value == SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1) { + int err = sid_crypto_keys_new_import(SID_CRYPTO_MFG_SECP_256R1_PRIV_KEY_ID, + payload_buffer, element.size); + LOG_INF("MFG_SECP_256R1 import %s", (0 == err) ? "success" : "failure"); + + if (err != 0) { + sid_hal_free(ram_tlv_data); + return -EACCES; + } + continue; + } +#endif + ret = tlv_write(&ram_tlv, element.value, payload_buffer, element.size); + if (ret != 0) { + LOG_ERR("Failed to write data"); + sid_hal_free(ram_tlv_data); + return -EIO; + } + } + + struct mfg_flags flags = { + .initialized = 1, +#if CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE + .keys_in_psa = 1, +#endif + }; + ret = tlv_write(&ram_tlv, MFG_FLAGS_TYPE_ID, (uint8_t *)&flags, sizeof(flags)); + if (ret != 0) { + LOG_ERR("Failed to write data"); + sid_hal_free(ram_tlv_data); + return -EIO; + } + + ret = tlv->storage_impl.write(tlv->storage_impl.ctx, tlv->start_offset, ram_tlv_data, size); + if (ret != 0) { + LOG_ERR("Failed to write parsed tlv data to flash"); + sid_hal_free(ram_tlv_data); + return -EIO; + } + sid_hal_free(ram_tlv_data); + return 0; +} diff --git a/subsys/sal/sid_pal/src/sid_mfg_hex_v8.c b/subsys/sal/sid_pal/src/sid_mfg_hex_v8.c new file mode 100644 index 0000000000..13fe0cab5f --- /dev/null +++ b/subsys/sal/sid_pal/src/sid_mfg_hex_v8.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE +#include +#include +#endif + +#define MFG_STORE_TLV_TAG_EMPTY 0xFFFF + +LOG_MODULE_REGISTER(sid_mfg_parser_v8, CONFIG_SIDEWALK_LOG_LEVEL); + +int parse_mfg_raw_tlv(tlv_ctx *tlv) +{ + if (tlv->end_offset <= tlv->start_offset) { + return -EINVAL; + } + + uint32_t size = tlv->end_offset - tlv->start_offset; + + uint8_t *ram_tlv_data = sid_hal_malloc(size); + if (ram_tlv_data == NULL) { + return -ENOMEM; + } + memset(ram_tlv_data, 0xff, size); + + tlv_ctx ram_tlv = { .start_offset = 0, + .end_offset = size, + .tlv_storage_start_marker_size = tlv->tlv_storage_start_marker_size, + .storage_impl = { .ctx = ram_tlv_data, + .read = tlv_storage_ram_read, + .write = tlv_storage_ram_write } }; + + uint32_t offset = tlv->start_offset + tlv->tlv_storage_start_marker_size; + + struct mfg_header mfg_header = { .magic_string = MFG_HEADER_MAGIC, + .raw_version = { 0, 0, 0, REPORTED_VERSION } }; + + int ret = + tlv_write_start_marker(&ram_tlv, (uint8_t *)&mfg_header, sizeof(struct mfg_header)); + if (ret != 0) { + LOG_ERR("Failed to write marker before mfg data"); + sid_hal_free(ram_tlv_data); + return -EIO; + } + + uint8_t payload_buffer[CONFIG_SIDEWALK_MFG_PARSER_MAX_ELEMENT_SIZE] = { 0 }; + for (; offset < tlv->end_offset;) { + uint8_t key[2]; + uint8_t size[2]; + int ret = tlv->storage_impl.read(tlv->storage_impl.ctx, offset, key, sizeof(key)); + if (ret != 0) { + LOG_ERR("Failed to read data"); + sid_hal_free(ram_tlv_data); + return -EIO; + } + offset += 2; + uint16_t key_decoded = (key[0] << 8) + key[1]; + if (key_decoded == MFG_STORE_TLV_TAG_EMPTY) { + break; + } + ret = tlv->storage_impl.read(tlv->storage_impl.ctx, offset, size, sizeof(size)); + if (ret != 0) { + LOG_ERR("Failed to read data"); + sid_hal_free(ram_tlv_data); + return -EIO; + } + offset += 2; + uint16_t size_decoded = (size[0] << 8) | size[1]; + ret = tlv->storage_impl.read(tlv->storage_impl.ctx, offset, payload_buffer, + size_decoded); + if (ret != 0) { + LOG_ERR("Failed to read data"); + sid_hal_free(ram_tlv_data); + return -EIO; + } + offset += size_decoded; + +#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE + if (key_decoded == SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519) { + int err = sid_crypto_keys_new_import(SID_CRYPTO_MFG_ED25519_PRIV_KEY_ID, + payload_buffer, size_decoded); + LOG_INF("MFG_ED25519 import %s", (0 == err) ? "success" : "failure"); + + if (err != 0) { + sid_hal_free(ram_tlv_data); + return -EACCES; + } + continue; + } + if (key_decoded == SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1) { + int err = sid_crypto_keys_new_import(SID_CRYPTO_MFG_SECP_256R1_PRIV_KEY_ID, + payload_buffer, size_decoded); + LOG_INF("MFG_SECP_256R1 import %s", (0 == err) ? "success" : "failure"); + + if (err != 0) { + sid_hal_free(ram_tlv_data); + return -EACCES; + } + continue; + } +#endif + + ret = tlv_write(&ram_tlv, key_decoded, payload_buffer, size_decoded); + if (ret != 0) { + LOG_ERR("Failed to write data"); + sid_hal_free(ram_tlv_data); + return -EIO; + } + } + + struct mfg_flags flags = { + .initialized = 1, +#if CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE + .keys_in_psa = 1, +#endif + }; + ret = tlv_write(&ram_tlv, MFG_FLAGS_TYPE_ID, (uint8_t *)&flags, sizeof(flags)); + if (ret != 0) { + LOG_ERR("Failed to write data"); + sid_hal_free(ram_tlv_data); + return -EIO; + } + + ret = tlv->storage_impl.write(tlv->storage_impl.ctx, tlv->start_offset, ram_tlv_data, + ram_tlv.end_offset); + if (ret != 0) { + LOG_ERR("Failed to write parsed tlv data to flash"); + sid_hal_free(ram_tlv_data); + return -EIO; + } + sid_hal_free(ram_tlv_data); + return 0; +} diff --git a/subsys/sal/sid_pal/src/sid_mfg_storage.c b/subsys/sal/sid_pal/src/sid_mfg_storage.c index 1afb83d462..affafe1d01 100644 --- a/subsys/sal/sid_pal/src/sid_mfg_storage.c +++ b/subsys/sal/sid_pal/src/sid_mfg_storage.c @@ -10,28 +10,28 @@ #include #include -#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE -#include -#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */ #include -#include #include #include +#include +#include #include #include -#include -#include #include -#include #include +#include +#include +#include + LOG_MODULE_REGISTER(sid_mfg, CONFIG_SIDEWALK_LOG_LEVEL); -// Manufacturing version define -#define MFG_VERSION_1_VAL 0x01000000 -#define MFG_VERSION_2_VAL 0x2 +#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE +#include +static int sid_mfg_storage_secure_read(uint16_t *p_value, uint8_t *buffer, uint16_t length); +#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */ #define FLASH_MEM_CHUNK (128) @@ -51,381 +51,132 @@ LOG_MODULE_REGISTER(sid_mfg, CONFIG_SIDEWALK_LOG_LEVEL); #endif #endif /* DEV_ID_REG */ -// DEV_ID masks -#define ENCODED_DEV_ID_SIZE_5_BYTES_MASK 0xA0 -#define DEV_ID_MSB_MASK 0x1F - -#define MFG_WORD_SIZE_VER_1 (8) - -static const uint32_t MFG_WORD_SIZE = 4; // in bytes - -#define MFG_STORE_TLV_HEADER_SIZE 4 -#define MFG_STORE_TLV_TAG_EMPTY 0xFFFF -#define EXPAND_TO_MULTIPLE_WORD(_VALUE_) (((_VALUE_ + 3) / 4) * 4) - -#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE -#define SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519_RAW (100) -#define SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1_RAW (101) -#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */ - -struct sid_pal_mfg_store_tlv_info { - uint16_t tag; - uint16_t length; - /** TLV offset from mfg_store_region.addr_start in bytes */ - size_t offset; -}; - -struct sid_pal_mfg_store_value_to_address_offset { - sid_pal_mfg_store_value_t value; - uint16_t size; - uint32_t offset; -}; - -static void ntoh_buff(uint8_t *buffer, size_t buff_len); -static uint32_t default_app_value_to_offset(int value); -static off_t checked_addr_return(off_t offset, uintptr_t start_address, uintptr_t end_address); -static off_t value_to_offset(sid_pal_mfg_store_value_t value, uintptr_t start_address, - uintptr_t end_address); - -// clang-format off -struct sid_pal_mfg_store_value_to_address_offset sid_pal_mfg_store_app_value_to_offset_table[] = { - {SID_PAL_MFG_STORE_VERSION, SID_PAL_MFG_STORE_VERSION_SIZE, SID_PAL_MFG_STORE_OFFSET_VERSION}, - {SID_PAL_MFG_STORE_DEVID, SID_PAL_MFG_STORE_DEVID_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVID}, - {SID_PAL_MFG_STORE_SERIAL_NUM, SID_PAL_MFG_STORE_SERIAL_NUM_SIZE, SID_PAL_MFG_STORE_OFFSET_SERIAL_NUM}, - {SID_PAL_MFG_STORE_SMSN, SID_PAL_MFG_STORE_SMSN_SIZE, SID_PAL_MFG_STORE_OFFSET_SMSN}, - {SID_PAL_MFG_STORE_APID, SID_PAL_MFG_STORE_APID_SIZE, SID_PAL_MFG_STORE_OFFSET_APID}, - {SID_PAL_MFG_STORE_APP_PUB_ED25519, SID_PAL_MFG_STORE_APP_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_APP_PUB_ED25519}, - {SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519, SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVICE_PRIV_ED25519}, - {SID_PAL_MFG_STORE_DEVICE_PUB_ED25519, SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_ED25519}, - {SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_SIGNATURE, SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_ED25519_SIGNATURE}, - {SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1, SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVICE_PRIV_P256R1}, - {SID_PAL_MFG_STORE_DEVICE_PUB_P256R1, SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_P256R1}, - {SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_SIGNATURE, SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_P256R1_SIGNATURE}, - {SID_PAL_MFG_STORE_DAK_PUB_ED25519, SID_PAL_MFG_STORE_DAK_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_DAK_PUB_ED25519}, - {SID_PAL_MFG_STORE_DAK_PUB_ED25519_SIGNATURE, SID_PAL_MFG_STORE_DAK_PUB_ED25519_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_DAK_PUB_ED25519_SIGNATURE}, - {SID_PAL_MFG_STORE_DAK_ED25519_SERIAL, SID_PAL_MFG_STORE_DAK_ED25519_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_DAK_ED25519_SERIAL}, - {SID_PAL_MFG_STORE_DAK_PUB_P256R1, SID_PAL_MFG_STORE_DAK_PUB_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_DAK_PUB_P256R1}, - {SID_PAL_MFG_STORE_DAK_PUB_P256R1_SIGNATURE, SID_PAL_MFG_STORE_DAK_PUB_P256R1_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_DAK_PUB_P256R1_SIGNATURE}, - {SID_PAL_MFG_STORE_DAK_P256R1_SERIAL, SID_PAL_MFG_STORE_DAK_P256R1_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_DAK_P256R1_SERIAL}, - {SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519, SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_ED25519}, - {SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_SIGNATURE,SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_SIGNATURE_SIZE,SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_ED25519_SIGNATURE}, - {SID_PAL_MFG_STORE_PRODUCT_ED25519_SERIAL, SID_PAL_MFG_STORE_PRODUCT_ED25519_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_PRODUCT_ED25519_SERIAL}, - {SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1, SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_P256R1}, - {SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_SIGNATURE, SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_P256R1_SIGNATURE}, - {SID_PAL_MFG_STORE_PRODUCT_P256R1_SERIAL, SID_PAL_MFG_STORE_PRODUCT_P256R1_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_PRODUCT_P256R1_SERIAL}, - {SID_PAL_MFG_STORE_MAN_PUB_ED25519, SID_PAL_MFG_STORE_MAN_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_MAN_PUB_ED25519}, - {SID_PAL_MFG_STORE_MAN_PUB_ED25519_SIGNATURE, SID_PAL_MFG_STORE_MAN_PUB_ED25519_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_MAN_PUB_ED25519_SIGNATURE}, - {SID_PAL_MFG_STORE_MAN_ED25519_SERIAL, SID_PAL_MFG_STORE_MAN_ED25519_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_MAN_ED25519_SERIAL}, - {SID_PAL_MFG_STORE_MAN_PUB_P256R1, SID_PAL_MFG_STORE_MAN_PUB_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_MAN_PUB_P256R1}, - {SID_PAL_MFG_STORE_MAN_PUB_P256R1_SIGNATURE, SID_PAL_MFG_STORE_MAN_PUB_P256R1_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_MAN_PUB_P256R1_SIGNATURE}, - {SID_PAL_MFG_STORE_MAN_P256R1_SERIAL, SID_PAL_MFG_STORE_MAN_P256R1_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_MAN_P256R1_SERIAL}, - {SID_PAL_MFG_STORE_SW_PUB_ED25519, SID_PAL_MFG_STORE_SW_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_SW_PUB_ED25519}, - {SID_PAL_MFG_STORE_SW_PUB_ED25519_SIGNATURE, SID_PAL_MFG_STORE_SW_PUB_ED25519_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_SW_PUB_ED25519_SIGNATURE}, - {SID_PAL_MFG_STORE_SW_ED25519_SERIAL, SID_PAL_MFG_STORE_SW_ED25519_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_SW_ED25519_SERIAL}, - {SID_PAL_MFG_STORE_SW_PUB_P256R1, SID_PAL_MFG_STORE_SW_PUB_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_SW_PUB_P256R1}, - {SID_PAL_MFG_STORE_SW_PUB_P256R1_SIGNATURE, SID_PAL_MFG_STORE_SW_PUB_P256R1_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_SW_PUB_P256R1_SIGNATURE}, - {SID_PAL_MFG_STORE_SW_P256R1_SERIAL, SID_PAL_MFG_STORE_SW_P256R1_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_SW_P256R1_SERIAL}, - {SID_PAL_MFG_STORE_AMZN_PUB_ED25519, SID_PAL_MFG_STORE_AMZN_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_AMZN_PUB_ED25519}, - {SID_PAL_MFG_STORE_AMZN_PUB_P256R1, SID_PAL_MFG_STORE_AMZN_PUB_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_AMZN_PUB_P256R1}, -}; -// clang-format on - -static sid_pal_mfg_store_region_t nrf_mfg_store_region = { - .app_value_to_offset = default_app_value_to_offset, -}; - static const struct device *flash_dev; +static uint32_t sid_mfg_version = INVALID_VERSION; +tlv_ctx tlv_flash; -static bool sid_pal_mfg_store_search_for_tag(uint16_t tag, - struct sid_pal_mfg_store_tlv_info *tlv_info) +void sid_pal_mfg_store_init(sid_pal_mfg_store_region_t mfg_store_region) { - off_t address = (off_t)(nrf_mfg_store_region.addr_start + - SID_PAL_MFG_STORE_OFFSET_VERSION * MFG_WORD_SIZE + - SID_PAL_MFG_STORE_VERSION_SIZE); - - uint16_t current_tag, length; - uint8_t type_length_raw[MFG_STORE_TLV_HEADER_SIZE] = { 0 }; - - while (1) { - int rc = flash_read(flash_dev, address, type_length_raw, MFG_STORE_TLV_HEADER_SIZE); - if (0 != rc) { - LOG_ERR("Flash read fail %d", rc); - return false; - } - current_tag = (type_length_raw[0] << 8) + type_length_raw[1]; - length = (type_length_raw[2] << 8) + type_length_raw[3]; - - if (current_tag == tag) { - tlv_info->tag = tag; - tlv_info->length = length; - tlv_info->offset = address; - return true; - } else { - if (current_tag == MFG_STORE_TLV_TAG_EMPTY) { - break; - } - /* - * Go to the next TLV. - * Since data is written to flash with data aligned to 4, we must take this - * into account if the data length is not a multiple of 4. - */ - address += (MFG_STORE_TLV_HEADER_SIZE + EXPAND_TO_MULTIPLE_WORD(length)); - // Check that we have not reached the end of the storage - if ((uintptr_t)(address + MFG_STORE_TLV_HEADER_SIZE + MFG_WORD_SIZE) > - nrf_mfg_store_region.addr_end) { - break; - } - } + /* Initialize Flash device*/ + flash_dev = DEVICE_DT_GET_OR_NULL(DT_CHOSEN(zephyr_flash_controller)); + if (!flash_dev) { + LOG_ERR("Flash device is not found."); + return; } - return false; -} -/** - * @brief The function converts network byte order to host byte order on the whole buffer. - * - * @param buffer - input/output buffer. - * @param buff_len - number of bytes in buffer. - */ -static void ntoh_buff(uint8_t *buffer, size_t buff_len) -{ - uint32_t val_l = 0; - size_t i = 0; - size_t mod_len = buff_len % sizeof(uint32_t); - - if (sizeof(uint32_t) <= buff_len) { - for (i = 0; i < (buff_len - mod_len); i += sizeof(uint32_t)) { - memcpy(&val_l, &buffer[i], sizeof(val_l)); - val_l = sys_be32_to_cpu(val_l); - memcpy(&buffer[i], &val_l, sizeof(val_l)); + tlv_flash = (tlv_ctx){ .storage_impl = { .write = tlv_storage_flash_write, + .read = tlv_storage_flash_read, + .ctx = (void *)flash_dev }, + .start_offset = mfg_store_region.addr_start, + .end_offset = mfg_store_region.addr_end, + .tlv_storage_start_marker_size = sizeof(struct mfg_header) }; + + struct mfg_header header; + int ret = tlv_read_start_marker(&tlv_flash, (uint8_t *)&header, sizeof(header)); + if (ret != 0 || + strncmp(header.magic_string, MFG_HEADER_MAGIC, strlen(MFG_HEADER_MAGIC)) != 0) { + if (ret != 0) { + LOG_ERR("Failed to read mfg start marker errno %d", ret); } +#if CONFIG_SIDEWALK_ON_DEV_CERT + LOG_INF("Please perform on_device_certification and reboot"); +#endif + return; } - if (2 == mod_len) { - uint16_t val_s = 0; - memcpy(&val_s, &buffer[i], sizeof(val_s)); - val_s = sys_be16_to_cpu(val_s); - memcpy(&buffer[i], &val_s, sizeof(val_s)); - } else if (3 == mod_len) { - val_l = 0; - memcpy(&val_l, &buffer[i], 3 * sizeof(uint8_t)); - val_l = sys_be24_to_cpu(val_l); - memcpy(&buffer[i], &val_l, 3 * sizeof(uint8_t)); - } -} - -/** - * @brief The 'dummy' function used when application doesn't provide it's own - * implementation for this function. - * - * @param value - unused argument. - * @return SID_PAL_MFG_STORE_INVALID_OFFSET - */ -static uint32_t default_app_value_to_offset(int value) -{ - ARG_UNUSED(value); - LOG_WRN("No support for app_value_to_offset."); - return SID_PAL_MFG_STORE_INVALID_OFFSET; -} - -/** - * @brief The function checks if offset is in address range of the manufacturing store partition. - * - * @param offset - memory offset. - * @param start_address - mfg partition start address. - * @param end_address - mfg partition end address. - * @return Offset in physical flash memory or SID_PAL_MFG_STORE_INVALID_OFFSET when offest is out - * of manufacturing storage address range. - */ -static off_t checked_addr_return(off_t offset, uintptr_t start_address, uintptr_t end_address) -{ - if (start_address + offset >= end_address) { - LOG_ERR("Offset past manufacturing store end: %d.", (int)offset); - return SID_PAL_MFG_STORE_INVALID_OFFSET; - } - return (off_t)(start_address + offset); -} - -/** - * @brief The function calculates memory offset for desired value. - * - * @param value - Enum constant for the desired value. - * @param start_address - mfg partition start address. - * @param end_address - mfg partition end address. - * @return Offset in physical flash memory when success otherwise SID_PAL_MFG_STORE_INVALID_OFFSET. - */ -static off_t value_to_offset(sid_pal_mfg_store_value_t value, uintptr_t start_address, - uintptr_t end_address) -{ - const size_t table_count = ARRAY_SIZE(sid_pal_mfg_store_app_value_to_offset_table); - - for (uint32_t i = 0; i < table_count; i++) { - if (value == sid_pal_mfg_store_app_value_to_offset_table[i].value) { - const off_t offset = sid_pal_mfg_store_app_value_to_offset_table[i].offset; - return (off_t)((SID_PAL_MFG_STORE_INVALID_OFFSET != offset) ? - (start_address + (offset << 2)) : - SID_PAL_MFG_STORE_INVALID_OFFSET); + sid_mfg_version = header.raw_version[3] + (header.raw_version[2] << 8) + + (header.raw_version[1] << 16) + ((header.raw_version[0]) << 24); + + bool need_to_parse = false; + if (sid_mfg_version == SID_PAL_MFG_STORE_TLV_VERSION) { + // header is valid, version is supported + struct mfg_flags flags = {}; + int ret = tlv_read(&tlv_flash, MFG_FLAGS_TYPE_ID, (uint8_t *)&flags, sizeof(flags)); + switch (ret) { + case -ENODATA: + need_to_parse = true; + break; + case 0: + break; + default: { + LOG_ERR("Failed to read mfg data errno: %d", ret); + return; } - } - - if (value < 0 || value >= SID_PAL_MFG_STORE_CORE_VALUE_MAX) { - // This is not a core value. Search for this value among those provided by the application. - off_t custom_offset = nrf_mfg_store_region.app_value_to_offset(value); - if (SID_PAL_MFG_STORE_INVALID_OFFSET != custom_offset) { - return checked_addr_return(custom_offset, start_address, end_address); } - } - - LOG_ERR("No Nordic manufacturing store offset for: %d.", value); - return SID_PAL_MFG_STORE_INVALID_OFFSET; -} -void sid_pal_mfg_store_init(sid_pal_mfg_store_region_t mfg_store_region) -{ - nrf_mfg_store_region = mfg_store_region; - - if (!nrf_mfg_store_region.app_value_to_offset) { - nrf_mfg_store_region.app_value_to_offset = default_app_value_to_offset; - } +#if CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE + if ((flags.keys_in_psa) == 0) { + // parse to move keys to psa + need_to_parse = true; + } +#else + if (flags.keys_in_psa) { + LOG_ERR("Replace mfg hex. Keys are stored in PSA, but application is not build to support it."); + return; + } +#endif + if (flags.initialized == 0) { + need_to_parse = true; + } - flash_dev = DEVICE_DT_GET_OR_NULL(DT_CHOSEN(zephyr_flash_controller)); - if (!flash_dev) { - LOG_ERR("Flash device is not found."); + } else { + need_to_parse = true; } -#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE - int rc = 0; - uint8_t raw_key[32]; - uint8_t zeros[32] = { 0 }; - - sid_pal_mfg_store_read(SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519_RAW, raw_key, sizeof(raw_key)); - if (0 != memcmp(raw_key, zeros, sizeof(raw_key))) { - rc = sid_crypto_keys_new_import(SID_CRYPTO_MFG_ED25519_PRIV_KEY_ID, raw_key, - sizeof(raw_key)); - LOG_INF("MFG_ED25519 import %s", (0 == rc) ? "success" : "failure"); - LOG_HEXDUMP_INF(raw_key, sizeof(raw_key), "value:"); - memset(raw_key, 0, sizeof(raw_key)); - rc = sid_pal_mfg_store_write(SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519_RAW, raw_key, - sizeof(raw_key)); - LOG_INF("MFG_ED25519 overwrite status %d", rc); + if (need_to_parse) { + LOG_INF("Need to parse MFG data"); + int err = 0; + switch (sid_mfg_version) { + case 8: + err = parse_mfg_raw_tlv(&tlv_flash); + break; +#if CONFIG_SIDEWALK_MFG_STORAGE_SUPPORT_HEX_v7 + case 1 ... 7: + case 0x01000000: + err = parse_mfg_const_offsets(&tlv_flash); + break; +#endif /* CONFIG_SIDEWALK_MFG_STORAGE_SUPPORT_HEX_v7 */ + default: { + LOG_ERR("Incompatible MFG hex version"); + return; + } + } + if (err != 0) { + LOG_ERR("Failed parsing MFG hex errno %d", err); + return; + } + LOG_INF("MFG data succesfully parsed"); + sid_mfg_version = SID_PAL_MFG_STORE_TLV_VERSION; } - sid_pal_mfg_store_read(SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1_RAW, raw_key, sizeof(raw_key)); - if (0 != memcmp(raw_key, zeros, sizeof(raw_key))) { - rc = sid_crypto_keys_new_import(SID_CRYPTO_MFG_SECP_256R1_PRIV_KEY_ID, raw_key, - sizeof(raw_key)); - LOG_INF("MFG_SECP_256R1 import %s", (0 == rc) ? "success" : "failure"); - LOG_HEXDUMP_INF(raw_key, sizeof(raw_key), "value:"); - memset(raw_key, 0, sizeof(raw_key)); - rc = sid_pal_mfg_store_write(SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1_RAW, raw_key, - sizeof(raw_key)); - LOG_INF("MFG_SECP_256R1 overwrite status %d", rc); +#if !CONFIG_SIDEWALK_MFG_STORAGE_DIAGNOSTIC + /* Protect against write */ + int err = fprotect_area(PM_MFG_FPROTECT_ADDRESS, PM_MFG_FPROTECT_SIZE); + if (err) { + LOG_ERR("Flash protect failed %d", err); } - -#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */ +#endif } void sid_pal_mfg_store_deinit(void) { - memset(&nrf_mfg_store_region, 0, sizeof(sid_pal_mfg_store_region_t)); + memset(&tlv_flash, 0x0, sizeof(tlv_flash)); } int32_t sid_pal_mfg_store_write(uint16_t value, const uint8_t *buffer, uint16_t length) { -#if CONFIG_SIDEWALK_MFG_STORAGE_WRITE - uint32_t ret_code = 0; - uint8_t __aligned(4) wr_array[SID_PAL_MFG_STORE_MAX_FLASH_WRITE_LEN]; - - if (length == 0 || value == MFG_STORE_TLV_TAG_EMPTY || buffer == NULL) { - return (int32_t)SID_ERROR_INVALID_ARGS; - } - - uint32_t version = sid_pal_mfg_store_get_version(); if (value == SID_PAL_MFG_STORE_VERSION) { - version = SID_PAL_MFG_STORE_VERSION; - } - if (version == SID_PAL_MFG_STORE_TLV_VERSION) { - struct sid_pal_mfg_store_tlv_info tlv_info = {}; - - if (sid_pal_mfg_store_search_for_tag(value, &tlv_info)) { - // The tag value already exists. We can't write duplicate - return -1; - } - - // Search for the end of data - if (!sid_pal_mfg_store_search_for_tag(MFG_STORE_TLV_TAG_EMPTY, &tlv_info)) { - LOG_ERR("MFG storage is full"); - return -1; + if (length != SID_PAL_MFG_STORE_VERSION_SIZE) { + return -EINVAL; } - - uint16_t wr_length; - // The length sholud be a multiple of the program unit - uint16_t full_length = EXPAND_TO_MULTIPLE_WORD(length); - uintptr_t address = tlv_info.offset; - - // Check the remaining storage size - if (address + MFG_STORE_TLV_HEADER_SIZE + full_length > - nrf_mfg_store_region.addr_end) { - LOG_ERR("Not enough space to store: %d", value); - return -1; - } - - wr_array[0] = value >> 8; - wr_array[1] = value; - wr_array[2] = full_length >> 8; - wr_array[3] = full_length; - - ret_code = (int32_t)flash_write(flash_dev, address, wr_array, - MFG_STORE_TLV_HEADER_SIZE); - if (ret_code != 0) { - return ret_code; - } - address += MFG_STORE_TLV_HEADER_SIZE; - - while (full_length) { - wr_length = full_length > sizeof(wr_array) ? sizeof(wr_array) : full_length; - memset(wr_array, 0xFF, sizeof(wr_array)); - memcpy(wr_array, buffer, wr_length > length ? length : wr_length); - - ret_code = (int32_t)flash_write(flash_dev, address, wr_array, wr_length); - - if (ret_code != 0) { - return ret_code; - } - address += wr_length; - buffer += wr_length; - full_length -= wr_length; - }; - - return 0; - - } else { - if (length > sizeof(wr_array)) { - return (int32_t)SID_ERROR_OUT_OF_RESOURCES; - } - - if (length % sizeof(uint32_t)) { - LOG_WRN("Length is not word-aligned."); - return (int32_t)SID_ERROR_INCOMPATIBLE_PARAMS; - } - - const off_t value_offset = value_to_offset(value, nrf_mfg_store_region.addr_start, - nrf_mfg_store_region.addr_end); - - if (SID_PAL_MFG_STORE_INVALID_OFFSET == value_offset) { - return (int32_t)SID_ERROR_NOT_FOUND; - } - - if (NULL == buffer) { - return (int32_t)SID_ERROR_NULL_POINTER; - } - - memcpy(wr_array, buffer, length); - if (flash_dev) { - return (int32_t)flash_write(flash_dev, value_offset, wr_array, length); - } - - return (int32_t)SID_ERROR_UNINITIALIZED; + struct mfg_header mfg_header = { .magic_string = MFG_HEADER_MAGIC }; + memcpy(mfg_header.raw_version, buffer, SID_PAL_MFG_STORE_VERSION_SIZE); + return tlv_write_start_marker(&tlv_flash, (uint8_t *)&mfg_header, + sizeof(struct mfg_header)); } + +#if CONFIG_SIDEWALK_MFG_STORAGE_DIAGNOSTIC + return tlv_write(&tlv_flash, value, buffer, length); #else return (int32_t)SID_ERROR_NOSUPPORT; #endif @@ -434,162 +185,88 @@ int32_t sid_pal_mfg_store_write(uint16_t value, const uint8_t *buffer, uint16_t void sid_pal_mfg_store_read(uint16_t value, uint8_t *buffer, uint16_t length) { #ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE - switch (value) { - case SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519: - if (sid_crypto_keys_buffer_set(SID_CRYPTO_MFG_ED25519_PRIV_KEY_ID, buffer, length)) { - LOG_ERR("DEVICE_PRIV_ED25519 read fail"); - } - return; - case SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1: - if (sid_crypto_keys_buffer_set(SID_CRYPTO_MFG_SECP_256R1_PRIV_KEY_ID, buffer, length)) { - LOG_ERR("DEVICE_PRIV_P256R1 read fail"); - } + int err_sec = sid_mfg_storage_secure_read(&value, buffer, length); + if (err_sec != -ENOENT) { + LOG_DBG("secure read tag %d status %d", value, err_sec); return; - case SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519_RAW: - value = SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519; - break; - case SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1_RAW: - value = SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1; - break; } #endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */ - - uint32_t version = sid_pal_mfg_store_get_version(); - if (version == SID_PAL_MFG_STORE_TLV_VERSION) { - // The SID_PAL_MFG_STORE_VERSION we should read as fixed offset - if (value == SID_PAL_MFG_STORE_VERSION) { - memcpy(buffer, &version, sizeof(version)); - return; - } - - struct sid_pal_mfg_store_tlv_info tlv_info; - if (sid_pal_mfg_store_search_for_tag(value, &tlv_info)) { - if (length > tlv_info.length) { - LOG_ERR("invalid length of the value"); - return; - } - int rc = flash_read(flash_dev, tlv_info.offset + MFG_STORE_TLV_HEADER_SIZE, - buffer, length); - if (0 != rc) { - LOG_ERR("Flash read fail %d", rc); - return; - } - } else { - /* - * For backwards compatibility with MFG version with fixed offsets, - * we must fill the buffer with empty data. - */ - memset(buffer, 0xFF, length); - } - } else { - const off_t value_offset = value_to_offset((sid_pal_mfg_store_value_t)value, - nrf_mfg_store_region.addr_start, - nrf_mfg_store_region.addr_end); - - if (!buffer) { - LOG_ERR("Null pointer provided."); - return; - } - - if (SID_PAL_MFG_STORE_INVALID_OFFSET != value_offset) { - if (flash_dev) { - int rc = flash_read(flash_dev, value_offset, buffer, length); - if (0 != rc) { - LOG_ERR("Flash read fail %d", rc); - } - } else { - LOG_ERR("MFG store is not initialized."); - } - } + if (value == SID_PAL_MFG_STORE_VERSION) { + memcpy(buffer, (uint8_t[]){ 0, 0, 0, SID_PAL_MFG_STORE_TLV_VERSION }, + SID_PAL_MFG_STORE_VERSION_SIZE); + return; } -} - -static bool is_valid_value_offset(uint32_t offset) -{ - return offset != SID_PAL_MFG_STORE_INVALID_OFFSET; -} - -static uint16_t value_to_size(sid_pal_mfg_store_value_t value) -{ - const size_t table_count = sizeof(sid_pal_mfg_store_app_value_to_offset_table) / - sizeof(sid_pal_mfg_store_app_value_to_offset_table[0]); - - for (uint32_t i = 0; i < table_count; i++) { - if (value == sid_pal_mfg_store_app_value_to_offset_table[i].value) { - return is_valid_value_offset( - sid_pal_mfg_store_app_value_to_offset_table[i].offset) ? - sid_pal_mfg_store_app_value_to_offset_table[i].size : - 0; - } + int ret = tlv_read(&tlv_flash, value, buffer, length); + if (ret != 0) { + LOG_ERR("Failed to read tlv type %d with errno %d", value, ret); } - - // NOTE: Getting size for App values >= SID_PAL_MFG_STORE_CORE_VALUE_MAX is not supported - return 0; } uint16_t sid_pal_mfg_store_get_length_for_value(uint16_t value) { - uint16_t length = 0; - if (sid_pal_mfg_store_get_version() == SID_PAL_MFG_STORE_TLV_VERSION) { - struct sid_pal_mfg_store_tlv_info tlv_info; - if (sid_pal_mfg_store_search_for_tag(value, &tlv_info)) { - length = tlv_info.length; - } - } else { - length = value_to_size((sid_pal_mfg_store_value_t)value); + tlv_header header = {}; + + int ret = tlv_lookup(&tlv_flash, value, &header); + if (ret != 0) { + LOG_ERR("Failed to find value %d in MFG storage errno: %d", value, ret); + return 0; } - return length; + return header.payload_size.data_size; } int32_t sid_pal_mfg_store_erase(void) { -#if CONFIG_SIDEWALK_MFG_STORAGE_WRITE - const size_t mfg_size = nrf_mfg_store_region.addr_end - nrf_mfg_store_region.addr_start; +#if CONFIG_SIDEWALK_MFG_STORAGE_DIAGNOSTIC + const size_t mfg_size = tlv_flash.end_offset - tlv_flash.start_offset; if (flash_dev) { - return (int32_t)flash_erase(flash_dev, nrf_mfg_store_region.addr_start, mfg_size); + return (int32_t)flash_erase(flash_dev, tlv_flash.start_offset, mfg_size); } LOG_ERR("MFG store is not initialized"); return (int32_t)SID_ERROR_UNINITIALIZED; #else return (int32_t)SID_ERROR_NOSUPPORT; -#endif +#endif /* CONFIG_SIDEWALK_MFG_STORAGE_DIAGNOSTIC */ } bool sid_pal_mfg_store_is_empty(void) { -#if CONFIG_SIDEWALK_MFG_STORAGE_WRITE +#if CONFIG_SIDEWALK_MFG_STORAGE_DIAGNOSTIC + // read header, if failed to read magic, it is empty + uint8_t empty_flash_mem[FLASH_MEM_CHUNK]; uint8_t tmp_buff[FLASH_MEM_CHUNK]; size_t length = sizeof(tmp_buff); + int rc; + const struct flash_parameters *flash_params; - memset(empty_flash_mem, 0xFF, sizeof(empty_flash_mem)); + if (!flash_dev) { + LOG_ERR("No flash device to erase."); + return false; + } - if (flash_dev) { - int rc; - for (off_t offset = nrf_mfg_store_region.addr_start; - offset < nrf_mfg_store_region.addr_end; offset += length) { - if ((offset + length) > nrf_mfg_store_region.addr_end) { - length = nrf_mfg_store_region.addr_end - offset; - } - - rc = flash_read(flash_dev, offset, tmp_buff, length); - if (0 != rc) { - LOG_ERR("Read flash memory error: %d.", rc); - return false; - } - - if (0 != memcmp(empty_flash_mem, tmp_buff, length)) { - return false; - } + flash_params = flash_get_parameters(flash_dev); + memset(empty_flash_mem, flash_params->erase_value, sizeof(empty_flash_mem)); + for (off_t offset = tlv_flash.start_offset; offset < tlv_flash.end_offset; + offset += length) { + if ((offset + length) > tlv_flash.end_offset) { + length = tlv_flash.end_offset - offset; + } + + rc = flash_read(flash_dev, offset, tmp_buff, length); + if (0 != rc) { + LOG_ERR("Read flash memory error: %d.", rc); + return false; + } + + if (0 != memcmp(empty_flash_mem, tmp_buff, length)) { + return false; } - return true; - } else { - LOG_ERR("MFG store is not initialized."); } + return true; #else LOG_WRN("The sid_pal_mfg_store_is_empty function is not enabled."); -#endif return false; +#endif /* CONFIG_SIDEWALK_MFG_STORAGE_DIAGNOSTIC */ } bool sid_pal_mfg_store_is_tlv_support(void) @@ -599,101 +276,56 @@ bool sid_pal_mfg_store_is_tlv_support(void) uint32_t sid_pal_mfg_store_get_version(void) { - uint32_t version = 0; -#define MFG_VERSION_OFFSET_BYTES 4 - - if (flash_dev) { - int rc = flash_read(flash_dev, - nrf_mfg_store_region.addr_start + MFG_VERSION_OFFSET_BYTES, - (uint8_t *)&version, SID_PAL_MFG_STORE_VERSION_SIZE); - if (0 != rc) { - LOG_ERR("Flash read fail %d", rc); - } - } else { - LOG_ERR("MFG store is not initialized."); - } - - return sys_be32_to_cpu(version); + return sid_mfg_version; } +/* Functions specific to Sidewalk with special handling */ + bool sid_pal_mfg_store_dev_id_get(uint8_t dev_id[SID_PAL_MFG_STORE_DEVID_SIZE]) { - bool dev_id_found = false; - - if (dev_id) { - uint8_t unset_dev_id[SID_PAL_MFG_STORE_DEVID_SIZE]; - memset(unset_dev_id, 0xFF, SID_PAL_MFG_STORE_DEVID_SIZE); - memset(dev_id, 0xFF, SID_PAL_MFG_STORE_DEVID_SIZE); - sid_pal_mfg_store_read(SID_PAL_MFG_STORE_DEVID, dev_id, - SID_PAL_MFG_STORE_DEVID_SIZE); - - if (0 == memcmp(dev_id, unset_dev_id, SID_PAL_MFG_STORE_DEVID_SIZE)) { - uint32_t mcu_devid = DEV_ID_REG; - dev_id[0] = 0xBF; - mcu_devid = sys_cpu_to_be32(mcu_devid); - memcpy(&dev_id[1], &mcu_devid, sizeof(mcu_devid)); - } else { - const uint32_t version = sid_pal_mfg_store_get_version(); - if (MFG_VERSION_1_VAL == version || 0x1 == version) { - /** - * Correct dev_id for mfg version 1 - * For devices with mfg version 1, the device Id is stored as two words - * in network endian format. - * To read the device Id two words at SID_PAL_MFG_STORE_DEVID has to be - * read and each word needs to be changed to host endian format. - */ - uint8_t dev_id_buffer[MFG_WORD_SIZE_VER_1] = { 0 }; - sid_pal_mfg_store_read(SID_PAL_MFG_STORE_DEVID, dev_id_buffer, - sizeof(dev_id_buffer)); - ntoh_buff(dev_id_buffer, sizeof(dev_id_buffer)); - // Encode the size in the first 3 bits in MSB of the devId - dev_id_buffer[0] = (dev_id_buffer[0] & DEV_ID_MSB_MASK) | - ENCODED_DEV_ID_SIZE_5_BYTES_MASK; - memcpy(dev_id, dev_id_buffer, SID_PAL_MFG_STORE_DEVID_SIZE); - } - dev_id_found = true; - } - } - return dev_id_found; + uint32_t mcu_devid = DEV_ID_REG; + dev_id[0] = 0xBF; + mcu_devid = sys_cpu_to_be32(mcu_devid); + memcpy(&dev_id[1], &mcu_devid, sizeof(mcu_devid)); + return true; } bool sid_pal_mfg_store_serial_num_get(uint8_t serial_num[SID_PAL_MFG_STORE_SERIAL_NUM_SIZE]) { - uint8_t unset_serial_num[SID_PAL_MFG_STORE_SERIAL_NUM_SIZE]; - - if (!serial_num) { - return false; - } - - memset(unset_serial_num, 0xFF, SID_PAL_MFG_STORE_SERIAL_NUM_SIZE); - memset(serial_num, 0xFF, SID_PAL_MFG_STORE_SERIAL_NUM_SIZE); - sid_pal_mfg_store_read(SID_PAL_MFG_STORE_SERIAL_NUM, serial_num, - SID_PAL_MFG_STORE_SERIAL_NUM_SIZE); - - if (0 == memcmp(serial_num, unset_serial_num, SID_PAL_MFG_STORE_SERIAL_NUM_SIZE)) { - return false; - } - - const uint32_t version = sid_pal_mfg_store_get_version(); - - if (MFG_VERSION_1_VAL == version || 0x1 == version) { - ntoh_buff(serial_num, SID_PAL_MFG_STORE_SERIAL_NUM_SIZE); - } - return true; + int ret = tlv_read(&tlv_flash, SID_PAL_MFG_STORE_SERIAL_NUM, serial_num, + SID_PAL_MFG_STORE_SERIAL_NUM_SIZE); + return ret == 0; } -static const uint8_t product_apid[] = { 0x76, 0x43, 0x74, 0x32 }; -static const uint8_t app_server_public_key[] = { 0xb2, 0x40, 0xbf, 0x98, 0xc6, 0x5c, 0xdf, 0x84, - 0xbf, 0x2a, 0xa1, 0xac, 0x29, 0x11, 0x14, 0x1f, - 0xb4, 0x80, 0x7c, 0xbc, 0xb6, 0x6e, 0xcf, 0x09, - 0x1c, 0x20, 0x04, 0xb3, 0x37, 0xb4, 0x06, 0x47 }; - void sid_pal_mfg_store_apid_get(uint8_t apid[SID_PAL_MFG_STORE_APID_SIZE]) { - memcpy(apid, product_apid, sizeof(product_apid)); + sid_pal_mfg_store_read(SID_PAL_MFG_STORE_APID, apid, SID_PAL_MFG_STORE_APID_SIZE); } void sid_pal_mfg_store_app_pub_key_get(uint8_t app_pub[SID_PAL_MFG_STORE_APP_PUB_ED25519_SIZE]) { - memcpy(app_pub, app_server_public_key, sizeof(app_server_public_key)); + sid_pal_mfg_store_read(SID_PAL_MFG_STORE_APP_PUB_ED25519, app_pub, + SID_PAL_MFG_STORE_APP_PUB_ED25519_SIZE); +} + +#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE +#define SID_PAL_MFG_STORE_PRIV_KEY_SIZE (32) + +static int sid_mfg_storage_secure_read(uint16_t *p_value, uint8_t *buffer, uint16_t length) +{ + int err = -ENOENT; + switch (*p_value) { + case SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519: + err = sid_crypto_keys_buffer_set(SID_CRYPTO_MFG_ED25519_PRIV_KEY_ID, buffer, + length); + break; + case SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1: + err = sid_crypto_keys_buffer_set(SID_CRYPTO_MFG_SECP_256R1_PRIV_KEY_ID, buffer, + length); + break; + } + + return err; } + +#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */ diff --git a/subsys/sal/sid_pal/src/sid_mfg_storage_deprecated.c b/subsys/sal/sid_pal/src/sid_mfg_storage_deprecated.c new file mode 100644 index 0000000000..588ace23b3 --- /dev/null +++ b/subsys/sal/sid_pal/src/sid_mfg_storage_deprecated.c @@ -0,0 +1,699 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/** @file sid_mfg_storage.c + * @brief Sidewalk MFG storage. + */ + +#include +#include +#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE +#include +#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(sid_mfg, CONFIG_SIDEWALK_LOG_LEVEL); + +// Manufacturing version define +#define MFG_VERSION_1_VAL 0x01000000 +#define MFG_VERSION_2_VAL 0x2 + +#define FLASH_MEM_CHUNK (128) + +#ifndef DEV_ID_REG +#if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(NRF52832_XXAA) +#define DEV_ID_REG (uint32_t)(NRF_FICR->DEVICEID[0]) +#elif defined(NRF5340_XXAA) +#if defined(NRF_APPLICATION) +#define DEV_ID_REG (uint32_t)(NRF_FICR_S->INFO.DEVICEID[0]) +#elif defined(NRF_NETWORK) +#define DEV_ID_REG (uint32_t)(NRF_FICR_NS->INFO.DEVICEID[0]) +#endif /* NRF5340_XXAA */ +#elif defined(NRF54L15_ENGA_XXAA) +#define DEV_ID_REG (uint32_t)(NRF_FICR->INFO.DEVICEID[0]) +#else +#error "Unknow Device ID register." +#endif +#endif /* DEV_ID_REG */ + +// DEV_ID masks +#define ENCODED_DEV_ID_SIZE_5_BYTES_MASK 0xA0 +#define DEV_ID_MSB_MASK 0x1F + +#define MFG_WORD_SIZE_VER_1 (8) + +static const uint32_t MFG_WORD_SIZE = 4; // in bytes + +#define MFG_STORE_TLV_HEADER_SIZE 4 +#define MFG_STORE_TLV_TAG_EMPTY 0xFFFF +#define EXPAND_TO_MULTIPLE_WORD(_VALUE_) (((_VALUE_ + 3) / 4) * 4) + +#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE +#define SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519_RAW (100) +#define SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1_RAW (101) +#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */ + +struct sid_pal_mfg_store_tlv_info { + uint16_t tag; + uint16_t length; + /** TLV offset from mfg_store_region.addr_start in bytes */ + size_t offset; +}; + +struct sid_pal_mfg_store_value_to_address_offset { + sid_pal_mfg_store_value_t value; + uint16_t size; + uint32_t offset; +}; + +static void ntoh_buff(uint8_t *buffer, size_t buff_len); +static uint32_t default_app_value_to_offset(int value); +static off_t checked_addr_return(off_t offset, uintptr_t start_address, uintptr_t end_address); +static off_t value_to_offset(sid_pal_mfg_store_value_t value, uintptr_t start_address, + uintptr_t end_address); + +// clang-format off +struct sid_pal_mfg_store_value_to_address_offset sid_pal_mfg_store_app_value_to_offset_table[] = { + {SID_PAL_MFG_STORE_VERSION, SID_PAL_MFG_STORE_VERSION_SIZE, SID_PAL_MFG_STORE_OFFSET_VERSION}, + {SID_PAL_MFG_STORE_DEVID, SID_PAL_MFG_STORE_DEVID_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVID}, + {SID_PAL_MFG_STORE_SERIAL_NUM, SID_PAL_MFG_STORE_SERIAL_NUM_SIZE, SID_PAL_MFG_STORE_OFFSET_SERIAL_NUM}, + {SID_PAL_MFG_STORE_SMSN, SID_PAL_MFG_STORE_SMSN_SIZE, SID_PAL_MFG_STORE_OFFSET_SMSN}, + {SID_PAL_MFG_STORE_APID, SID_PAL_MFG_STORE_APID_SIZE, SID_PAL_MFG_STORE_OFFSET_APID}, + {SID_PAL_MFG_STORE_APP_PUB_ED25519, SID_PAL_MFG_STORE_APP_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_APP_PUB_ED25519}, + {SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519, SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVICE_PRIV_ED25519}, + {SID_PAL_MFG_STORE_DEVICE_PUB_ED25519, SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_ED25519}, + {SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_SIGNATURE, SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_ED25519_SIGNATURE}, + {SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1, SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVICE_PRIV_P256R1}, + {SID_PAL_MFG_STORE_DEVICE_PUB_P256R1, SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_P256R1}, + {SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_SIGNATURE, SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_P256R1_SIGNATURE}, + {SID_PAL_MFG_STORE_DAK_PUB_ED25519, SID_PAL_MFG_STORE_DAK_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_DAK_PUB_ED25519}, + {SID_PAL_MFG_STORE_DAK_PUB_ED25519_SIGNATURE, SID_PAL_MFG_STORE_DAK_PUB_ED25519_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_DAK_PUB_ED25519_SIGNATURE}, + {SID_PAL_MFG_STORE_DAK_ED25519_SERIAL, SID_PAL_MFG_STORE_DAK_ED25519_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_DAK_ED25519_SERIAL}, + {SID_PAL_MFG_STORE_DAK_PUB_P256R1, SID_PAL_MFG_STORE_DAK_PUB_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_DAK_PUB_P256R1}, + {SID_PAL_MFG_STORE_DAK_PUB_P256R1_SIGNATURE, SID_PAL_MFG_STORE_DAK_PUB_P256R1_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_DAK_PUB_P256R1_SIGNATURE}, + {SID_PAL_MFG_STORE_DAK_P256R1_SERIAL, SID_PAL_MFG_STORE_DAK_P256R1_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_DAK_P256R1_SERIAL}, + {SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519, SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_ED25519}, + {SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_SIGNATURE,SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_SIGNATURE_SIZE,SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_ED25519_SIGNATURE}, + {SID_PAL_MFG_STORE_PRODUCT_ED25519_SERIAL, SID_PAL_MFG_STORE_PRODUCT_ED25519_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_PRODUCT_ED25519_SERIAL}, + {SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1, SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_P256R1}, + {SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_SIGNATURE, SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_P256R1_SIGNATURE}, + {SID_PAL_MFG_STORE_PRODUCT_P256R1_SERIAL, SID_PAL_MFG_STORE_PRODUCT_P256R1_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_PRODUCT_P256R1_SERIAL}, + {SID_PAL_MFG_STORE_MAN_PUB_ED25519, SID_PAL_MFG_STORE_MAN_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_MAN_PUB_ED25519}, + {SID_PAL_MFG_STORE_MAN_PUB_ED25519_SIGNATURE, SID_PAL_MFG_STORE_MAN_PUB_ED25519_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_MAN_PUB_ED25519_SIGNATURE}, + {SID_PAL_MFG_STORE_MAN_ED25519_SERIAL, SID_PAL_MFG_STORE_MAN_ED25519_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_MAN_ED25519_SERIAL}, + {SID_PAL_MFG_STORE_MAN_PUB_P256R1, SID_PAL_MFG_STORE_MAN_PUB_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_MAN_PUB_P256R1}, + {SID_PAL_MFG_STORE_MAN_PUB_P256R1_SIGNATURE, SID_PAL_MFG_STORE_MAN_PUB_P256R1_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_MAN_PUB_P256R1_SIGNATURE}, + {SID_PAL_MFG_STORE_MAN_P256R1_SERIAL, SID_PAL_MFG_STORE_MAN_P256R1_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_MAN_P256R1_SERIAL}, + {SID_PAL_MFG_STORE_SW_PUB_ED25519, SID_PAL_MFG_STORE_SW_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_SW_PUB_ED25519}, + {SID_PAL_MFG_STORE_SW_PUB_ED25519_SIGNATURE, SID_PAL_MFG_STORE_SW_PUB_ED25519_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_SW_PUB_ED25519_SIGNATURE}, + {SID_PAL_MFG_STORE_SW_ED25519_SERIAL, SID_PAL_MFG_STORE_SW_ED25519_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_SW_ED25519_SERIAL}, + {SID_PAL_MFG_STORE_SW_PUB_P256R1, SID_PAL_MFG_STORE_SW_PUB_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_SW_PUB_P256R1}, + {SID_PAL_MFG_STORE_SW_PUB_P256R1_SIGNATURE, SID_PAL_MFG_STORE_SW_PUB_P256R1_SIGNATURE_SIZE, SID_PAL_MFG_STORE_OFFSET_SW_PUB_P256R1_SIGNATURE}, + {SID_PAL_MFG_STORE_SW_P256R1_SERIAL, SID_PAL_MFG_STORE_SW_P256R1_SERIAL_SIZE, SID_PAL_MFG_STORE_OFFSET_SW_P256R1_SERIAL}, + {SID_PAL_MFG_STORE_AMZN_PUB_ED25519, SID_PAL_MFG_STORE_AMZN_PUB_ED25519_SIZE, SID_PAL_MFG_STORE_OFFSET_AMZN_PUB_ED25519}, + {SID_PAL_MFG_STORE_AMZN_PUB_P256R1, SID_PAL_MFG_STORE_AMZN_PUB_P256R1_SIZE, SID_PAL_MFG_STORE_OFFSET_AMZN_PUB_P256R1}, +}; +// clang-format on + +static sid_pal_mfg_store_region_t nrf_mfg_store_region = { + .app_value_to_offset = default_app_value_to_offset, +}; + +static const struct device *flash_dev; + +static bool sid_pal_mfg_store_search_for_tag(uint16_t tag, + struct sid_pal_mfg_store_tlv_info *tlv_info) +{ + off_t address = (off_t)(nrf_mfg_store_region.addr_start + + SID_PAL_MFG_STORE_OFFSET_VERSION * MFG_WORD_SIZE + + SID_PAL_MFG_STORE_VERSION_SIZE); + + uint16_t current_tag, length; + uint8_t type_length_raw[MFG_STORE_TLV_HEADER_SIZE] = { 0 }; + + while (1) { + int rc = flash_read(flash_dev, address, type_length_raw, MFG_STORE_TLV_HEADER_SIZE); + if (0 != rc) { + LOG_ERR("Flash read fail %d", rc); + return false; + } + current_tag = (type_length_raw[0] << 8) + type_length_raw[1]; + length = (type_length_raw[2] << 8) + type_length_raw[3]; + + if (current_tag == tag) { + tlv_info->tag = tag; + tlv_info->length = length; + tlv_info->offset = address; + return true; + } else { + if (current_tag == MFG_STORE_TLV_TAG_EMPTY) { + break; + } + /* + * Go to the next TLV. + * Since data is written to flash with data aligned to 4, we must take this + * into account if the data length is not a multiple of 4. + */ + address += (MFG_STORE_TLV_HEADER_SIZE + EXPAND_TO_MULTIPLE_WORD(length)); + // Check that we have not reached the end of the storage + if ((uintptr_t)(address + MFG_STORE_TLV_HEADER_SIZE + MFG_WORD_SIZE) > + nrf_mfg_store_region.addr_end) { + break; + } + } + } + return false; +} + +/** + * @brief The function converts network byte order to host byte order on the whole buffer. + * + * @param buffer - input/output buffer. + * @param buff_len - number of bytes in buffer. + */ +static void ntoh_buff(uint8_t *buffer, size_t buff_len) +{ + uint32_t val_l = 0; + size_t i = 0; + size_t mod_len = buff_len % sizeof(uint32_t); + + if (sizeof(uint32_t) <= buff_len) { + for (i = 0; i < (buff_len - mod_len); i += sizeof(uint32_t)) { + memcpy(&val_l, &buffer[i], sizeof(val_l)); + val_l = sys_be32_to_cpu(val_l); + memcpy(&buffer[i], &val_l, sizeof(val_l)); + } + } + + if (2 == mod_len) { + uint16_t val_s = 0; + memcpy(&val_s, &buffer[i], sizeof(val_s)); + val_s = sys_be16_to_cpu(val_s); + memcpy(&buffer[i], &val_s, sizeof(val_s)); + } else if (3 == mod_len) { + val_l = 0; + memcpy(&val_l, &buffer[i], 3 * sizeof(uint8_t)); + val_l = sys_be24_to_cpu(val_l); + memcpy(&buffer[i], &val_l, 3 * sizeof(uint8_t)); + } +} + +/** + * @brief The 'dummy' function used when application doesn't provide it's own + * implementation for this function. + * + * @param value - unused argument. + * @return SID_PAL_MFG_STORE_INVALID_OFFSET + */ +static uint32_t default_app_value_to_offset(int value) +{ + ARG_UNUSED(value); + LOG_WRN("No support for app_value_to_offset."); + return SID_PAL_MFG_STORE_INVALID_OFFSET; +} + +/** + * @brief The function checks if offset is in address range of the manufacturing store partition. + * + * @param offset - memory offset. + * @param start_address - mfg partition start address. + * @param end_address - mfg partition end address. + * @return Offset in physical flash memory or SID_PAL_MFG_STORE_INVALID_OFFSET when offest is out + * of manufacturing storage address range. + */ +static off_t checked_addr_return(off_t offset, uintptr_t start_address, uintptr_t end_address) +{ + if (start_address + offset >= end_address) { + LOG_ERR("Offset past manufacturing store end: %d.", (int)offset); + return SID_PAL_MFG_STORE_INVALID_OFFSET; + } + return (off_t)(start_address + offset); +} + +/** + * @brief The function calculates memory offset for desired value. + * + * @param value - Enum constant for the desired value. + * @param start_address - mfg partition start address. + * @param end_address - mfg partition end address. + * @return Offset in physical flash memory when success otherwise SID_PAL_MFG_STORE_INVALID_OFFSET. + */ +static off_t value_to_offset(sid_pal_mfg_store_value_t value, uintptr_t start_address, + uintptr_t end_address) +{ + const size_t table_count = ARRAY_SIZE(sid_pal_mfg_store_app_value_to_offset_table); + + for (uint32_t i = 0; i < table_count; i++) { + if (value == sid_pal_mfg_store_app_value_to_offset_table[i].value) { + const off_t offset = sid_pal_mfg_store_app_value_to_offset_table[i].offset; + return (off_t)((SID_PAL_MFG_STORE_INVALID_OFFSET != offset) ? + (start_address + (offset << 2)) : + SID_PAL_MFG_STORE_INVALID_OFFSET); + } + } + + if (value < 0 || value >= SID_PAL_MFG_STORE_CORE_VALUE_MAX) { + // This is not a core value. Search for this value among those provided by the application. + off_t custom_offset = nrf_mfg_store_region.app_value_to_offset(value); + if (SID_PAL_MFG_STORE_INVALID_OFFSET != custom_offset) { + return checked_addr_return(custom_offset, start_address, end_address); + } + } + + LOG_ERR("No Nordic manufacturing store offset for: %d.", value); + return SID_PAL_MFG_STORE_INVALID_OFFSET; +} + +void sid_pal_mfg_store_init(sid_pal_mfg_store_region_t mfg_store_region) +{ + nrf_mfg_store_region = mfg_store_region; + + if (!nrf_mfg_store_region.app_value_to_offset) { + nrf_mfg_store_region.app_value_to_offset = default_app_value_to_offset; + } + + flash_dev = DEVICE_DT_GET_OR_NULL(DT_CHOSEN(zephyr_flash_controller)); + if (!flash_dev) { + LOG_ERR("Flash device is not found."); + } + +#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE + int rc = 0; + uint8_t raw_key[32]; + uint8_t zeros[32] = { 0 }; + + sid_pal_mfg_store_read(SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519_RAW, raw_key, sizeof(raw_key)); + if (0 != memcmp(raw_key, zeros, sizeof(raw_key))) { + rc = sid_crypto_keys_new_import(SID_CRYPTO_MFG_ED25519_PRIV_KEY_ID, raw_key, + sizeof(raw_key)); + LOG_INF("MFG_ED25519 import %s", (0 == rc) ? "success" : "failure"); + memset(raw_key, 0, sizeof(raw_key)); + rc = sid_pal_mfg_store_write(SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519_RAW, raw_key, + sizeof(raw_key)); + LOG_INF("MFG_ED25519 overwrite status %d", rc); + } + + sid_pal_mfg_store_read(SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1_RAW, raw_key, sizeof(raw_key)); + if (0 != memcmp(raw_key, zeros, sizeof(raw_key))) { + rc = sid_crypto_keys_new_import(SID_CRYPTO_MFG_SECP_256R1_PRIV_KEY_ID, raw_key, + sizeof(raw_key)); + LOG_INF("MFG_SECP_256R1 import %s", (0 == rc) ? "success" : "failure"); + memset(raw_key, 0, sizeof(raw_key)); + rc = sid_pal_mfg_store_write(SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1_RAW, raw_key, + sizeof(raw_key)); + LOG_INF("MFG_SECP_256R1 overwrite status %d", rc); + } + +#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */ +} + +void sid_pal_mfg_store_deinit(void) +{ + memset(&nrf_mfg_store_region, 0, sizeof(sid_pal_mfg_store_region_t)); +} + +int32_t sid_pal_mfg_store_write(uint16_t value, const uint8_t *buffer, uint16_t length) +{ +#if CONFIG_SIDEWALK_MFG_STORAGE_WRITE + uint32_t ret_code = 0; + uint8_t __aligned(4) wr_array[SID_PAL_MFG_STORE_MAX_FLASH_WRITE_LEN]; + + if (length == 0 || value == MFG_STORE_TLV_TAG_EMPTY || buffer == NULL) { + return (int32_t)SID_ERROR_INVALID_ARGS; + } + + uint32_t version = sid_pal_mfg_store_get_version(); + if (value == SID_PAL_MFG_STORE_VERSION) { + version = SID_PAL_MFG_STORE_VERSION; + } + if (version == SID_PAL_MFG_STORE_TLV_VERSION) { + struct sid_pal_mfg_store_tlv_info tlv_info = {}; + + if (sid_pal_mfg_store_search_for_tag(value, &tlv_info)) { + // The tag value already exists. We can't write duplicate + return -1; + } + + // Search for the end of data + if (!sid_pal_mfg_store_search_for_tag(MFG_STORE_TLV_TAG_EMPTY, &tlv_info)) { + LOG_ERR("MFG storage is full"); + return -1; + } + + uint16_t wr_length; + // The length sholud be a multiple of the program unit + uint16_t full_length = EXPAND_TO_MULTIPLE_WORD(length); + uintptr_t address = tlv_info.offset; + + // Check the remaining storage size + if (address + MFG_STORE_TLV_HEADER_SIZE + full_length > + nrf_mfg_store_region.addr_end) { + LOG_ERR("Not enough space to store: %d", value); + return -1; + } + + wr_array[0] = value >> 8; + wr_array[1] = value; + wr_array[2] = full_length >> 8; + wr_array[3] = full_length; + + ret_code = (int32_t)flash_write(flash_dev, address, wr_array, + MFG_STORE_TLV_HEADER_SIZE); + if (ret_code != 0) { + return ret_code; + } + address += MFG_STORE_TLV_HEADER_SIZE; + + while (full_length) { + wr_length = full_length > sizeof(wr_array) ? sizeof(wr_array) : full_length; + memset(wr_array, 0xFF, sizeof(wr_array)); + memcpy(wr_array, buffer, wr_length > length ? length : wr_length); + + ret_code = (int32_t)flash_write(flash_dev, address, wr_array, wr_length); + + if (ret_code != 0) { + return ret_code; + } + address += wr_length; + buffer += wr_length; + full_length -= wr_length; + }; + + return 0; + + } else { + if (length > sizeof(wr_array)) { + return (int32_t)SID_ERROR_OUT_OF_RESOURCES; + } + + if (length % sizeof(uint32_t)) { + LOG_WRN("Length is not word-aligned."); + return (int32_t)SID_ERROR_INCOMPATIBLE_PARAMS; + } + + const off_t value_offset = value_to_offset(value, nrf_mfg_store_region.addr_start, + nrf_mfg_store_region.addr_end); + + if (SID_PAL_MFG_STORE_INVALID_OFFSET == value_offset) { + return (int32_t)SID_ERROR_NOT_FOUND; + } + + if (NULL == buffer) { + return (int32_t)SID_ERROR_NULL_POINTER; + } + + memcpy(wr_array, buffer, length); + if (flash_dev) { + return (int32_t)flash_write(flash_dev, value_offset, wr_array, length); + } + + return (int32_t)SID_ERROR_UNINITIALIZED; + } +#else + return (int32_t)SID_ERROR_NOSUPPORT; +#endif +} + +void sid_pal_mfg_store_read(uint16_t value, uint8_t *buffer, uint16_t length) +{ +#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE + switch (value) { + case SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519: + if (sid_crypto_keys_buffer_set(SID_CRYPTO_MFG_ED25519_PRIV_KEY_ID, buffer, + length)) { + LOG_ERR("DEVICE_PRIV_ED25519 read fail"); + } + return; + case SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1: + if (sid_crypto_keys_buffer_set(SID_CRYPTO_MFG_SECP_256R1_PRIV_KEY_ID, buffer, + length)) { + LOG_ERR("DEVICE_PRIV_P256R1 read fail"); + } + return; + case SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519_RAW: + value = SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519; + break; + case SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1_RAW: + value = SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1; + break; + } +#endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */ + + uint32_t version = sid_pal_mfg_store_get_version(); + if (version == SID_PAL_MFG_STORE_TLV_VERSION) { + // The SID_PAL_MFG_STORE_VERSION we should read as fixed offset + if (value == SID_PAL_MFG_STORE_VERSION) { + memcpy(buffer, &version, sizeof(version)); + return; + } + + struct sid_pal_mfg_store_tlv_info tlv_info; + if (sid_pal_mfg_store_search_for_tag(value, &tlv_info)) { + if (length > tlv_info.length) { + LOG_ERR("invalid length of the value"); + return; + } + int rc = flash_read(flash_dev, tlv_info.offset + MFG_STORE_TLV_HEADER_SIZE, + buffer, length); + if (0 != rc) { + LOG_ERR("Flash read fail %d", rc); + return; + } + } else { + /* + * For backwards compatibility with MFG version with fixed offsets, + * we must fill the buffer with empty data. + */ + memset(buffer, 0xFF, length); + } + } else { + const off_t value_offset = value_to_offset((sid_pal_mfg_store_value_t)value, + nrf_mfg_store_region.addr_start, + nrf_mfg_store_region.addr_end); + + if (!buffer) { + LOG_ERR("Null pointer provided."); + return; + } + + if (SID_PAL_MFG_STORE_INVALID_OFFSET != value_offset) { + if (flash_dev) { + int rc = flash_read(flash_dev, value_offset, buffer, length); + if (0 != rc) { + LOG_ERR("Flash read fail %d", rc); + } + } else { + LOG_ERR("MFG store is not initialized."); + } + } + } +} + +static bool is_valid_value_offset(uint32_t offset) +{ + return offset != SID_PAL_MFG_STORE_INVALID_OFFSET; +} + +static uint16_t value_to_size(sid_pal_mfg_store_value_t value) +{ + const size_t table_count = sizeof(sid_pal_mfg_store_app_value_to_offset_table) / + sizeof(sid_pal_mfg_store_app_value_to_offset_table[0]); + + for (uint32_t i = 0; i < table_count; i++) { + if (value == sid_pal_mfg_store_app_value_to_offset_table[i].value) { + return is_valid_value_offset( + sid_pal_mfg_store_app_value_to_offset_table[i].offset) ? + sid_pal_mfg_store_app_value_to_offset_table[i].size : + 0; + } + } + + // NOTE: Getting size for App values >= SID_PAL_MFG_STORE_CORE_VALUE_MAX is not supported + return 0; +} + +uint16_t sid_pal_mfg_store_get_length_for_value(uint16_t value) +{ + uint16_t length = 0; + if (sid_pal_mfg_store_get_version() == SID_PAL_MFG_STORE_TLV_VERSION) { + struct sid_pal_mfg_store_tlv_info tlv_info; + if (sid_pal_mfg_store_search_for_tag(value, &tlv_info)) { + length = tlv_info.length; + } + } else { + length = value_to_size((sid_pal_mfg_store_value_t)value); + } + return length; +} + +int32_t sid_pal_mfg_store_erase(void) +{ +#if CONFIG_SIDEWALK_MFG_STORAGE_WRITE + const size_t mfg_size = nrf_mfg_store_region.addr_end - nrf_mfg_store_region.addr_start; + if (flash_dev) { + return (int32_t)flash_erase(flash_dev, nrf_mfg_store_region.addr_start, mfg_size); + } + LOG_ERR("MFG store is not initialized"); + return (int32_t)SID_ERROR_UNINITIALIZED; +#else + return (int32_t)SID_ERROR_NOSUPPORT; +#endif +} + +bool sid_pal_mfg_store_is_empty(void) +{ +#if CONFIG_SIDEWALK_MFG_STORAGE_WRITE + uint8_t empty_flash_mem[FLASH_MEM_CHUNK]; + uint8_t tmp_buff[FLASH_MEM_CHUNK]; + size_t length = sizeof(tmp_buff); + + memset(empty_flash_mem, 0xFF, sizeof(empty_flash_mem)); + + if (flash_dev) { + int rc; + for (off_t offset = nrf_mfg_store_region.addr_start; + offset < nrf_mfg_store_region.addr_end; offset += length) { + if ((offset + length) > nrf_mfg_store_region.addr_end) { + length = nrf_mfg_store_region.addr_end - offset; + } + + rc = flash_read(flash_dev, offset, tmp_buff, length); + if (0 != rc) { + LOG_ERR("Read flash memory error: %d.", rc); + return false; + } + + if (0 != memcmp(empty_flash_mem, tmp_buff, length)) { + return false; + } + } + return true; + } else { + LOG_ERR("MFG store is not initialized."); + } +#else + LOG_WRN("The sid_pal_mfg_store_is_empty function is not enabled."); +#endif + return false; +} + +bool sid_pal_mfg_store_is_tlv_support(void) +{ + return true; +} + +uint32_t sid_pal_mfg_store_get_version(void) +{ + uint32_t version = 0; +#define MFG_VERSION_OFFSET_BYTES 4 + + if (flash_dev) { + int rc = flash_read(flash_dev, + nrf_mfg_store_region.addr_start + MFG_VERSION_OFFSET_BYTES, + (uint8_t *)&version, SID_PAL_MFG_STORE_VERSION_SIZE); + if (0 != rc) { + LOG_ERR("Flash read fail %d", rc); + } + } else { + LOG_ERR("MFG store is not initialized."); + } + + return sys_be32_to_cpu(version); +} + +bool sid_pal_mfg_store_dev_id_get(uint8_t dev_id[SID_PAL_MFG_STORE_DEVID_SIZE]) +{ + bool dev_id_found = false; + + if (dev_id) { + uint8_t unset_dev_id[SID_PAL_MFG_STORE_DEVID_SIZE]; + memset(unset_dev_id, 0xFF, SID_PAL_MFG_STORE_DEVID_SIZE); + memset(dev_id, 0xFF, SID_PAL_MFG_STORE_DEVID_SIZE); + sid_pal_mfg_store_read(SID_PAL_MFG_STORE_DEVID, dev_id, + SID_PAL_MFG_STORE_DEVID_SIZE); + + if (0 == memcmp(dev_id, unset_dev_id, SID_PAL_MFG_STORE_DEVID_SIZE)) { + uint32_t mcu_devid = DEV_ID_REG; + dev_id[0] = 0xBF; + mcu_devid = sys_cpu_to_be32(mcu_devid); + memcpy(&dev_id[1], &mcu_devid, sizeof(mcu_devid)); + } else { + const uint32_t version = sid_pal_mfg_store_get_version(); + if (MFG_VERSION_1_VAL == version || 0x1 == version) { + /** + * Correct dev_id for mfg version 1 + * For devices with mfg version 1, the device Id is stored as two words + * in network endian format. + * To read the device Id two words at SID_PAL_MFG_STORE_DEVID has to be + * read and each word needs to be changed to host endian format. + */ + uint8_t dev_id_buffer[MFG_WORD_SIZE_VER_1] = { 0 }; + sid_pal_mfg_store_read(SID_PAL_MFG_STORE_DEVID, dev_id_buffer, + sizeof(dev_id_buffer)); + ntoh_buff(dev_id_buffer, sizeof(dev_id_buffer)); + // Encode the size in the first 3 bits in MSB of the devId + dev_id_buffer[0] = (dev_id_buffer[0] & DEV_ID_MSB_MASK) | + ENCODED_DEV_ID_SIZE_5_BYTES_MASK; + memcpy(dev_id, dev_id_buffer, SID_PAL_MFG_STORE_DEVID_SIZE); + } + dev_id_found = true; + } + } + return dev_id_found; +} + +bool sid_pal_mfg_store_serial_num_get(uint8_t serial_num[SID_PAL_MFG_STORE_SERIAL_NUM_SIZE]) +{ + uint8_t unset_serial_num[SID_PAL_MFG_STORE_SERIAL_NUM_SIZE]; + + if (!serial_num) { + return false; + } + + memset(unset_serial_num, 0xFF, SID_PAL_MFG_STORE_SERIAL_NUM_SIZE); + memset(serial_num, 0xFF, SID_PAL_MFG_STORE_SERIAL_NUM_SIZE); + sid_pal_mfg_store_read(SID_PAL_MFG_STORE_SERIAL_NUM, serial_num, + SID_PAL_MFG_STORE_SERIAL_NUM_SIZE); + + if (0 == memcmp(serial_num, unset_serial_num, SID_PAL_MFG_STORE_SERIAL_NUM_SIZE)) { + return false; + } + + const uint32_t version = sid_pal_mfg_store_get_version(); + + if (MFG_VERSION_1_VAL == version || 0x1 == version) { + ntoh_buff(serial_num, SID_PAL_MFG_STORE_SERIAL_NUM_SIZE); + } + return true; +} + +static const uint8_t product_apid[] = { 0x76, 0x43, 0x74, 0x32 }; +static const uint8_t app_server_public_key[] = { 0xb2, 0x40, 0xbf, 0x98, 0xc6, 0x5c, 0xdf, 0x84, + 0xbf, 0x2a, 0xa1, 0xac, 0x29, 0x11, 0x14, 0x1f, + 0xb4, 0x80, 0x7c, 0xbc, 0xb6, 0x6e, 0xcf, 0x09, + 0x1c, 0x20, 0x04, 0xb3, 0x37, 0xb4, 0x06, 0x47 }; + +void sid_pal_mfg_store_apid_get(uint8_t apid[SID_PAL_MFG_STORE_APID_SIZE]) +{ + memcpy(apid, product_apid, sizeof(product_apid)); +} + +void sid_pal_mfg_store_app_pub_key_get(uint8_t app_pub[SID_PAL_MFG_STORE_APP_PUB_ED25519_SIZE]) +{ + memcpy(app_pub, app_server_public_key, sizeof(app_server_public_key)); +} diff --git a/tests/functional/mfg_storage/Kconfig b/tests/functional/mfg_storage/Kconfig index 195a7409f3..38fc7cd78e 100644 --- a/tests/functional/mfg_storage/Kconfig +++ b/tests/functional/mfg_storage/Kconfig @@ -16,7 +16,7 @@ config SIDEWALK_LOG_LEVEL config SHELL default y -config SIDEWALK_MFG_STORAGE_WRITE +config SIDEWALK_MFG_STORAGE_DIAGNOSTIC default y source "Kconfig.zephyr" diff --git a/tests/functional/mfg_storage/testcase.yaml b/tests/functional/mfg_storage/testcase.yaml index a23672385b..b2607efd94 100644 --- a/tests/functional/mfg_storage/testcase.yaml +++ b/tests/functional/mfg_storage/testcase.yaml @@ -8,3 +8,15 @@ tests: - nrf52840dk/nrf52840 - nrf5340dk/nrf5340/cpuapp - nrf54l15pdk/nrf54l15/cpuapp + + sidewalk.functional.mfg_storage_deprecated: + skip: true + sysbuild: true + tags: Sidewalk + platform_allow: nrf52840dk/nrf52840 nrf5340dk/nrf5340/cpuapp nrf54l15pdk/nrf54l15/cpuapp + integration_platforms: + - nrf52840dk/nrf52840 + - nrf5340dk/nrf5340/cpuapp + - nrf54l15pdk/nrf54l15/cpuapp + extra_configs: + - CONFIG_DEPRECATED_SIDEWALK_MFG_STORAGE=y diff --git a/tests/manual/ble/Kconfig b/tests/manual/ble/Kconfig index 2cb4452150..b08e2ec018 100644 --- a/tests/manual/ble/Kconfig +++ b/tests/manual/ble/Kconfig @@ -4,4 +4,7 @@ # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # +config SIDEWALK_MFG_STORAGE + default n + source "Kconfig.zephyr" diff --git a/tests/manual/ble/sysbuild.conf b/tests/manual/ble/sysbuild.conf index 7e6d419a0f..69eac613d0 100644 --- a/tests/manual/ble/sysbuild.conf +++ b/tests/manual/ble/sysbuild.conf @@ -4,4 +4,4 @@ # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # -SB_CONFIG_PARTITION_MANAGER=n +SB_CONFIG_PARTITION_MANAGER=y diff --git a/tests/manual/log/Kconfig b/tests/manual/log/Kconfig index 2cb4452150..b08e2ec018 100644 --- a/tests/manual/log/Kconfig +++ b/tests/manual/log/Kconfig @@ -4,4 +4,7 @@ # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # +config SIDEWALK_MFG_STORAGE + default n + source "Kconfig.zephyr" diff --git a/tests/manual/log/sysbuild.conf b/tests/manual/log/sysbuild.conf index 7e6d419a0f..69eac613d0 100644 --- a/tests/manual/log/sysbuild.conf +++ b/tests/manual/log/sysbuild.conf @@ -4,4 +4,4 @@ # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # -SB_CONFIG_PARTITION_MANAGER=n +SB_CONFIG_PARTITION_MANAGER=y diff --git a/tests/unit_tests/mfg_parsers/CMakeLists.txt b/tests/unit_tests/mfg_parsers/CMakeLists.txt new file mode 100644 index 0000000000..ba1ceb93bf --- /dev/null +++ b/tests/unit_tests/mfg_parsers/CMakeLists.txt @@ -0,0 +1,33 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +set(SIDEWALK_BASE $ENV{ZEPHYR_BASE}/../sidewalk) + +project(device) + +FILE(GLOB app_sources src/*.c) + +target_sources(app PRIVATE + ${app_sources} + ${SIDEWALK_BASE}/utils/tlv/tlv.c + ${SIDEWALK_BASE}/utils/tlv/tlv_ram_storage_impl.c + ${SIDEWALK_BASE}/utils/tlv/tlv_flash_storage_impl.c + ${SIDEWALK_BASE}/subsys/sal/sid_pal/src/sid_mfg_hex_v7.c + ${SIDEWALK_BASE}/subsys/sal/sid_pal/src/sid_mfg_hex_v8.c +) + +target_include_directories(app PRIVATE + . + ./mocks + src + ${SIDEWALK_BASE}/utils/include + ${SIDEWALK_BASE}/subsys/sal/sid_pal/include + ${SIDEWALK_BASE}/subsys/hal/include + ${SIDEWALK_BASE}/subsys/sal/common/sid_pal_ifc + ${SIDEWALK_BASE}/subsys/config/common/include +) diff --git a/tests/unit_tests/mfg_parsers/Kconfig b/tests/unit_tests/mfg_parsers/Kconfig new file mode 100644 index 0000000000..ad26620305 --- /dev/null +++ b/tests/unit_tests/mfg_parsers/Kconfig @@ -0,0 +1,18 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +config LOG + default false + +config SIDEWALK_LOG_LEVEL + default 0 + + +config SIDEWALK_CRYPTO_PSA_KEY_STORAGE + bool "Enable psa crypto storage for persistent Sidewalk keys [EXPERIMENTAL]" + +source "${ZEPHYR_BASE}/../sidewalk/utils/Kconfig" +source "Kconfig.zephyr" diff --git a/tests/unit_tests/mfg_parsers/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/unit_tests/mfg_parsers/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 0000000000..8edfb6476e --- /dev/null +++ b/tests/unit_tests/mfg_parsers/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + + +/* Application does not use cpuflpr core. Assign whole RRAM to cpuapp. */ +&cpuapp_rram { + reg = < 0x0 DT_SIZE_K(1524) >; +}; diff --git a/tests/unit_tests/mfg_parsers/mocks/sid_crypto_keys.h b/tests/unit_tests/mfg_parsers/mocks/sid_crypto_keys.h new file mode 100644 index 0000000000..dac71d808d --- /dev/null +++ b/tests/unit_tests/mfg_parsers/mocks/sid_crypto_keys.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef SID_CRYPTO_KEYS_H +#define SID_CRYPTO_KEYS_H + +#include +#include +#define PSA_KEY_ID_USER_MIN 0 +typedef int psa_key_id_t; + +#define SID_CRYPTO_KEYS_ID_IS_SIDEWALK_KEY(_id) \ + (PSA_KEY_ID_USER_MIN <= _id && _id < SID_CRYPTO_KEY_ID_LAST) + +/** + * @brief Persistent psa key ids used in Sidewalk. + */ +typedef enum { + SID_CRYPTO_MFG_ED25519_PRIV_KEY_ID = PSA_KEY_ID_USER_MIN, + SID_CRYPTO_MFG_SECP_256R1_PRIV_KEY_ID, + SID_CRYPTO_KV_WAN_MASTER_KEY_ID, + SID_CRYPTO_KV_APP_KEY_KEY_ID, + SID_CRYPTO_KV_D2D_KEY_ID, + SID_CRYPTO_KEY_ID_LAST +} sid_crypto_key_id_t; + +/** + * @brief Init secure key storage for Sidewalk keys. + * + * @return 0 on success, or -errno on failure. + */ +int sid_crypto_keys_init(void); + +/** + * @brief Import key value form buffer. + * + * @note key value under given key id will be overwritten. + * + * @param id [in] Key id to import data. + * @param data [in] raw key data on input. + * @param size [in] size of raw key data buffer. + * @return 0 on success, or -errno on failure. + */ +int sid_crypto_keys_new_import(psa_key_id_t id, uint8_t *data, size_t size); + +/** + * @brief Generate a new key value. + * + * @note key value under given key id will be overwritten. + * + * @param id [in] Key id to generate new. + * @param puk [in] Buffer with raw key value. + * @param puk_size [in] Size of buffer with rew kay value. + * @return 0 on success, or -errno on failure. + */ +int sid_crypto_keys_new_generate(psa_key_id_t id, uint8_t *puk, size_t puk_size); + +/** + * @brief Set key id in buffer. + * + * @param id [in] Key id to write to the data buffer. + * @param buffer [out] key id fulfilled with zeros. + * @param size [in] size of raw key data buffer. + * @return 0 on success, or -errno on failure. + */ +int sid_crypto_keys_buffer_set(psa_key_id_t id, uint8_t *buffer, size_t size); + +/** + * @brief Get key id from buffer. + * + * @param id [out] psa key id from key data buffer. + * If key not found set to PSA_KEY_ID_NULL. + * @param buffer [in] key data buffer. + * @param size [in] size of key data buffer. + * @return 0 on success, or -errno on failure. + * -ENOENT - if no key in buffer. + */ +int sid_crypto_keys_buffer_get(psa_key_id_t *id, uint8_t *buffer, size_t size); + +/** + * @brief Destroy key. + * + * @note This operation is irreversible. + * + * @param id [in] psa key id to be permanently removed. + * @return 0 on success, or -errno on failure. + */ +int sid_crypto_keys_delete(psa_key_id_t id); + +/** + * @brief Deinit sidewalk key storage. + * + * @return 0 on success, or -errno on failure. + */ +int sid_crypto_keys_deinit(void); + +#endif /* SID_CRYPTO_KEYS_H */ diff --git a/tests/functional/mfg_storage/pm_static.yml b/tests/unit_tests/mfg_parsers/pm_static.yml similarity index 74% rename from tests/functional/mfg_storage/pm_static.yml rename to tests/unit_tests/mfg_parsers/pm_static.yml index 38e6c17c13..658ce757c1 100644 --- a/tests/functional/mfg_storage/pm_static.yml +++ b/tests/unit_tests/mfg_parsers/pm_static.yml @@ -1,4 +1,5 @@ mfg_storage: address: 0xff000 + end_address: 0x100000 region: flash_primary size: 0x1000 diff --git a/tests/unit_tests/mfg_parsers/pm_static_nrf54l15pdk_nrf54l15_cpuapp.yml b/tests/unit_tests/mfg_parsers/pm_static_nrf54l15pdk_nrf54l15_cpuapp.yml new file mode 100644 index 0000000000..38f2de2a08 --- /dev/null +++ b/tests/unit_tests/mfg_parsers/pm_static_nrf54l15pdk_nrf54l15_cpuapp.yml @@ -0,0 +1,5 @@ +mfg_storage: + address: 0x17c000 + end_address: 0x17d000 + region: flash_primary + size: 0x1000 diff --git a/tests/unit_tests/mfg_parsers/prj.conf b/tests/unit_tests/mfg_parsers/prj.conf new file mode 100644 index 0000000000..182f3f68f9 --- /dev/null +++ b/tests/unit_tests/mfg_parsers/prj.conf @@ -0,0 +1,11 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# +CONFIG_ZTEST=y +CONFIG_SIDEWALK_TLV=y +CONFIG_SIDEWALK_TLV_RAM=y +CONFIG_SIDEWALK_TLV_FLASH=y + +CONFIG_FLASH=y diff --git a/tests/unit_tests/mfg_parsers/src/mfg_parser.c b/tests/unit_tests/mfg_parsers/src/mfg_parser.c new file mode 100644 index 0000000000..cb5f2c30a5 --- /dev/null +++ b/tests/unit_tests/mfg_parsers/src/mfg_parser.c @@ -0,0 +1,738 @@ +/** + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#if CONFIG_BOARD_NATIVE_POSIX +#define FIXED_PARTITION_OFFSET(x) 0xFF000 +#else +#include "flash_map_pm.h" +#endif +#include "sid_hal_memory_ifc.h" +#include "zephyr/drivers/flash.h" +#include "zephyr/ztest_assert.h" +#include +#include +#include +#include +#include +#include + +uint8_t TLV_RAM_STORAGE[0x1000] = { [0x0 ... 0xfff] = 0xff }; + +#define RAW_MFG_VERSION_8_VALUE 0x00, 0x00, 0x00, 0x08 + +/* RANDOM VALUES FOR TEST*/ +/* 4 */ +#define SID_PAL_MFG_STORE_SMSN_VALUE \ + 0x25, 0xd6, 0xb6, 0xbf, 0x35, 0x58, 0xea, 0x6e, 0x0e, 0xec, 0x0d, 0x43, 0xc3, 0x6f, 0x01, \ + 0xf0, 0xf5, 0x74, 0x81, 0xfa, 0x3d, 0x43, 0x54, 0x0d, 0xdb, 0x31, 0x96, 0x7c, \ + 0xe9, 0xb1, 0xb8, 0xa6 + +/* 5 */ +#define SID_PAL_MFG_STORE_APP_PUB_ED25519_VALUE \ + 0xdd, 0x33, 0x8d, 0xd6, 0x47, 0xad, 0x3b, 0x52, 0xd2, 0x1c, 0xd4, 0xd2, 0xc7, 0x94, 0x8c, \ + 0x10, 0x25, 0xf2, 0xe8, 0x57, 0x2c, 0x46, 0xd4, 0x7b, 0xfa, 0x0c, 0x91, 0x60, \ + 0xf1, 0xc7, 0xed, 0xe6 + +/* 6 */ +#define SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519_VALUE \ + 0x85, 0xcb, 0x3f, 0xf2, 0x61, 0xa6, 0x33, 0x2e, 0xef, 0xa0, 0x60, 0xa5, 0x00, 0x73, 0x4b, \ + 0xf2, 0xcf, 0x11, 0xb8, 0xa7, 0xb7, 0x82, 0x15, 0x11, 0x29, 0x99, 0xf3, 0xa1, \ + 0x58, 0xed, 0x59, 0xaf + +/* 7 */ +#define SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_VALUE \ + 0xa2, 0x43, 0x2d, 0x98, 0xfe, 0xae, 0x13, 0xa3, 0xfe, 0x5e, 0x5f, 0x31, 0x41, 0xfd, 0x6c, \ + 0x39, 0x98, 0xd6, 0xcf, 0x29, 0x34, 0x0c, 0x4f, 0xaf, 0x09, 0xd6, 0x5e, 0x50, \ + 0xe9, 0x8b, 0x56, 0x0a + +/* 8 */ +#define SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_SIGNATURE_VALUE \ + 0x69, 0x9d, 0x33, 0x97, 0x60, 0x08, 0x6b, 0xfc, 0xca, 0x9d, 0x69, 0xe5, 0x35, 0xf6, 0x6a, \ + 0xb6, 0x46, 0x07, 0x4b, 0x20, 0xbd, 0xa9, 0xcc, 0x7c, 0xef, 0x93, 0x0c, 0xfd, \ + 0xef, 0x90, 0x71, 0xcf, 0x25, 0xa7, 0x37, 0x1c, 0xa8, 0x01, 0x11, 0x36, 0x5f, \ + 0x00, 0x6c, 0xf6, 0x2f, 0xb6, 0x74, 0xe3, 0xc9, 0x68, 0xf8, 0x1c, 0x73, 0x3b, \ + 0x40, 0xde, 0x61, 0x32, 0x7e, 0x2a, 0xdf, 0x2e, 0x21, 0x63 + +/* 9 */ +#define SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1_VALUE \ + 0x7d, 0x2a, 0x0a, 0xca, 0xe2, 0x3a, 0xc8, 0xb2, 0x7f, 0x3e, 0xa6, 0x0a, 0xa0, 0xfb, 0x44, \ + 0xf4, 0x4b, 0xf2, 0x0f, 0xa6, 0x97, 0x08, 0xbc, 0x52, 0x27, 0x5a, 0x23, 0x7c, \ + 0x53, 0x81, 0x99, 0x0b + +/* 10 */ +#define SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_VALUE \ + 0xc9, 0xd3, 0x4d, 0xab, 0x57, 0x94, 0x6e, 0xe3, 0xd7, 0xb4, 0xe2, 0x29, 0x14, 0xdf, 0xb1, \ + 0x6c, 0xa3, 0xbc, 0x30, 0x81, 0x90, 0xaa, 0x17, 0xc3, 0x71, 0xd0, 0xf2, 0xbb, \ + 0xc2, 0x2b, 0xbd, 0x1b, 0xa5, 0x22, 0xfd, 0xac, 0xc8, 0xa3, 0xc3, 0xd7, 0xbd, \ + 0xec, 0xa1, 0xac, 0x9b, 0x67, 0xeb, 0x3e, 0xe0, 0x6c, 0xb7, 0x07, 0xc8, 0x50, \ + 0xd8, 0x09, 0xa8, 0xb4, 0x87, 0xac, 0xbd, 0x98, 0x72, 0x3b + +/* 11 */ +#define SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_SIGNATURE_VALUE \ + 0xe2, 0x51, 0x15, 0xfd, 0x41, 0x53, 0xbd, 0xc3, 0x01, 0x01, 0xa3, 0x0b, 0x4f, 0x5c, 0xfd, \ + 0x91, 0xaa, 0xf8, 0x12, 0xd3, 0x6e, 0xb8, 0xc0, 0x6a, 0xf9, 0x38, 0xa6, 0x81, \ + 0x0d, 0x9e, 0x67, 0xdd, 0xb6, 0xae, 0xe8, 0x92, 0x8a, 0xb0, 0x5b, 0xb4, 0xb1, \ + 0xe8, 0x46, 0x13, 0x83, 0xd0, 0x06, 0x09, 0xb2, 0xac, 0x8e, 0x6e, 0x75, 0x31, \ + 0x08, 0x80, 0x85, 0x69, 0xb6, 0x06, 0x43, 0x97, 0x6f, 0x22 + +/* 12 */ +#define SID_PAL_MFG_STORE_DAK_PUB_ED25519_VALUE \ + 0xbb, 0x41, 0xf6, 0x41, 0x1b, 0xa9, 0x84, 0x74, 0xa4, 0x49, 0x1e, 0x08, 0xd1, 0x72, 0x60, \ + 0x22, 0x62, 0x7d, 0xfa, 0xdf, 0x6e, 0x89, 0x5c, 0xf0, 0x84, 0xb1, 0x9c, 0xba, \ + 0xb9, 0x70, 0x40, 0x0d + +/* 13 */ +#define SID_PAL_MFG_STORE_DAK_PUB_ED25519_SIGNATURE_VALUE \ + 0xb6, 0x93, 0xa8, 0xa5, 0x2a, 0xda, 0xe8, 0x1c, 0xaf, 0x16, 0x34, 0x53, 0x63, 0x21, 0xde, \ + 0x5a, 0x94, 0x16, 0x89, 0x8c, 0x35, 0x91, 0x91, 0xde, 0xc2, 0xc5, 0xdc, 0x1d, \ + 0x65, 0xd7, 0x4a, 0x76, 0xd7, 0x83, 0x1f, 0x9b, 0x42, 0x80, 0x55, 0x1a, 0x7e, \ + 0x9f, 0xe8, 0xbe, 0xdc, 0xef, 0x0b, 0x27, 0x22, 0xf6, 0x08, 0x49, 0x67, 0x9c, \ + 0xd0, 0xf6, 0xbe, 0x2e, 0x5c, 0x79, 0x9d, 0x68, 0x4f, 0x41 + +/* 14 */ +#define SID_PAL_MFG_STORE_DAK_ED25519_SERIAL_VALUE 0x17, 0xca, 0x3d, 0xc4 + +/* 15 */ +#define SID_PAL_MFG_STORE_DAK_PUB_P256R1_VALUE \ + 0x8c, 0x6b, 0x58, 0x7e, 0x7f, 0xb5, 0x8e, 0x8d, 0x89, 0xe7, 0x0e, 0x6d, 0x1a, 0x19, 0x46, \ + 0x16, 0xbf, 0x2a, 0x87, 0xc1, 0x55, 0xa3, 0x84, 0x3b, 0xae, 0x33, 0xdf, 0x18, \ + 0x10, 0x41, 0x12, 0xdf, 0x86, 0x84, 0x0c, 0xe0, 0x24, 0xf9, 0x55, 0x3d, 0xf8, \ + 0x78, 0x70, 0x7a, 0x68, 0x56, 0xdd, 0xb8, 0x0c, 0x29, 0xc8, 0x4c, 0xca, 0x8c, \ + 0x38, 0x9d, 0xcc, 0x3a, 0x46, 0xd5, 0xc8, 0x7a, 0xf3, 0x98 + +/* 16 */ +#define SID_PAL_MFG_STORE_DAK_PUB_P256R1_SIGNATURE_VALUE \ + 0xd3, 0xcd, 0x58, 0xbb, 0x17, 0x3b, 0x68, 0xf9, 0x3e, 0xbf, 0x0c, 0x38, 0x94, 0x80, 0x2c, \ + 0x80, 0xd2, 0x8c, 0x2a, 0x51, 0x8b, 0x5f, 0x7e, 0x5a, 0xe3, 0x79, 0x6d, 0x10, \ + 0x4f, 0x4a, 0x08, 0x72, 0xa2, 0x52, 0xff, 0xf4, 0x55, 0xcf, 0xc8, 0x53, 0x32, \ + 0x2f, 0xf6, 0xec, 0x12, 0x2e, 0x0f, 0xb2, 0xfe, 0xe2, 0x6f, 0xab, 0xdc, 0xcc, \ + 0x5d, 0x77, 0x5d, 0x24, 0xbc, 0x08, 0xdb, 0x3e, 0x26, 0x68 + +/* 17 */ +#define SID_PAL_MFG_STORE_DAK_P256R1_SERIAL_VALUE 0x98, 0x69, 0x6e, 0xa9 +/* 18 */ +#define SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_VALUE \ + 0x3c, 0x5d, 0xb9, 0x14, 0xb9, 0xd0, 0x5e, 0x7b, 0xfc, 0x98, 0xec, 0x31, 0xaf, 0xa0, 0x43, \ + 0x80, 0x0d, 0xe0, 0xb1, 0x9c, 0x2d, 0xf5, 0xe3, 0xf2, 0x53, 0x78, 0xc2, 0x21, \ + 0x25, 0x7d, 0x9b, 0x33 + +/* 19 */ +#define SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_SIGNATURE_VALUE \ + 0x1f, 0xa1, 0x4a, 0x6d, 0xac, 0xb9, 0x1d, 0x85, 0xdc, 0x87, 0x44, 0x76, 0x75, 0x1e, 0xa2, \ + 0xc0, 0x40, 0xb0, 0x83, 0x70, 0x2b, 0x26, 0xf3, 0xc2, 0xa0, 0xa4, 0xb2, 0x38, \ + 0x01, 0x99, 0x84, 0x06, 0x36, 0xe8, 0x88, 0xcb, 0x55, 0xa7, 0xfb, 0x5e, 0x03, \ + 0x16, 0xb7, 0x9d, 0xbe, 0xab, 0xf9, 0x57, 0x1c, 0xc6, 0x2f, 0x06, 0x0e, 0xa1, \ + 0xf7, 0x8f, 0x61, 0x43, 0x33, 0x83, 0x6a, 0x67, 0x54, 0xf7 + +/* 20 */ +#define SID_PAL_MFG_STORE_PRODUCT_ED25519_SERIAL_VALUE 0x0b, 0xab, 0x8a, 0xb2 + +/* 21 */ +#define SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_VALUE \ + 0x77, 0x49, 0xf9, 0x6c, 0x3e, 0x80, 0xb2, 0x84, 0x94, 0xe4, 0xe7, 0xb4, 0xab, 0x43, 0x25, \ + 0x26, 0x6c, 0xf9, 0xf1, 0x52, 0x3a, 0x0a, 0x75, 0x9a, 0x36, 0xe0, 0xde, 0x81, \ + 0x95, 0x7f, 0x90, 0xe4, 0xb3, 0x3a, 0x44, 0xe5, 0x8b, 0xaf, 0xf2, 0x03, 0xb9, \ + 0xe6, 0xb8, 0xf2, 0x24, 0xa4, 0x86, 0x54, 0xf8, 0x9f, 0x78, 0xb3, 0x5f, 0x44, \ + 0x36, 0xa8, 0x65, 0x09, 0xc5, 0xfc, 0x13, 0x66, 0x59, 0xf5 + +/* 22 */ +#define SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_SIGNATURE_VALUE \ + 0x7a, 0x41, 0xf2, 0x8e, 0xbf, 0x5e, 0x03, 0xa8, 0x64, 0x75, 0x7b, 0x72, 0x6d, 0x84, 0xbd, \ + 0x94, 0x99, 0x77, 0xcc, 0xef, 0x5b, 0x8d, 0x72, 0xef, 0x86, 0xac, 0x78, 0x0d, \ + 0xdf, 0x22, 0xc3, 0x92, 0x6c, 0x75, 0xef, 0x46, 0x9b, 0x1e, 0xb4, 0x73, 0x36, \ + 0xa1, 0x16, 0x70, 0x4f, 0x9d, 0x59, 0xfc, 0x5c, 0x1f, 0x87, 0xcd, 0x49, 0xd4, \ + 0x50, 0x64, 0x70, 0x3d, 0xe7, 0x94, 0x72, 0xc4, 0xea, 0x8c + +/* 23 */ +#define SID_PAL_MFG_STORE_PRODUCT_P256R1_SERIAL_VALUE 0xff, 0x7e, 0x36, 0x4d + +/* 24 */ +#define SID_PAL_MFG_STORE_MAN_PUB_ED25519_VALUE \ + 0x61, 0x12, 0xf3, 0x57, 0xa5, 0xc3, 0x82, 0x8f, 0x5d, 0x3a, 0x5f, 0x76, 0xbd, 0x47, 0x57, \ + 0x69, 0x11, 0x3b, 0x5a, 0x58, 0x6b, 0x10, 0x9b, 0xeb, 0x1d, 0x83, 0xc6, 0x2c, \ + 0xea, 0xce, 0xc1, 0xba + +/* 25 */ +#define SID_PAL_MFG_STORE_MAN_PUB_ED25519_SIGNATURE_VALUE \ + 0xab, 0xfd, 0xd4, 0x30, 0x7d, 0x0d, 0x2b, 0x8a, 0x92, 0x5c, 0xd2, 0x89, 0x47, 0xec, 0x16, \ + 0x66, 0x92, 0x2b, 0xa7, 0x0a, 0xe2, 0x14, 0x97, 0x94, 0x46, 0xb7, 0x0c, 0x58, \ + 0x40, 0x91, 0x79, 0xa9, 0xdc, 0xcc, 0x32, 0x0c, 0x48, 0xac, 0x1a, 0x6b, 0x41, \ + 0xb9, 0x1e, 0xe0, 0x39, 0xaa, 0x70, 0x45, 0x23, 0x21, 0xc3, 0x04, 0x2e, 0x6d, \ + 0x72, 0x44, 0x28, 0x3c, 0x37, 0xca, 0xbd, 0xba, 0x10, 0x43 + +/* 26 */ +#define SID_PAL_MFG_STORE_MAN_ED25519_SERIAL_VALUE 0x61, 0x28, 0x1b, 0x29 + +/* 27 */ +#define SID_PAL_MFG_STORE_MAN_PUB_P256R1_VALUE \ + 0xa9, 0x5c, 0x61, 0xba, 0x1a, 0xdc, 0x4b, 0x6b, 0x2b, 0xfd, 0xd2, 0x02, 0xa9, 0xba, 0x50, \ + 0x17, 0xa5, 0x1a, 0x87, 0x39, 0x9a, 0x2b, 0x5d, 0x50, 0xa2, 0xc3, 0xed, 0xcc, \ + 0xdd, 0xff, 0x27, 0x0a, 0x32, 0xc8, 0xd8, 0x30, 0x60, 0xdb, 0x20, 0xfc, 0x46, \ + 0xe8, 0x3b, 0x1c, 0xf4, 0x19, 0xf1, 0xee, 0xc4, 0xef, 0x9f, 0x66, 0xb8, 0x61, \ + 0xd4, 0x78, 0x3a, 0x84, 0xc0, 0x50, 0x95, 0x14, 0xf6, 0x71 + +/* 28 */ +#define SID_PAL_MFG_STORE_MAN_PUB_P256R1_SIGNATURE_VALUE \ + 0xd3, 0x72, 0x99, 0x84, 0x54, 0xec, 0xec, 0x8f, 0x66, 0xcb, 0x06, 0x95, 0x13, 0x80, 0x81, \ + 0xd2, 0xb0, 0x02, 0xbb, 0x4f, 0x9e, 0x78, 0xff, 0xbc, 0x41, 0x87, 0x4e, 0xef, \ + 0xbf, 0x61, 0x87, 0x32, 0x0f, 0xd3, 0x25, 0xf0, 0x74, 0x0e, 0x91, 0xf3, 0x60, \ + 0x51, 0xd8, 0x9a, 0xe6, 0x7b, 0x56, 0xa6, 0x6d, 0x6b, 0xaf, 0x1e, 0xd0, 0x2c, \ + 0x7e, 0xc6, 0x91, 0xec, 0x76, 0x12, 0x30, 0xff, 0x24, 0x94 + +/* 29 */ +#define SID_PAL_MFG_STORE_MAN_P256R1_SERIAL_VALUE 0x72, 0x73, 0x8a, 0x7b + +/* 30 */ +#define SID_PAL_MFG_STORE_SW_PUB_ED25519_VALUE \ + 0x78, 0x17, 0x5e, 0x1b, 0xc6, 0x2a, 0x37, 0x19, 0x0e, 0x8f, 0xb4, 0xa5, 0x76, 0x81, 0xf5, \ + 0x0a, 0x39, 0x2b, 0xd3, 0x40, 0x34, 0x0d, 0x90, 0x06, 0x0d, 0xda, 0x53, 0x26, \ + 0x2d, 0x11, 0x73, 0xb0 + +/* 31 */ +#define SID_PAL_MFG_STORE_SW_PUB_ED25519_SIGNATURE_VALUE \ + 0x71, 0x29, 0xae, 0x6f, 0x94, 0x16, 0xd6, 0xf8, 0x62, 0xd7, 0xec, 0x9b, 0x45, 0x14, 0x1b, \ + 0xae, 0x0e, 0x53, 0x71, 0x39, 0x84, 0xbc, 0x80, 0x95, 0x8f, 0x8c, 0x90, 0x21, \ + 0xdb, 0xa3, 0xd3, 0x1f, 0x5b, 0x72, 0x21, 0x1e, 0x60, 0x46, 0x32, 0x3e, 0x72, \ + 0xdd, 0xfb, 0xb2, 0x8b, 0xff, 0xb9, 0x55, 0xbd, 0x84, 0xc7, 0x79, 0xf3, 0xfa, \ + 0x80, 0x45, 0x5f, 0x22, 0xaa, 0xa8, 0x30, 0x8f, 0x8a, 0x3d + +/* 32 */ +#define SID_PAL_MFG_STORE_SW_ED25519_SERIAL_VALUE 0x22, 0x51, 0x83, 0x55 + +/* 33 */ +#define SID_PAL_MFG_STORE_SW_PUB_P256R1_VALUE \ + 0xe6, 0x9b, 0x15, 0xcd, 0x78, 0x31, 0x02, 0xc3, 0x4d, 0x4b, 0x1a, 0x95, 0xaa, 0x57, 0x6d, \ + 0x3d, 0x0e, 0xac, 0xeb, 0x1f, 0xec, 0x62, 0xfb, 0xac, 0xc0, 0x8a, 0x7b, 0x3f, \ + 0x07, 0x36, 0x36, 0xe0, 0x56, 0x23, 0x65, 0x14, 0xbd, 0xfc, 0x38, 0x1e, 0xa2, \ + 0x68, 0xda, 0x3c, 0xa1, 0x28, 0xa5, 0x79, 0x9d, 0x39, 0xee, 0x4c, 0x96, 0x12, \ + 0x31, 0xea, 0x7a, 0x04, 0x49, 0xd8, 0x24, 0x93, 0x98, 0xea + +/* 34 */ +#define SID_PAL_MFG_STORE_SW_PUB_P256R1_SIGNATURE_VALUE \ + 0x0c, 0xdb, 0x18, 0x85, 0x05, 0xb0, 0x64, 0xe3, 0x58, 0x10, 0x2c, 0x67, 0xf1, 0xd2, 0x98, \ + 0x68, 0xbb, 0xf8, 0x75, 0xac, 0xcc, 0x67, 0xc2, 0x3d, 0xac, 0xe5, 0x8c, 0x47, \ + 0x7f, 0x2c, 0xf8, 0x40, 0xb5, 0xb1, 0x15, 0xe2, 0x9f, 0x78, 0x6c, 0x14, 0xce, \ + 0x82, 0x1c, 0xc8, 0xe9, 0xd7, 0x26, 0xba, 0x6d, 0x7e, 0xb0, 0xc9, 0x8d, 0x77, \ + 0x5e, 0xe3, 0x5f, 0xab, 0xbc, 0x14, 0x8f, 0xe3, 0xd5, 0x67 + +/* 35 */ +#define SID_PAL_MFG_STORE_SW_P256R1_SERIAL_VALUE 0xe7, 0xe0, 0x9b, 0x03 + +/* 36 */ +#define SID_PAL_MFG_STORE_AMZN_PUB_ED25519_VALUE \ + 0x35, 0x7c, 0x3a, 0xca, 0x1e, 0xfc, 0x4a, 0x81, 0x25, 0xed, 0xce, 0xbc, 0xfc, 0xf2, 0x33, \ + 0xa6, 0xa7, 0x4a, 0x8c, 0xca, 0x7b, 0x85, 0x49, 0x79, 0xea, 0x46, 0xa0, 0xa6, \ + 0xa8, 0x55, 0x32, 0x17 + +/* 37 */ +#define SID_PAL_MFG_STORE_AMZN_PUB_P256R1_VALUE \ + 0x5f, 0x0a, 0xe1, 0x14, 0x88, 0x92, 0xd9, 0x70, 0xb8, 0xea, 0x80, 0x34, 0xe1, 0xf7, 0x22, \ + 0x08, 0xc1, 0x96, 0x58, 0x4c, 0xdc, 0xe0, 0x67, 0x18, 0x8a, 0x3b, 0x9e, 0xfe, \ + 0x5b, 0xfa, 0xb1, 0x39, 0x9a, 0x0e, 0x14, 0x4c, 0x21, 0xd3, 0x9d, 0x38, 0x64, \ + 0xe1, 0x46, 0x17, 0xe5, 0x5b, 0xb4, 0xef, 0x73, 0x1f, 0x62, 0x4a, 0xb7, 0x3e, \ + 0xf1, 0x53, 0x75, 0x2f, 0x67, 0x3a, 0x6c, 0xa6, 0x75, 0x6b + +/* 38 */ +#define SID_PAL_MFG_STORE_APID_VALUE 0x76, 0x9d, 0x02, 0x7f + +unsigned int mfg_v8_bin_len = 1528; + +unsigned char mfg_v8_bin_raw[] = { + 0x53, 0x49, 0x44, 0x30, RAW_MFG_VERSION_8_VALUE, + + 0x00, 0x04, 0x00, 0x20, SID_PAL_MFG_STORE_SMSN_VALUE, + + 0x00, 0x05, 0x00, 0x20, SID_PAL_MFG_STORE_APP_PUB_ED25519_VALUE, + + 0x00, 0x06, 0x00, 0x20, SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519_VALUE, + + 0x00, 0x07, 0x00, 0x20, SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_VALUE, + + 0x00, 0x08, 0x00, 0x40, SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_SIGNATURE_VALUE, + + 0x00, 0x09, 0x00, 0x20, SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1_VALUE, + + 0x00, 0x0a, 0x00, 0x40, SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_VALUE, + + 0x00, 0x0b, 0x00, 0x40, SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_SIGNATURE_VALUE, + + 0x00, 0x0c, 0x00, 0x20, SID_PAL_MFG_STORE_DAK_PUB_ED25519_VALUE, + + 0x00, 0x0d, 0x00, 0x40, SID_PAL_MFG_STORE_DAK_PUB_ED25519_SIGNATURE_VALUE, + + 0x00, 0x0e, 0x00, 0x04, SID_PAL_MFG_STORE_DAK_ED25519_SERIAL_VALUE, + + 0x00, 0x0f, 0x00, 0x40, SID_PAL_MFG_STORE_DAK_PUB_P256R1_VALUE, + + 0x00, 0x10, 0x00, 0x40, SID_PAL_MFG_STORE_DAK_PUB_P256R1_SIGNATURE_VALUE, + + 0x00, 0x11, 0x00, 0x04, SID_PAL_MFG_STORE_DAK_P256R1_SERIAL_VALUE, + + 0x00, 0x12, 0x00, 0x20, SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_VALUE, + + 0x00, 0x13, 0x00, 0x40, SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_SIGNATURE_VALUE, + + 0x00, 0x14, 0x00, 0x04, SID_PAL_MFG_STORE_PRODUCT_ED25519_SERIAL_VALUE, + + 0x00, 0x15, 0x00, 0x40, SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_VALUE, + + 0x00, 0x16, 0x00, 0x40, SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_SIGNATURE_VALUE, + + 0x00, 0x17, 0x00, 0x04, SID_PAL_MFG_STORE_PRODUCT_P256R1_SERIAL_VALUE, + + 0x00, 0x18, 0x00, 0x20, SID_PAL_MFG_STORE_MAN_PUB_ED25519_VALUE, + + 0x00, 0x19, 0x00, 0x40, SID_PAL_MFG_STORE_MAN_PUB_ED25519_SIGNATURE_VALUE, + + 0x00, 0x1a, 0x00, 0x04, SID_PAL_MFG_STORE_MAN_ED25519_SERIAL_VALUE, + + 0x00, 0x1b, 0x00, 0x40, SID_PAL_MFG_STORE_MAN_PUB_P256R1_VALUE, + + 0x00, 0x1c, 0x00, 0x40, SID_PAL_MFG_STORE_MAN_PUB_P256R1_SIGNATURE_VALUE, + + 0x00, 0x1d, 0x00, 0x04, SID_PAL_MFG_STORE_MAN_P256R1_SERIAL_VALUE, + + 0x00, 0x1e, 0x00, 0x20, SID_PAL_MFG_STORE_SW_PUB_ED25519_VALUE, + + 0x00, 0x1f, 0x00, 0x40, SID_PAL_MFG_STORE_SW_PUB_ED25519_SIGNATURE_VALUE, + + 0x00, 0x20, 0x00, 0x04, SID_PAL_MFG_STORE_SW_ED25519_SERIAL_VALUE, + + 0x00, 0x21, 0x00, 0x40, SID_PAL_MFG_STORE_SW_PUB_P256R1_VALUE, + + 0x00, 0x22, 0x00, 0x40, SID_PAL_MFG_STORE_SW_PUB_P256R1_SIGNATURE_VALUE, + + 0x00, 0x23, 0x00, 0x04, SID_PAL_MFG_STORE_SW_P256R1_SERIAL_VALUE, + + 0x00, 0x24, 0x00, 0x20, SID_PAL_MFG_STORE_AMZN_PUB_ED25519_VALUE, + + 0x00, 0x25, 0x00, 0x40, SID_PAL_MFG_STORE_AMZN_PUB_P256R1_VALUE, + + 0x00, 0x26, 0x00, 0x04, SID_PAL_MFG_STORE_APID_VALUE +}; + +#define RAW_MFG_VERSION_7_VALUE 0x00, 0x00, 0x00, 0x07 +enum { + SID_PAL_MFG_STORE_OFFSET_MAGIC = 4 * 0, + SID_PAL_MFG_STORE_OFFSET_VERSION = 4 * 1, + SID_PAL_MFG_STORE_OFFSET_SERIAL_NUM = 4 * 2, + SID_PAL_MFG_STORE_OFFSET_SMSN = 4 * 8, + SID_PAL_MFG_STORE_OFFSET_APID = 4 * 16, + SID_PAL_MFG_STORE_OFFSET_APP_PUB_ED25519 = 4 * 18, + SID_PAL_MFG_STORE_OFFSET_DEVICE_PRIV_ED25519 = 4 * 26, + SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_ED25519 = 4 * 34, + SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_ED25519_SIGNATURE = 4 * 42, + SID_PAL_MFG_STORE_OFFSET_DEVICE_PRIV_P256R1 = 4 * 58, + SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_P256R1 = 4 * 66, + SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_P256R1_SIGNATURE = 4 * 82, + SID_PAL_MFG_STORE_OFFSET_DAK_PUB_ED25519 = 4 * 98, + SID_PAL_MFG_STORE_OFFSET_DAK_PUB_ED25519_SIGNATURE = 4 * 106, + SID_PAL_MFG_STORE_OFFSET_DAK_ED25519_SERIAL = 4 * 122, + SID_PAL_MFG_STORE_OFFSET_DAK_PUB_P256R1 = 4 * 123, + SID_PAL_MFG_STORE_OFFSET_DAK_PUB_P256R1_SIGNATURE = 4 * 139, + SID_PAL_MFG_STORE_OFFSET_DAK_P256R1_SERIAL = 4 * 155, + SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_ED25519 = 4 * 156, + SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_ED25519_SIGNATURE = 4 * 164, + SID_PAL_MFG_STORE_OFFSET_PRODUCT_ED25519_SERIAL = 4 * 180, + SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_P256R1 = 4 * 181, + SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_P256R1_SIGNATURE = 4 * 197, + SID_PAL_MFG_STORE_OFFSET_PRODUCT_P256R1_SERIAL = 4 * 213, + SID_PAL_MFG_STORE_OFFSET_MAN_PUB_ED25519 = 4 * 214, + SID_PAL_MFG_STORE_OFFSET_MAN_PUB_ED25519_SIGNATURE = 4 * 222, + SID_PAL_MFG_STORE_OFFSET_MAN_ED25519_SERIAL = 4 * 238, + SID_PAL_MFG_STORE_OFFSET_MAN_PUB_P256R1 = 4 * 239, + SID_PAL_MFG_STORE_OFFSET_MAN_PUB_P256R1_SIGNATURE = 4 * 255, + SID_PAL_MFG_STORE_OFFSET_MAN_P256R1_SERIAL = 4 * 271, + SID_PAL_MFG_STORE_OFFSET_SW_PUB_ED25519 = 4 * 272, + SID_PAL_MFG_STORE_OFFSET_SW_PUB_ED25519_SIGNATURE = 4 * 280, + SID_PAL_MFG_STORE_OFFSET_SW_ED25519_SERIAL = 4 * 296, + SID_PAL_MFG_STORE_OFFSET_SW_PUB_P256R1 = 4 * 297, + SID_PAL_MFG_STORE_OFFSET_SW_PUB_P256R1_SIGNATURE = 4 * 313, + SID_PAL_MFG_STORE_OFFSET_SW_P256R1_SERIAL = 4 * 329, + SID_PAL_MFG_STORE_OFFSET_AMZN_PUB_ED25519 = 4 * 330, + SID_PAL_MFG_STORE_OFFSET_AMZN_PUB_P256R1 = 4 * 338, + SID_PAL_MFG_STORE_SID_V0_MAX_OFFSET = 4 * 346, +}; + +unsigned char mfg_v7_bin_raw[] = { + [SID_PAL_MFG_STORE_OFFSET_MAGIC] = 0x53, + 0x49, + 0x44, + 0x30, + [SID_PAL_MFG_STORE_OFFSET_VERSION] = RAW_MFG_VERSION_7_VALUE, + [SID_PAL_MFG_STORE_OFFSET_SMSN] = SID_PAL_MFG_STORE_SMSN_VALUE, + [SID_PAL_MFG_STORE_OFFSET_APP_PUB_ED25519] = SID_PAL_MFG_STORE_APP_PUB_ED25519_VALUE, + [SID_PAL_MFG_STORE_OFFSET_DEVICE_PRIV_ED25519] = + SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519_VALUE, + [SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_ED25519] = SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_VALUE, + [SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_ED25519_SIGNATURE] = + SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_SIGNATURE_VALUE, + [SID_PAL_MFG_STORE_OFFSET_DEVICE_PRIV_P256R1] = SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1_VALUE, + [SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_P256R1] = SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_VALUE, + [SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_P256R1_SIGNATURE] = + SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_SIGNATURE_VALUE, + [SID_PAL_MFG_STORE_OFFSET_DAK_PUB_ED25519] = SID_PAL_MFG_STORE_DAK_PUB_ED25519_VALUE, + [SID_PAL_MFG_STORE_OFFSET_DAK_PUB_ED25519_SIGNATURE] = + SID_PAL_MFG_STORE_DAK_PUB_ED25519_SIGNATURE_VALUE, + [SID_PAL_MFG_STORE_OFFSET_DAK_ED25519_SERIAL] = SID_PAL_MFG_STORE_DAK_ED25519_SERIAL_VALUE, + [SID_PAL_MFG_STORE_OFFSET_DAK_PUB_P256R1] = SID_PAL_MFG_STORE_DAK_PUB_P256R1_VALUE, + [SID_PAL_MFG_STORE_OFFSET_DAK_PUB_P256R1_SIGNATURE] = + SID_PAL_MFG_STORE_DAK_PUB_P256R1_SIGNATURE_VALUE, + [SID_PAL_MFG_STORE_OFFSET_DAK_P256R1_SERIAL] = SID_PAL_MFG_STORE_DAK_P256R1_SERIAL_VALUE, + [SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_ED25519] = + SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_VALUE, + [SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_ED25519_SIGNATURE] = + SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_SIGNATURE_VALUE, + [SID_PAL_MFG_STORE_OFFSET_PRODUCT_ED25519_SERIAL] = + SID_PAL_MFG_STORE_PRODUCT_ED25519_SERIAL_VALUE, + [SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_P256R1] = SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_VALUE, + [SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_P256R1_SIGNATURE] = + SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_SIGNATURE_VALUE, + [SID_PAL_MFG_STORE_OFFSET_PRODUCT_P256R1_SERIAL] = + SID_PAL_MFG_STORE_PRODUCT_P256R1_SERIAL_VALUE, + [SID_PAL_MFG_STORE_OFFSET_MAN_PUB_ED25519] = SID_PAL_MFG_STORE_MAN_PUB_ED25519_VALUE, + [SID_PAL_MFG_STORE_OFFSET_MAN_PUB_ED25519_SIGNATURE] = + SID_PAL_MFG_STORE_MAN_PUB_ED25519_SIGNATURE_VALUE, + [SID_PAL_MFG_STORE_OFFSET_MAN_ED25519_SERIAL] = SID_PAL_MFG_STORE_MAN_ED25519_SERIAL_VALUE, + [SID_PAL_MFG_STORE_OFFSET_MAN_PUB_P256R1] = SID_PAL_MFG_STORE_MAN_PUB_P256R1_VALUE, + [SID_PAL_MFG_STORE_OFFSET_MAN_PUB_P256R1_SIGNATURE] = + SID_PAL_MFG_STORE_MAN_PUB_P256R1_SIGNATURE_VALUE, + [SID_PAL_MFG_STORE_OFFSET_MAN_P256R1_SERIAL] = SID_PAL_MFG_STORE_MAN_P256R1_SERIAL_VALUE, + [SID_PAL_MFG_STORE_OFFSET_SW_PUB_ED25519] = SID_PAL_MFG_STORE_SW_PUB_ED25519_VALUE, + [SID_PAL_MFG_STORE_OFFSET_SW_PUB_ED25519_SIGNATURE] = + SID_PAL_MFG_STORE_SW_PUB_ED25519_SIGNATURE_VALUE, + [SID_PAL_MFG_STORE_OFFSET_SW_ED25519_SERIAL] = SID_PAL_MFG_STORE_SW_ED25519_SERIAL_VALUE, + [SID_PAL_MFG_STORE_OFFSET_SW_PUB_P256R1] = SID_PAL_MFG_STORE_SW_PUB_P256R1_VALUE, + [SID_PAL_MFG_STORE_OFFSET_SW_PUB_P256R1_SIGNATURE] = + SID_PAL_MFG_STORE_SW_PUB_P256R1_SIGNATURE_VALUE, + [SID_PAL_MFG_STORE_OFFSET_SW_P256R1_SERIAL] = SID_PAL_MFG_STORE_SW_P256R1_SERIAL_VALUE, + [SID_PAL_MFG_STORE_OFFSET_AMZN_PUB_ED25519] = SID_PAL_MFG_STORE_AMZN_PUB_ED25519_VALUE, + [SID_PAL_MFG_STORE_OFFSET_AMZN_PUB_P256R1] = SID_PAL_MFG_STORE_AMZN_PUB_P256R1_VALUE, + [SID_PAL_MFG_STORE_OFFSET_APID] = SID_PAL_MFG_STORE_APID_VALUE +}; + +/////////////////////// + +#define MFG_HEADER_FLAGS_INITIALIZED 0x80 +#ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE +#define PSA_USED 0x40 +#else +#define PSA_USED 0x00 +#endif + +#define MFG_FLAGS MFG_HEADER_FLAGS_INITIALIZED | PSA_USED + +unsigned char expected_parsed_mfg[] = { + 0x53, 0x49, 0x44, 0x30, 0x00, + 0x00, 0x00, 0x08, + + 0x00, 0x04, 0x00, 0x20, SID_PAL_MFG_STORE_SMSN_VALUE, + + 0x00, 0x05, 0x00, 0x20, SID_PAL_MFG_STORE_APP_PUB_ED25519_VALUE, +#ifndef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE + 0x00, 0x06, 0x00, 0x20, SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519_VALUE, +#endif + 0x00, 0x07, 0x00, 0x20, SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_VALUE, + + 0x00, 0x08, 0x00, 0x40, SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_SIGNATURE_VALUE, + +#ifndef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE + 0x00, 0x09, 0x00, 0x20, SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1_VALUE, +#endif + + 0x00, 0x0a, 0x00, 0x40, SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_VALUE, + + 0x00, 0x0b, 0x00, 0x40, SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_SIGNATURE_VALUE, + + 0x00, 0x0c, 0x00, 0x20, SID_PAL_MFG_STORE_DAK_PUB_ED25519_VALUE, + + 0x00, 0x0d, 0x00, 0x40, SID_PAL_MFG_STORE_DAK_PUB_ED25519_SIGNATURE_VALUE, + + 0x00, 0x0e, 0x00, 0x04, SID_PAL_MFG_STORE_DAK_ED25519_SERIAL_VALUE, + + 0x00, 0x0f, 0x00, 0x40, SID_PAL_MFG_STORE_DAK_PUB_P256R1_VALUE, + + 0x00, 0x10, 0x00, 0x40, SID_PAL_MFG_STORE_DAK_PUB_P256R1_SIGNATURE_VALUE, + + 0x00, 0x11, 0x00, 0x04, SID_PAL_MFG_STORE_DAK_P256R1_SERIAL_VALUE, + + 0x00, 0x12, 0x00, 0x20, SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_VALUE, + + 0x00, 0x13, 0x00, 0x40, SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_SIGNATURE_VALUE, + + 0x00, 0x14, 0x00, 0x04, SID_PAL_MFG_STORE_PRODUCT_ED25519_SERIAL_VALUE, + + 0x00, 0x15, 0x00, 0x40, SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_VALUE, + + 0x00, 0x16, 0x00, 0x40, SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_SIGNATURE_VALUE, + + 0x00, 0x17, 0x00, 0x04, SID_PAL_MFG_STORE_PRODUCT_P256R1_SERIAL_VALUE, + + 0x00, 0x18, 0x00, 0x20, SID_PAL_MFG_STORE_MAN_PUB_ED25519_VALUE, + + 0x00, 0x19, 0x00, 0x40, SID_PAL_MFG_STORE_MAN_PUB_ED25519_SIGNATURE_VALUE, + + 0x00, 0x1a, 0x00, 0x04, SID_PAL_MFG_STORE_MAN_ED25519_SERIAL_VALUE, + + 0x00, 0x1b, 0x00, 0x40, SID_PAL_MFG_STORE_MAN_PUB_P256R1_VALUE, + + 0x00, 0x1c, 0x00, 0x40, SID_PAL_MFG_STORE_MAN_PUB_P256R1_SIGNATURE_VALUE, + + 0x00, 0x1d, 0x00, 0x04, SID_PAL_MFG_STORE_MAN_P256R1_SERIAL_VALUE, + + 0x00, 0x1e, 0x00, 0x20, SID_PAL_MFG_STORE_SW_PUB_ED25519_VALUE, + + 0x00, 0x1f, 0x00, 0x40, SID_PAL_MFG_STORE_SW_PUB_ED25519_SIGNATURE_VALUE, + + 0x00, 0x20, 0x00, 0x04, SID_PAL_MFG_STORE_SW_ED25519_SERIAL_VALUE, + + 0x00, 0x21, 0x00, 0x40, SID_PAL_MFG_STORE_SW_PUB_P256R1_VALUE, + + 0x00, 0x22, 0x00, 0x40, SID_PAL_MFG_STORE_SW_PUB_P256R1_SIGNATURE_VALUE, + + 0x00, 0x23, 0x00, 0x04, SID_PAL_MFG_STORE_SW_P256R1_SERIAL_VALUE, + + 0x00, 0x24, 0x00, 0x20, SID_PAL_MFG_STORE_AMZN_PUB_ED25519_VALUE, + + 0x00, 0x25, 0x00, 0x40, SID_PAL_MFG_STORE_AMZN_PUB_P256R1_VALUE, + + 0x00, 0x26, 0x00, 0x04, SID_PAL_MFG_STORE_APID_VALUE, + 0x6F, 0xFD, 0x00, 0x04, MFG_FLAGS, + 0x00, 0x00, 0x00 +}; + +/** + * @brief Set up for test. + * + * @param f Pointer to fixture. + */ +static void setUp(void *f) +{ + memset(TLV_RAM_STORAGE, 0xff, sizeof(TLV_RAM_STORAGE)); +} + +ZTEST_SUITE(real_case, NULL, NULL, setUp, NULL, NULL); + +ZTEST(real_case, test_valid_mfg_hex_v8) +{ + memcpy(TLV_RAM_STORAGE, mfg_v8_bin_raw, mfg_v8_bin_len); + tlv_ctx tlv = (tlv_ctx){ .start_offset = 0, + .end_offset = sizeof(TLV_RAM_STORAGE), + .tlv_storage_start_marker_size = 8, + .storage_impl = { .ctx = TLV_RAM_STORAGE, + .read = tlv_storage_ram_read, + .write = tlv_storage_ram_write } }; + + int ret = parse_mfg_raw_tlv(&tlv); + zassert_equal(ret, 0); + zassert_mem_equal(TLV_RAM_STORAGE, expected_parsed_mfg, sizeof(expected_parsed_mfg)); + uint32_t empty_bytes_after_tlv_size = sizeof(TLV_RAM_STORAGE) - sizeof(expected_parsed_mfg); + uint8_t *empty_bytes = sid_hal_malloc(empty_bytes_after_tlv_size); + memset(empty_bytes, 0xFF, empty_bytes_after_tlv_size); + zassert_mem_equal(&TLV_RAM_STORAGE[sizeof(expected_parsed_mfg)], empty_bytes, + empty_bytes_after_tlv_size); + sid_hal_free(empty_bytes); +} + +ZTEST(real_case, test_valid_mfg_hex_v8_flash) +{ + memcpy(TLV_RAM_STORAGE, mfg_v8_bin_raw, mfg_v8_bin_len); + + const struct device *flash_dev = DEVICE_DT_GET_OR_NULL(DT_CHOSEN(zephyr_flash_controller)); + + tlv_ctx tlv = (tlv_ctx){ .start_offset = FIXED_PARTITION_OFFSET(mfg_storage), + .end_offset = FIXED_PARTITION_OFFSET(mfg_storage) + 0x1000, + .tlv_storage_start_marker_size = 8, + .storage_impl = { .ctx = (void *)flash_dev, + .read = tlv_storage_flash_read, + .write = tlv_storage_flash_write } }; + + flash_erase(flash_dev, FIXED_PARTITION_OFFSET(mfg_storage), 0x1000); + flash_write(flash_dev, FIXED_PARTITION_OFFSET(mfg_storage), TLV_RAM_STORAGE, 0x1000); + memset(TLV_RAM_STORAGE, 0xff, sizeof(TLV_RAM_STORAGE)); + + int ret = parse_mfg_raw_tlv(&tlv); + zassert_equal(ret, 0); + + flash_read(flash_dev, FIXED_PARTITION_OFFSET(mfg_storage), TLV_RAM_STORAGE, 0x1000); + + zassert_mem_equal(TLV_RAM_STORAGE, expected_parsed_mfg, sizeof(expected_parsed_mfg)); + uint32_t empty_bytes_after_tlv_size = sizeof(TLV_RAM_STORAGE) - sizeof(expected_parsed_mfg); + uint8_t *empty_bytes = sid_hal_malloc(empty_bytes_after_tlv_size); + memset(empty_bytes, 0xFF, empty_bytes_after_tlv_size); + zassert_mem_equal(&TLV_RAM_STORAGE[sizeof(expected_parsed_mfg)], empty_bytes, + empty_bytes_after_tlv_size); + sid_hal_free(empty_bytes); +} + +static void fill_storage_v7() +{ + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_MAGIC, + (uint8_t[]){ 0x53, 0x49, 0x44, 0x30 }, + sizeof((uint8_t[]){ 0x53, 0x49, 0x44, 0x30 })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_VERSION, + (uint8_t[]){ RAW_MFG_VERSION_7_VALUE }, + sizeof((uint8_t[]){ RAW_MFG_VERSION_7_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_SMSN, + (uint8_t[]){ SID_PAL_MFG_STORE_SMSN_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_SMSN_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_APP_PUB_ED25519, + (uint8_t[]){ SID_PAL_MFG_STORE_APP_PUB_ED25519_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_APP_PUB_ED25519_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_DEVICE_PRIV_ED25519, + (uint8_t[]){ SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_DEVICE_PRIV_ED25519_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_ED25519, + (uint8_t[]){ SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_ED25519_SIGNATURE, + (uint8_t[]){ SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_SIGNATURE_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_DEVICE_PUB_ED25519_SIGNATURE_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_DEVICE_PRIV_P256R1, + (uint8_t[]){ SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_DEVICE_PRIV_P256R1_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_P256R1, + (uint8_t[]){ SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_DEVICE_PUB_P256R1_SIGNATURE, + (uint8_t[]){ SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_SIGNATURE_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_DEVICE_PUB_P256R1_SIGNATURE_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_DAK_PUB_ED25519, + (uint8_t[]){ SID_PAL_MFG_STORE_DAK_PUB_ED25519_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_DAK_PUB_ED25519_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_DAK_PUB_ED25519_SIGNATURE, + (uint8_t[]){ SID_PAL_MFG_STORE_DAK_PUB_ED25519_SIGNATURE_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_DAK_PUB_ED25519_SIGNATURE_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_DAK_ED25519_SERIAL, + (uint8_t[]){ SID_PAL_MFG_STORE_DAK_ED25519_SERIAL_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_DAK_ED25519_SERIAL_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_DAK_PUB_P256R1, + (uint8_t[]){ SID_PAL_MFG_STORE_DAK_PUB_P256R1_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_DAK_PUB_P256R1_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_DAK_PUB_P256R1_SIGNATURE, + (uint8_t[]){ SID_PAL_MFG_STORE_DAK_PUB_P256R1_SIGNATURE_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_DAK_PUB_P256R1_SIGNATURE_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_DAK_P256R1_SERIAL, + (uint8_t[]){ SID_PAL_MFG_STORE_DAK_P256R1_SERIAL_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_DAK_P256R1_SERIAL_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_ED25519, + (uint8_t[]){ SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_ED25519_SIGNATURE, + (uint8_t[]){ SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_SIGNATURE_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_PRODUCT_PUB_ED25519_SIGNATURE_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_PRODUCT_ED25519_SERIAL, + (uint8_t[]){ SID_PAL_MFG_STORE_PRODUCT_ED25519_SERIAL_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_PRODUCT_ED25519_SERIAL_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_P256R1, + (uint8_t[]){ SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_PRODUCT_PUB_P256R1_SIGNATURE, + (uint8_t[]){ SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_SIGNATURE_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_PRODUCT_PUB_P256R1_SIGNATURE_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_PRODUCT_P256R1_SERIAL, + (uint8_t[]){ SID_PAL_MFG_STORE_PRODUCT_P256R1_SERIAL_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_PRODUCT_P256R1_SERIAL_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_MAN_PUB_ED25519, + (uint8_t[]){ SID_PAL_MFG_STORE_MAN_PUB_ED25519_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_MAN_PUB_ED25519_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_MAN_PUB_ED25519_SIGNATURE, + (uint8_t[]){ SID_PAL_MFG_STORE_MAN_PUB_ED25519_SIGNATURE_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_MAN_PUB_ED25519_SIGNATURE_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_MAN_ED25519_SERIAL, + (uint8_t[]){ SID_PAL_MFG_STORE_MAN_ED25519_SERIAL_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_MAN_ED25519_SERIAL_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_MAN_PUB_P256R1, + (uint8_t[]){ SID_PAL_MFG_STORE_MAN_PUB_P256R1_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_MAN_PUB_P256R1_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_MAN_PUB_P256R1_SIGNATURE, + (uint8_t[]){ SID_PAL_MFG_STORE_MAN_PUB_P256R1_SIGNATURE_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_MAN_PUB_P256R1_SIGNATURE_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_MAN_P256R1_SERIAL, + (uint8_t[]){ SID_PAL_MFG_STORE_MAN_P256R1_SERIAL_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_MAN_P256R1_SERIAL_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_SW_PUB_ED25519, + (uint8_t[]){ SID_PAL_MFG_STORE_SW_PUB_ED25519_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_SW_PUB_ED25519_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_SW_PUB_ED25519_SIGNATURE, + (uint8_t[]){ SID_PAL_MFG_STORE_SW_PUB_ED25519_SIGNATURE_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_SW_PUB_ED25519_SIGNATURE_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_SW_ED25519_SERIAL, + (uint8_t[]){ SID_PAL_MFG_STORE_SW_ED25519_SERIAL_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_SW_ED25519_SERIAL_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_SW_PUB_P256R1, + (uint8_t[]){ SID_PAL_MFG_STORE_SW_PUB_P256R1_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_SW_PUB_P256R1_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_SW_PUB_P256R1_SIGNATURE, + (uint8_t[]){ SID_PAL_MFG_STORE_SW_PUB_P256R1_SIGNATURE_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_SW_PUB_P256R1_SIGNATURE_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_SW_P256R1_SERIAL, + (uint8_t[]){ SID_PAL_MFG_STORE_SW_P256R1_SERIAL_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_SW_P256R1_SERIAL_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_AMZN_PUB_ED25519, + (uint8_t[]){ SID_PAL_MFG_STORE_AMZN_PUB_ED25519_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_AMZN_PUB_ED25519_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_AMZN_PUB_P256R1, + (uint8_t[]){ SID_PAL_MFG_STORE_AMZN_PUB_P256R1_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_AMZN_PUB_P256R1_VALUE })); + memcpy(TLV_RAM_STORAGE + SID_PAL_MFG_STORE_OFFSET_APID, + (uint8_t[]){ SID_PAL_MFG_STORE_APID_VALUE }, + sizeof((uint8_t[]){ SID_PAL_MFG_STORE_APID_VALUE })); +} + +ZTEST(real_case, test_valid_mfg_hex_v7) +{ + fill_storage_v7(); + + tlv_ctx tlv = (tlv_ctx){ .start_offset = 0, + .end_offset = sizeof(TLV_RAM_STORAGE), + .tlv_storage_start_marker_size = 8, + .storage_impl = { .ctx = TLV_RAM_STORAGE, + .read = tlv_storage_ram_read, + .write = tlv_storage_ram_write } }; + + int ret = parse_mfg_const_offsets(&tlv); + zassert_equal(ret, 0); + zassert_mem_equal(TLV_RAM_STORAGE, expected_parsed_mfg, sizeof(expected_parsed_mfg)); + uint32_t empty_bytes_after_tlv_size = sizeof(TLV_RAM_STORAGE) - sizeof(expected_parsed_mfg); + uint8_t *empty_bytes = sid_hal_malloc(empty_bytes_after_tlv_size); + memset(empty_bytes, 0xFF, empty_bytes_after_tlv_size); + zassert_mem_equal(&TLV_RAM_STORAGE[sizeof(expected_parsed_mfg)], empty_bytes, + empty_bytes_after_tlv_size); + sid_hal_free(empty_bytes); +} + +ZTEST(real_case, test_valid_mfg_hex_v7_flash) +{ + fill_storage_v7(); + // memcpy(TLV_RAM_STORAGE, mfg_v8_bin_raw, mfg_v8_bin_len); + + const struct device *flash_dev = DEVICE_DT_GET_OR_NULL(DT_CHOSEN(zephyr_flash_controller)); + + tlv_ctx tlv = (tlv_ctx){ .start_offset = FIXED_PARTITION_OFFSET(mfg_storage), + .end_offset = FIXED_PARTITION_OFFSET(mfg_storage) + 0x1000, + .tlv_storage_start_marker_size = 8, + .storage_impl = { .ctx = (void *)flash_dev, + .read = tlv_storage_flash_read, + .write = tlv_storage_flash_write } }; + + flash_erase(flash_dev, FIXED_PARTITION_OFFSET(mfg_storage), 0x1000); + flash_write(flash_dev, FIXED_PARTITION_OFFSET(mfg_storage), TLV_RAM_STORAGE, 0x1000); + memset(TLV_RAM_STORAGE, 0xff, sizeof(TLV_RAM_STORAGE)); + + int ret = parse_mfg_const_offsets(&tlv); + zassert_equal(ret, 0); + + flash_read(flash_dev, FIXED_PARTITION_OFFSET(mfg_storage), TLV_RAM_STORAGE, 0x1000); + + zassert_mem_equal(TLV_RAM_STORAGE, expected_parsed_mfg, sizeof(expected_parsed_mfg)); + uint32_t empty_bytes_after_tlv_size = sizeof(TLV_RAM_STORAGE) - sizeof(expected_parsed_mfg); + uint8_t *empty_bytes = sid_hal_malloc(empty_bytes_after_tlv_size); + memset(empty_bytes, 0xFF, empty_bytes_after_tlv_size); + zassert_mem_equal(&TLV_RAM_STORAGE[sizeof(expected_parsed_mfg)], empty_bytes, + empty_bytes_after_tlv_size); + sid_hal_free(empty_bytes); +} diff --git a/tests/unit_tests/mfg_parsers/src/mock_mem.c b/tests/unit_tests/mfg_parsers/src/mock_mem.c new file mode 100644 index 0000000000..fb2824fee7 --- /dev/null +++ b/tests/unit_tests/mfg_parsers/src/mock_mem.c @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +#include +#include + +K_HEAP_DEFINE(test_heap, KB(30)); + +void *sid_hal_malloc(size_t size) +{ + return k_heap_alloc(&test_heap, size, K_NO_WAIT); +} + +void sid_hal_free(void *ptr) +{ + k_heap_free(&test_heap, ptr); +} diff --git a/tests/unit_tests/mfg_parsers/src/sid_crypto_keys.c b/tests/unit_tests/mfg_parsers/src/sid_crypto_keys.c new file mode 100644 index 0000000000..aca073a6d0 --- /dev/null +++ b/tests/unit_tests/mfg_parsers/src/sid_crypto_keys.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +#include +/** + * @brief Init secure key storage for Sidewalk keys. + * + * @return 0 on success, or -errno on failure. + */ +int sid_crypto_keys_init(void) +{ + return 0; +} + +/** + * @brief Import key value form buffer. + * + * @note key value under given key id will be overwritten. + * + * @param id [in] Key id to import data. + * @param data [in] raw key data on input. + * @param size [in] size of raw key data buffer. + * @return 0 on success, or -errno on failure. + */ +int sid_crypto_keys_new_import(psa_key_id_t id, uint8_t *data, size_t size) +{ + return 0; +} + +/** + * @brief Generate a new key value. + * + * @note key value under given key id will be overwritten. + * + * @param id [in] Key id to generate new. + * @param puk [in] Buffer with raw key value. + * @param puk_size [in] Size of buffer with rew kay value. + * @return 0 on success, or -errno on failure. + */ +int sid_crypto_keys_new_generate(psa_key_id_t id, uint8_t *puk, size_t puk_size) +{ + return 0; +} + +/** + * @brief Set key id in buffer. + * + * @param id [in] Key id to write to the data buffer. + * @param buffer [out] key id fulfilled with zeros. + * @param size [in] size of raw key data buffer. + * @return 0 on success, or -errno on failure. + */ +int sid_crypto_keys_buffer_set(psa_key_id_t id, uint8_t *buffer, size_t size) +{ + return 0; +} + +/** + * @brief Get key id from buffer. + * + * @param id [out] psa key id from key data buffer. + * If key not found set to PSA_KEY_ID_NULL. + * @param buffer [in] key data buffer. + * @param size [in] size of key data buffer. + * @return 0 on success, or -errno on failure. + * -ENOENT - if no key in buffer. + */ +int sid_crypto_keys_buffer_get(psa_key_id_t *id, uint8_t *buffer, size_t size) +{ + return 0; +} + +/** + * @brief Destroy key. + * + * @note This operation is irreversible. + * + * @param id [in] psa key id to be permanently removed. + * @return 0 on success, or -errno on failure. + */ +int sid_crypto_keys_delete(psa_key_id_t id) +{ + return 0; +} + +/** + * @brief Deinit sidewalk key storage. + * + * @return 0 on success, or -errno on failure. + */ +int sid_crypto_keys_deinit(void) +{ + return 0; +} diff --git a/tests/unit_tests/mfg_parsers/testcase.yaml b/tests/unit_tests/mfg_parsers/testcase.yaml new file mode 100644 index 0000000000..14f8836a41 --- /dev/null +++ b/tests/unit_tests/mfg_parsers/testcase.yaml @@ -0,0 +1,23 @@ +tests: + sidewalk.unit_tests.mfg_parser: + sysbuild: true + platform_allow: + - native_posix + - nrf52840dk/nrf52840 + - nrf5340dk/nrf5340/cpuapp + - nrf54l15pdk/nrf54l15/cpuapp + tags: Sidewalk + integration_platforms: + - native_posix + - nrf52840dk/nrf52840 + - nrf5340dk/nrf5340/cpuapp + - nrf54l15pdk/nrf54l15/cpuapp + + sidewalk.unit_tests.mfg_parser_psa_storage: + sysbuild: true + platform_allow: native_posix + tags: Sidewalk + integration_platforms: + - native_posix + extra_configs: + - CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE=y diff --git a/tests/unit_tests/pal_mfg_storage/Kconfig b/tests/unit_tests/pal_mfg_storage/Kconfig index ceac53f3be..88180e72fb 100644 --- a/tests/unit_tests/pal_mfg_storage/Kconfig +++ b/tests/unit_tests/pal_mfg_storage/Kconfig @@ -11,7 +11,7 @@ config SIDEWALK_MFG_STORAGE default y imply FLASH -config SIDEWALK_MFG_STORAGE_WRITE +config SIDEWALK_MFG_STORAGE_DIAGNOSTIC default y source "Kconfig.zephyr" diff --git a/tests/unit_tests/tlv/src/ram_backend_tests.c b/tests/unit_tests/tlv/src/ram_backend_tests.c index daf16ff447..59f3681525 100644 --- a/tests/unit_tests/tlv/src/ram_backend_tests.c +++ b/tests/unit_tests/tlv/src/ram_backend_tests.c @@ -18,43 +18,50 @@ uint8_t TLV_RAM_STORAGE[64] = { 0 }; -tlv_ctx RAM_TLV_OBJECT = (tlv_ctx){ .first_entry_offset = 0, - .last_valid_offset = sizeof(TLV_RAM_STORAGE), - .storage = { .ctx = TLV_RAM_STORAGE, - .read = tlv_storage_ram_read, - .write = tlv_storage_ram_write } }; +tlv_ctx RAM_TLV_OBJECT = (tlv_ctx){ .start_offset = 0, + .end_offset = sizeof(TLV_RAM_STORAGE), + .storage_impl = { .ctx = TLV_RAM_STORAGE, + .read = tlv_storage_ram_read, + .write = tlv_storage_ram_write } }; + +tlv_ctx RAM_TLV_OBJECT_WITH_MAGIC = (tlv_ctx){ .start_offset = 0, + .end_offset = sizeof(TLV_RAM_STORAGE), + .tlv_storage_start_marker_size = 8, + .storage_impl = { .ctx = TLV_RAM_STORAGE, + .read = tlv_storage_ram_read, + .write = tlv_storage_ram_write } }; tlv_ctx RAM_TLV_OBJECT_NO_WRITE = (tlv_ctx){ - .first_entry_offset = 0, - .last_valid_offset = sizeof(TLV_RAM_STORAGE), - .storage = { .ctx = TLV_RAM_STORAGE, .read = tlv_storage_ram_read, .write = NULL } + .start_offset = 0, + .end_offset = sizeof(TLV_RAM_STORAGE), + .storage_impl = { .ctx = TLV_RAM_STORAGE, .read = tlv_storage_ram_read, .write = NULL } }; tlv_ctx RAM_TLV_OBJECT_NO_READ = (tlv_ctx){ - .first_entry_offset = 0, - .last_valid_offset = sizeof(TLV_RAM_STORAGE), - .storage = { .ctx = TLV_RAM_STORAGE, .read = NULL, .write = tlv_storage_ram_write } + .start_offset = 0, + .end_offset = sizeof(TLV_RAM_STORAGE), + .storage_impl = { .ctx = TLV_RAM_STORAGE, .read = NULL, .write = tlv_storage_ram_write } }; -tlv_ctx RAM_TLV_OBJECT_OFFSET = (tlv_ctx){ .first_entry_offset = 3, - .last_valid_offset = sizeof(TLV_RAM_STORAGE), - .storage = { .ctx = TLV_RAM_STORAGE, - .read = tlv_storage_ram_read, - .write = tlv_storage_ram_write } }; +tlv_ctx RAM_TLV_OBJECT_OFFSET = (tlv_ctx){ .start_offset = 3, + .end_offset = sizeof(TLV_RAM_STORAGE), + .storage_impl = { .ctx = TLV_RAM_STORAGE, + .read = tlv_storage_ram_read, + .write = tlv_storage_ram_write } }; tlv_ctx RAM_TLV_OBJECT_LAST_OFFSET_LE_FIRST = - (tlv_ctx){ .first_entry_offset = 0, - .last_valid_offset = 0, - .storage = { .ctx = TLV_RAM_STORAGE, - .read = tlv_storage_ram_read, - .write = tlv_storage_ram_write } }; + (tlv_ctx){ .start_offset = 0, + .end_offset = 0, + .storage_impl = { .ctx = TLV_RAM_STORAGE, + .read = tlv_storage_ram_read, + .write = tlv_storage_ram_write } }; tlv_ctx RAM_TLV_OBJECT_LAST_OFFSET_ONLY_HEADER = - (tlv_ctx){ .first_entry_offset = 0, - .last_valid_offset = 5, - .storage = { .ctx = TLV_RAM_STORAGE, - .read = tlv_storage_ram_read, - .write = tlv_storage_ram_write } }; + (tlv_ctx){ .start_offset = 0, + .end_offset = 5, + .storage_impl = { .ctx = TLV_RAM_STORAGE, + .read = tlv_storage_ram_read, + .write = tlv_storage_ram_write } }; /** * @brief Set up for test. @@ -89,6 +96,13 @@ static void test_tlv_lookup(struct test_tlv_lookup_parameters parameters) zassert_mem_equal(&header, ¶meters.header, sizeof(header)); } +static void test_tlv_lookup_no_header(struct test_tlv_lookup_parameters parameters) +{ + memcpy(TLV_RAM_STORAGE, parameters.initial_storage_content, 64); + int ret = tlv_lookup(¶meters.tlv, parameters.tlv_type, NULL); + zassert_equal(ret, parameters.expected_return); +} + struct test_tlv_read_parameters { tlv_type tlv_type; int expected_return; @@ -126,6 +140,40 @@ static void test_tlv_write(struct test_tlv_write_parameters parameters) zassert_mem_equal(TLV_RAM_STORAGE, parameters.final_storage_content, 64); } +struct test_tlv_read_start_marker_parameters { + int expected_return; + tlv_ctx tlv; + uint8_t expect_read_data[64]; + uint8_t read_size; + uint8_t initial_storage_content[64]; +}; + +static void test_tlv_read_start_marker(struct test_tlv_read_start_marker_parameters parameters) +{ + memcpy(TLV_RAM_STORAGE, parameters.initial_storage_content, 64); + uint8_t read_data[64] = { 0 }; + int ret = tlv_read_start_marker(¶meters.tlv, read_data, parameters.read_size); + zassert_equal(ret, parameters.expected_return); + zassert_mem_equal(read_data, parameters.expect_read_data, parameters.read_size); +} + +struct test_tlv_write_start_marker_parameters { + int expected_return; + tlv_ctx tlv; + uint8_t write_data[64]; + uint8_t write_size; + uint8_t initial_storage_content[64]; + uint8_t final_storage_content[64]; +}; + +static void test_tlv_write_start_marker(struct test_tlv_write_start_marker_parameters parameters) +{ + memcpy(TLV_RAM_STORAGE, parameters.initial_storage_content, 64); + int ret = tlv_write_start_marker(¶meters.tlv, parameters.write_data, + parameters.write_size); + zassert_equal(ret, parameters.expected_return); + zassert_mem_equal(TLV_RAM_STORAGE, parameters.final_storage_content, 64); +} /* tlv lookup */ PARAMETRIZED_TEST(valid_ctx, test_tlv_lookup_0_ram_empty, test_tlv_lookup, (struct test_tlv_lookup_parameters){ @@ -140,6 +188,11 @@ PARAMETRIZED_TEST(valid_ctx, test_tlv_lookup_0xff_ram_empty, test_tlv_lookup, .tlv_type = 0xFF, .expected_return = -ENODATA }) +PARAMETRIZED_TEST(valid_ctx, test_tlv_lookup_0xff_ram_empty_no_header, test_tlv_lookup_no_header, + (struct test_tlv_lookup_parameters){ .tlv = RAM_TLV_OBJECT, + .tlv_type = 0xFF, + .expected_return = -ENODATA }) + PARAMETRIZED_TEST(valid_ctx, test_tlv_lookup_1_ram_empty, test_tlv_lookup, (struct test_tlv_lookup_parameters){ .tlv = RAM_TLV_OBJECT, .tlv_type = 1, @@ -178,6 +231,14 @@ PARAMETRIZED_TEST(valid_ctx, test_tlv_lookup_1_filled, test_tlv_lookup, .header = { .type = 1, .payload_size = { .padding = 0, .data_size = 4 } } }) +PARAMETRIZED_TEST(valid_ctx, test_tlv_lookup_1_filled_no_header, test_tlv_lookup_no_header, + (struct test_tlv_lookup_parameters){ + .tlv = RAM_TLV_OBJECT, + .initial_storage_content = { 0x0, 0x1, 0x0, 0x4, 0x1, 0x2, 0x3, 0x4 }, + .tlv_type = 1, + .expected_return = 0, + }) + PARAMETRIZED_TEST(valid_ctx, test_tlv_lookup_0xff_filled, test_tlv_lookup, (struct test_tlv_lookup_parameters){ .tlv = RAM_TLV_OBJECT, @@ -361,8 +422,72 @@ PARAMETRIZED_TEST(valid_ctx, test_tlv_write_floded_ff, test_tlv_write, .final_storage_content = { 0x01, 0x1, 0x0, 0x4, 0x1, 0x2, 0x3, 0x4, [8 ... 63] = 0xff } }) +PARAMETRIZED_TEST(valid_ctx, test_tlv_write_floded_ff_magic, test_tlv_write, + (struct test_tlv_write_parameters){ + .tlv = RAM_TLV_OBJECT_WITH_MAGIC, + .initial_storage_content = { [0 ... 63] = 0xff }, + .tlv_type = 0x101, + .expected_return = 0, + .write_data = { 0x1, 0x2, 0x3, 0x4 }, + .write_size = 4, + .final_storage_content = { [0 ... 7] = 0xff, + 0x01, + 0x1, + 0x0, + 0x4, + 0x1, + 0x2, + 0x3, + 0x4, + [16 ... 63] = 0xff } }) + +PARAMETRIZED_TEST(valid_ctx, test_tlv_read_start_marker_real, test_tlv_read_start_marker, + (struct test_tlv_read_start_marker_parameters){ + .tlv = RAM_TLV_OBJECT_WITH_MAGIC, + .initial_storage_content = { 0x53, 0x49, 0x44, 0x30, 0x00, 0x00, 0x00, + 0x08, [8 ... 63] = 0xff }, + .expected_return = 0, + .expect_read_data = { 0x53, 0x49, 0x44, 0x30, 0x00, 0x00, 0x00, 0x08 }, + .read_size = 8 }) + +PARAMETRIZED_TEST(valid_ctx, test_tlv_write_start_marker_real, test_tlv_write_start_marker, + (struct test_tlv_write_start_marker_parameters){ + .tlv = RAM_TLV_OBJECT_WITH_MAGIC, + .initial_storage_content = { [0 ... 63] = 0xff }, + .write_data = { 0x53, 0x49, 0x44, 0x30, 0x00, 0x00, 0x00, 0x08 }, + .write_size = 8, + .expected_return = 0, + .final_storage_content = { 0x53, 0x49, 0x44, 0x30, 0x00, 0x00, 0x00, 0x08, + [8 ... 63] = 0xff } }) + +PARAMETRIZED_TEST(valid_ctx, test_tlv_read_start_marker_real_nomem, test_tlv_read_start_marker, + (struct test_tlv_read_start_marker_parameters){ + .tlv = RAM_TLV_OBJECT_WITH_MAGIC, + .initial_storage_content = { 0x53, 0x49, 0x44, 0x30, 0x00, 0x00, 0x00, + 0x08, [8 ... 63] = 0xff }, + .expected_return = -ENOMEM, + .expect_read_data = { 0x0 }, + .read_size = 5 }) + +PARAMETRIZED_TEST(valid_ctx, test_tlv_write_start_marker_real_nomem, test_tlv_write_start_marker, + (struct test_tlv_write_start_marker_parameters){ + .tlv = RAM_TLV_OBJECT_WITH_MAGIC, + .initial_storage_content = { [0 ... 63] = 0xff }, + .write_data = { 0x53, 0x49, 0x44, 0x30, 0x00, 0x00, 0x00, 0x08 }, + .write_size = 12, + .expected_return = -ENOMEM, + .final_storage_content = { [0 ... 63] = 0xff } }) /* ctx not fully provided */ +PARAMETRIZED_TEST(missing_read, test_tlv_read_start_marker_real, test_tlv_read_start_marker, + (struct test_tlv_read_start_marker_parameters){ + .tlv = RAM_TLV_OBJECT_NO_READ, + .initial_storage_content = { 0x53, 0x49, 0x44, 0x30, 0x00, 0x00, 0x00, + 0x08, [8 ... 63] = 0xff }, + .expected_return = -EINVAL, + .expect_read_data = { 0 }, + .read_size = 8 }) + PARAMETRIZED_TEST(missing_read, test_tlv_lookup_1_filled, test_tlv_lookup, (struct test_tlv_lookup_parameters){ .tlv = RAM_TLV_OBJECT_NO_READ, @@ -392,6 +517,15 @@ PARAMETRIZED_TEST(missing_read, test_tlv_write_empty, test_tlv_write, .write_size = 3, }) +PARAMETRIZED_TEST(missing_write, test_tlv_write_start_marker_real, test_tlv_write_start_marker, + (struct test_tlv_write_start_marker_parameters){ + .tlv = RAM_TLV_OBJECT_NO_WRITE, + .initial_storage_content = { [0 ... 63] = 0xff }, + .write_data = { 0x53, 0x49, 0x44, 0x30, 0x00, 0x00, 0x00, 0x08 }, + .write_size = 8, + .expected_return = -EINVAL, + .final_storage_content = { [0 ... 63] = 0xff } }) + PARAMETRIZED_TEST(missing_write, test_tlv_lookup_1_filled, test_tlv_lookup, (struct test_tlv_lookup_parameters){ .tlv = RAM_TLV_OBJECT_NO_WRITE, diff --git a/tests/validation/crypto/Kconfig b/tests/validation/crypto/Kconfig index 2cb4452150..b08e2ec018 100644 --- a/tests/validation/crypto/Kconfig +++ b/tests/validation/crypto/Kconfig @@ -4,4 +4,7 @@ # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # +config SIDEWALK_MFG_STORAGE + default n + source "Kconfig.zephyr" diff --git a/tests/validation/crypto/sysbuild.conf b/tests/validation/crypto/sysbuild.conf index 7e6d419a0f..69eac613d0 100644 --- a/tests/validation/crypto/sysbuild.conf +++ b/tests/validation/crypto/sysbuild.conf @@ -4,4 +4,4 @@ # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # -SB_CONFIG_PARTITION_MANAGER=n +SB_CONFIG_PARTITION_MANAGER=y diff --git a/tests/validation/storage_kv/Kconfig b/tests/validation/storage_kv/Kconfig index 2cb4452150..b08e2ec018 100644 --- a/tests/validation/storage_kv/Kconfig +++ b/tests/validation/storage_kv/Kconfig @@ -4,4 +4,7 @@ # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # +config SIDEWALK_MFG_STORAGE + default n + source "Kconfig.zephyr" diff --git a/tests/validation/storage_kv/prj.conf b/tests/validation/storage_kv/prj.conf index 060c811818..ea7c29d7ed 100644 --- a/tests/validation/storage_kv/prj.conf +++ b/tests/validation/storage_kv/prj.conf @@ -8,6 +8,7 @@ CONFIG_ZTEST=y CONFIG_SIDEWALK=y CONFIG_SIDEWALK_DFU=n CONFIG_SIDEWALK_SUBGHZ_SUPPORT=n +CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE=n CONFIG_SIDEWALK_LOG_LEVEL_OFF=y CONFIG_NVS_LOG_LEVEL_OFF=y diff --git a/tests/validation/storage_kv/src/main.c b/tests/validation/storage_kv/src/main.c index ca598f279a..fd39de1c68 100644 --- a/tests/validation/storage_kv/src/main.c +++ b/tests/validation/storage_kv/src/main.c @@ -24,28 +24,26 @@ #define DEV_VER_SZ 2 #define PROT_VER_SZ 2 -void setUp(void *fixture) +void before_test(void *fixture) { - zassert_equal(SID_ERROR_NONE, sid_pal_storage_kv_init()); + zassert_equal(SID_ERROR_NONE, sid_pal_storage_kv_init()); } -void tearDown(void *fixture) +void after_test(void *fixture) { - sid_error_t ret; - - ret = sid_pal_storage_kv_group_delete(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID); - zassert_equal(SID_ERROR_NONE, ret); + zassert_equal(SID_ERROR_NONE, sid_pal_storage_kv_group_delete( + SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID)); } /* Helper function to populate records to test deletion */ static void set_record() { - sid_error_t ret; + sid_error_t ret; uint8_t id[DEV_ID_SZ] = {0x99, 0x88}; - ret = sid_pal_storage_kv_record_set(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DBG_DEV_ID, id, DEV_ID_SZ); - zassert_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_record_set(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DBG_DEV_ID, id, DEV_ID_SZ); + zassert_equal(SID_ERROR_NONE, ret); } static uint32_t roundup_to_word(uint32_t v) @@ -56,177 +54,177 @@ static uint32_t roundup_to_word(uint32_t v) /* Test basic record set and get */ ZTEST(storage, test_record_set_get) { - sid_error_t ret; + sid_error_t ret; uint8_t dev_id[DEV_ID_SZ] = {0xfe, 0xed, 0xfa, 0xce, 0xa1}; - uint8_t id[DEV_ID_SZ]; + uint8_t id[DEV_ID_SZ]; uint8_t dev_ver[DEV_VER_SZ] = {0x5, 0x6}; - uint8_t ver[DEV_VER_SZ]; - uint32_t len; + uint8_t ver[DEV_VER_SZ]; + uint32_t len; - ret = sid_pal_storage_kv_record_set(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DBG_DEV_ID, dev_id, DEV_ID_SZ); - zassert_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_record_set(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DBG_DEV_ID, dev_id, DEV_ID_SZ); + zassert_equal(SID_ERROR_NONE, ret); - ret = sid_pal_storage_kv_record_set(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DEV_VERSION, dev_ver, DEV_VER_SZ); - zassert_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_record_set(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DEV_VERSION, dev_ver, DEV_VER_SZ); + zassert_equal(SID_ERROR_NONE, ret); - ret = sid_pal_storage_kv_record_get_len(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DBG_DEV_ID, &len); - zassert_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_record_get_len(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DBG_DEV_ID, &len); + zassert_equal(SID_ERROR_NONE, ret); zassert_true(len>=DEV_ID_SZ); - zassert_true(len <= roundup_to_word(DEV_ID_SZ)); + zassert_true(len <= roundup_to_word(DEV_ID_SZ)); - ret = sid_pal_storage_kv_record_get(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DBG_DEV_ID, id, len); - zassert_equal(SID_ERROR_NONE, ret); - zassert_equal(0, memcmp(dev_id, id, DEV_ID_SZ)); + ret = sid_pal_storage_kv_record_get(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DBG_DEV_ID, id, len); + zassert_equal(SID_ERROR_NONE, ret); + zassert_equal(0, memcmp(dev_id, id, DEV_ID_SZ)); - ret = sid_pal_storage_kv_record_get_len(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DEV_VERSION, &len); - zassert_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_record_get_len(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DEV_VERSION, &len); + zassert_equal(SID_ERROR_NONE, ret); zassert_true(len>=DEV_VER_SZ); - zassert_true(len <= roundup_to_word(DEV_VER_SZ)); + zassert_true(len <= roundup_to_word(DEV_VER_SZ)); - ret = sid_pal_storage_kv_record_get(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DEV_VERSION, ver, DEV_VER_SZ); - zassert_equal(SID_ERROR_NONE, ret); - zassert_equal(0, memcmp(dev_ver, ver, DEV_VER_SZ)); + ret = sid_pal_storage_kv_record_get(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DEV_VERSION, ver, DEV_VER_SZ); + zassert_equal(SID_ERROR_NONE, ret); + zassert_equal(0, memcmp(dev_ver, ver, DEV_VER_SZ)); } /* Test setting record twice updates the record */ ZTEST(storage, test_record_set_twice) { - sid_error_t ret; + sid_error_t ret; uint8_t dev_id[DEV_ID_SZ] = {0xfe, 0xed, 0xfa, 0xce, 0xa1}; uint8_t dev_id2[DEV_ID_SZ] = {0xca, 0xfe, 0xf0, 0x0d, 0x5e}; - uint8_t id[DEV_ID_SZ]; - uint32_t len; + uint8_t id[DEV_ID_SZ]; + uint32_t len; - ret = sid_pal_storage_kv_record_set(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DBG_DEV_ID, dev_id, DEV_ID_SZ); - zassert_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_record_set(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DBG_DEV_ID, dev_id, DEV_ID_SZ); + zassert_equal(SID_ERROR_NONE, ret); - ret = sid_pal_storage_kv_record_set(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DBG_DEV_ID, dev_id2, DEV_ID_SZ); - zassert_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_record_set(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DBG_DEV_ID, dev_id2, DEV_ID_SZ); + zassert_equal(SID_ERROR_NONE, ret); - ret = sid_pal_storage_kv_record_get_len(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DBG_DEV_ID, &len); - zassert_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_record_get_len(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DBG_DEV_ID, &len); + zassert_equal(SID_ERROR_NONE, ret); zassert_true(len>=DEV_ID_SZ); - zassert_true(len <= roundup_to_word(DEV_ID_SZ)); + zassert_true(len <= roundup_to_word(DEV_ID_SZ)); - ret = sid_pal_storage_kv_record_get(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DBG_DEV_ID, id, len); - zassert_equal(SID_ERROR_NONE, ret); - zassert_equal(0, memcmp(dev_id2, id, DEV_ID_SZ)); + ret = sid_pal_storage_kv_record_get(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DBG_DEV_ID, id, len); + zassert_equal(SID_ERROR_NONE, ret); + zassert_equal(0, memcmp(dev_id2, id, DEV_ID_SZ)); } /* Test re-setting record after a delete */ ZTEST(storage, test_record_set_delete_set) { - sid_error_t ret; + sid_error_t ret; uint8_t dev_id[DEV_ID_SZ] = {0xfe, 0xed, 0xfa, 0xce, 0xa1}; uint8_t dev_id2[DEV_ID_SZ] = {0xca, 0xfe, 0xf0, 0x0d, 0x5e}; - uint8_t id[DEV_ID_SZ]; - uint32_t len; + uint8_t id[DEV_ID_SZ]; + uint32_t len; - ret = sid_pal_storage_kv_record_set(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DBG_DEV_ID, dev_id, DEV_ID_SZ); - zassert_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_record_set(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DBG_DEV_ID, dev_id, DEV_ID_SZ); + zassert_equal(SID_ERROR_NONE, ret); - ret = sid_pal_storage_kv_record_delete(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DBG_DEV_ID); - zassert_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_record_delete(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DBG_DEV_ID); + zassert_equal(SID_ERROR_NONE, ret); - ret = sid_pal_storage_kv_record_set(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DBG_DEV_ID, dev_id2, DEV_ID_SZ); - zassert_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_record_set(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DBG_DEV_ID, dev_id2, DEV_ID_SZ); + zassert_equal(SID_ERROR_NONE, ret); - ret = sid_pal_storage_kv_record_get_len(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DBG_DEV_ID, &len); - zassert_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_record_get_len(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DBG_DEV_ID, &len); + zassert_equal(SID_ERROR_NONE, ret); zassert_true(len>=DEV_ID_SZ); - zassert_true(len <= roundup_to_word(DEV_ID_SZ)); + zassert_true(len <= roundup_to_word(DEV_ID_SZ)); - ret = sid_pal_storage_kv_record_get(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DBG_DEV_ID, id, len); - zassert_equal(SID_ERROR_NONE, ret); - zassert_equal(0, memcmp(dev_id2, id, DEV_ID_SZ)); + ret = sid_pal_storage_kv_record_get(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DBG_DEV_ID, id, len); + zassert_equal(SID_ERROR_NONE, ret); + zassert_equal(0, memcmp(dev_id2, id, DEV_ID_SZ)); } /* Test reading non-existent record */ ZTEST(storage, test_record_get_error) { - sid_error_t ret; - uint8_t ver[DEV_VER_SZ]; + sid_error_t ret; + uint8_t ver[DEV_VER_SZ]; - ret = sid_pal_storage_kv_record_get(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_PROTOCOL_VERSION, ver, PROT_VER_SZ); - zassert_equal(SID_ERROR_NOT_FOUND, ret); + ret = sid_pal_storage_kv_record_get(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_PROTOCOL_VERSION, ver, PROT_VER_SZ); + zassert_equal(SID_ERROR_NOT_FOUND, ret); } /* Test record is properly deleted */ ZTEST(storage, test_record_delete) { - sid_error_t ret; - uint8_t id[DEV_ID_SZ]; + sid_error_t ret; + uint8_t id[DEV_ID_SZ]; - set_record(); + set_record(); - ret = sid_pal_storage_kv_record_delete(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DBG_DEV_ID); - zassert_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_record_delete(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DBG_DEV_ID); + zassert_equal(SID_ERROR_NONE, ret); - ret = sid_pal_storage_kv_record_get(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DBG_DEV_ID, id, DEV_ID_SZ); - zassert_not_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_record_get(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DBG_DEV_ID, id, DEV_ID_SZ); + zassert_not_equal(SID_ERROR_NONE, ret); } /* Test deleting non-existent record */ ZTEST(storage, test_record_delete_error) { - ztest_test_skip(); - // TEST_IGNORE_MESSAGE("There is no error on deleting non-existing record in NVS"); + ztest_test_skip(); + // TEST_IGNORE_MESSAGE("There is no error on deleting non-existing record in NVS"); - sid_error_t ret; + sid_error_t ret; - ret = sid_pal_storage_kv_record_delete(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_PROTOCOL_VERSION); - zassert_not_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_record_delete(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_PROTOCOL_VERSION); + zassert_not_equal(SID_ERROR_NONE, ret); } /* Test deleting a group removes records */ ZTEST(storage, test_record_group_delete) { - sid_error_t ret; - uint8_t id[DEV_ID_SZ]; + sid_error_t ret; + uint8_t id[DEV_ID_SZ]; - set_record(); + set_record(); - ret = sid_pal_storage_kv_group_delete(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID); - zassert_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_group_delete(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID); + zassert_equal(SID_ERROR_NONE, ret); - ret = sid_pal_storage_kv_record_get(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, - STORAGE_KV_DBG_DEV_ID, id, DEV_ID_SZ); - zassert_not_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_record_get(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID, + STORAGE_KV_DBG_DEV_ID, id, DEV_ID_SZ); + zassert_not_equal(SID_ERROR_NONE, ret); } /* Test deleting group twice */ ZTEST(storage, test_record_group_delete_error) { - sid_error_t ret; + sid_error_t ret; - set_record(); + set_record(); - ret = sid_pal_storage_kv_group_delete(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID); - zassert_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_group_delete(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID); + zassert_equal(SID_ERROR_NONE, ret); - ret = sid_pal_storage_kv_group_delete(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID); - zassert_equal(SID_ERROR_NONE, ret); + ret = sid_pal_storage_kv_group_delete(SID_PAL_STORAGE_KV_INTERNAL_PROTOCOL_GROUP_ID); + zassert_equal(SID_ERROR_NONE, ret); } -ZTEST_SUITE(storage, NULL, NULL, setUp, tearDown, NULL); +ZTEST_SUITE(storage, NULL, NULL, before_test, after_test, NULL); diff --git a/tests/validation/storage_kv/sysbuild.conf b/tests/validation/storage_kv/sysbuild.conf index 7e6d419a0f..69eac613d0 100644 --- a/tests/validation/storage_kv/sysbuild.conf +++ b/tests/validation/storage_kv/sysbuild.conf @@ -4,4 +4,4 @@ # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # -SB_CONFIG_PARTITION_MANAGER=n +SB_CONFIG_PARTITION_MANAGER=y diff --git a/tests/validation/timer/Kconfig b/tests/validation/timer/Kconfig index 2cb4452150..b08e2ec018 100644 --- a/tests/validation/timer/Kconfig +++ b/tests/validation/timer/Kconfig @@ -4,4 +4,7 @@ # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # +config SIDEWALK_MFG_STORAGE + default n + source "Kconfig.zephyr" diff --git a/tests/validation/timer/sysbuild.conf b/tests/validation/timer/sysbuild.conf index 7e6d419a0f..69eac613d0 100644 --- a/tests/validation/timer/sysbuild.conf +++ b/tests/validation/timer/sysbuild.conf @@ -4,4 +4,4 @@ # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # -SB_CONFIG_PARTITION_MANAGER=n +SB_CONFIG_PARTITION_MANAGER=y diff --git a/utils/include/tlv/tlv.h b/utils/include/tlv/tlv.h index 60c8ce3c48..b975c81551 100644 --- a/utils/include/tlv/tlv.h +++ b/utils/include/tlv/tlv.h @@ -3,6 +3,8 @@ * * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ +#ifndef TLV_H +#define TLV_H #include #include @@ -38,9 +40,13 @@ typedef struct tlv_ctx { void *ctx; tlv_storage_write_t write; tlv_storage_read_t read; - } storage; - uint32_t first_entry_offset; - uint32_t last_valid_offset; + } storage_impl; + /*starting offset of the tlv memory region, including storage marker*/ + uint32_t start_offset; + /*first offset outside valid memory range, that can not be written*/ + uint32_t end_offset; + /* size of starting marker, after the marker the first tlv entry is stored.*/ + uint32_t tlv_storage_start_marker_size; } tlv_ctx; typedef uint16_t tlv_type; @@ -54,6 +60,28 @@ typedef struct { tlv_size payload_size; } tlv_header; +/** + * @brief read the header of the TLV storage + * The header usually contains some magic value that signal start of data + * + * @param ctx tlv context + * @param data [OUT] content of header + * @param data_size size of the header to read, need to match the size passed in ctx + * @return int 0 on success, negative in case of error + */ +int tlv_read_start_marker(tlv_ctx *ctx, uint8_t *data, uint8_t data_size); + +/** + * @brief Write the header of the TLV storage + * The header usually contains some magic value that signal start of data + * + * @param ctx tlv context + * @param data [IN] content of header + * @param data_size size of the header to read, need to match the size passed in ctx + * @return int 0 on success, negative in case of error + */ +int tlv_write_start_marker(tlv_ctx *ctx, uint8_t *data, uint8_t data_size); + /** * @brief Find TLV header * @@ -94,4 +122,6 @@ int tlv_read(tlv_ctx *ctx, tlv_type type, uint8_t *data, uint16_t data_size); * -ENOMEM when can not fit data in storage * other errors are passed from storage handlers. */ -int tlv_write(tlv_ctx *ctx, tlv_type type, uint8_t *data, uint16_t data_size); +int tlv_write(tlv_ctx *ctx, tlv_type type, const uint8_t *data, uint16_t data_size); + +#endif diff --git a/utils/include/tlv/tlv_storage_impl.h b/utils/include/tlv/tlv_storage_impl.h index 9c4a41e8ab..71e4c84985 100644 --- a/utils/include/tlv/tlv_storage_impl.h +++ b/utils/include/tlv/tlv_storage_impl.h @@ -3,6 +3,8 @@ * * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ +#ifndef TLV_STORAGE_IMPL_H +#define TLV_STORAGE_IMPL_H #include @@ -15,3 +17,5 @@ int tlv_storage_ram_read(void *ctx, uint32_t offset, uint8_t *data, uint32_t dat int tlv_storage_flash_write(void *ctx, uint32_t offset, uint8_t *data, uint32_t data_size); int tlv_storage_flash_read(void *ctx, uint32_t offset, uint8_t *data, uint32_t data_size); #endif + +#endif diff --git a/utils/tlv/CMakeLists.txt b/utils/tlv/CMakeLists.txt index 2583ca7d52..a90b450c1b 100644 --- a/utils/tlv/CMakeLists.txt +++ b/utils/tlv/CMakeLists.txt @@ -10,9 +10,9 @@ zephyr_library_sources( tlv.c ) -zephyr_library_sources_ifdef(SIDEWALK_TLV_FLASH +zephyr_library_sources_ifdef(CONFIG_SIDEWALK_TLV_FLASH tlv_flash_storage_impl.c ) -zephyr_library_sources_ifdef(SIDEWALK_TLV_RAM +zephyr_library_sources_ifdef(CONFIG_SIDEWALK_TLV_RAM tlv_ram_storage_impl.c ) diff --git a/utils/tlv/tlv.c b/utils/tlv/tlv.c index 7fe507a341..ccf2b779f2 100644 --- a/utils/tlv/tlv.c +++ b/utils/tlv/tlv.c @@ -28,22 +28,24 @@ static void header_to_bytes(tlv_header header, uint8_t data[4]) int tlv_lookup(tlv_ctx *ctx, tlv_type type, tlv_header *lookup_data) { - if (ctx == NULL || ctx->storage.read == NULL) { + if (ctx == NULL || ctx->storage_impl.read == NULL) { return -EINVAL; } - for (uint32_t offset = ctx->first_entry_offset; - (offset + sizeof(tlv_header)) <= ctx->last_valid_offset;) { + for (uint32_t offset = ctx->start_offset + ctx->tlv_storage_start_marker_size; + (offset + sizeof(tlv_header)) <= ctx->end_offset;) { uint8_t header_raw[4]; - int ret = - ctx->storage.read(ctx->storage.ctx, offset, header_raw, sizeof(header_raw)); + int ret = ctx->storage_impl.read(ctx->storage_impl.ctx, offset, header_raw, + sizeof(header_raw)); if (ret != 0) { return ret; } tlv_header header = bytes_to_header(header_raw); offset += sizeof(header); if (header.type == type) { - *lookup_data = header; + if (lookup_data) { + *lookup_data = header; + } return 0; } @@ -54,15 +56,15 @@ int tlv_lookup(tlv_ctx *ctx, tlv_type type, tlv_header *lookup_data) int tlv_read(tlv_ctx *ctx, tlv_type type, uint8_t *data, uint16_t data_size) { - if (ctx == NULL || ctx->storage.read == NULL) { + if (ctx == NULL || ctx->storage_impl.read == NULL) { return -EINVAL; } - for (uint32_t offset = ctx->first_entry_offset; - (offset + sizeof(tlv_header)) <= ctx->last_valid_offset;) { + for (uint32_t offset = ctx->start_offset + ctx->tlv_storage_start_marker_size; + (offset + sizeof(tlv_header)) <= ctx->end_offset;) { uint8_t header_raw[4]; - int ret = - ctx->storage.read(ctx->storage.ctx, offset, header_raw, sizeof(header_raw)); + int ret = ctx->storage_impl.read(ctx->storage_impl.ctx, offset, header_raw, + sizeof(header_raw)); if (ret != 0) { return ret; } @@ -71,11 +73,13 @@ int tlv_read(tlv_ctx *ctx, tlv_type type, uint8_t *data, uint16_t data_size) offset += sizeof(header_raw); if (header.type == type) { - if (data_size <= header.payload_size.data_size) { - if (offset + data_size > ctx->last_valid_offset) { + if (data_size <= + header.payload_size.data_size + header.payload_size.padding) { + if (offset + data_size > ctx->end_offset) { return -ENODATA; } - return ctx->storage.read(ctx->storage.ctx, offset, data, data_size); + return ctx->storage_impl.read(ctx->storage_impl.ctx, offset, data, + data_size); } return -ENOMEM; } @@ -86,13 +90,14 @@ int tlv_read(tlv_ctx *ctx, tlv_type type, uint8_t *data, uint16_t data_size) static uint32_t get_next_free_offset(tlv_ctx *ctx) { - if (ctx->storage.read == NULL) { - return ctx->last_valid_offset; + if (ctx->storage_impl.read == NULL) { + return ctx->end_offset; } - for (uint32_t offset = ctx->first_entry_offset; offset <= ctx->last_valid_offset;) { + for (uint32_t offset = ctx->start_offset + ctx->tlv_storage_start_marker_size; + offset <= ctx->end_offset;) { uint8_t header_raw[4]; - int ret = - ctx->storage.read(ctx->storage.ctx, offset, header_raw, sizeof(header_raw)); + int ret = ctx->storage_impl.read(ctx->storage_impl.ctx, offset, header_raw, + sizeof(header_raw)); if (ret != 0) { return ret; } @@ -103,17 +108,17 @@ static uint32_t get_next_free_offset(tlv_ctx *ctx) offset += sizeof(header_raw); offset += header.payload_size.data_size + header.payload_size.padding; } - return ctx->last_valid_offset; + return ctx->end_offset; } -int tlv_write(tlv_ctx *ctx, tlv_type type, uint8_t *data, uint16_t data_size) +int tlv_write(tlv_ctx *ctx, tlv_type type, const uint8_t *data, uint16_t data_size) { - if (ctx == NULL || ctx->storage.read == NULL || ctx->storage.write == NULL) { + if (ctx == NULL || ctx->storage_impl.read == NULL || ctx->storage_impl.write == NULL) { return -EINVAL; } uint32_t next_free_offset = get_next_free_offset(ctx); - if (ctx->last_valid_offset < + if (ctx->end_offset < (next_free_offset + sizeof(tlv_header) + data_size + CALCULATE_PADDING(data_size))) { return -ENOMEM; } @@ -123,8 +128,8 @@ int tlv_write(tlv_ctx *ctx, tlv_type type, uint8_t *data, uint16_t data_size) .padding = CALCULATE_PADDING(data_size) } }; uint8_t header_raw[4] = { 0 }; header_to_bytes(header, header_raw); - int ret = ctx->storage.write(ctx->storage.ctx, next_free_offset, header_raw, - sizeof(header_raw)); + int ret = ctx->storage_impl.write(ctx->storage_impl.ctx, next_free_offset, header_raw, + sizeof(header_raw)); if (ret != 0) { return ret; } @@ -138,8 +143,8 @@ int tlv_write(tlv_ctx *ctx, tlv_type type, uint8_t *data, uint16_t data_size) uint16_t bytes_to_write = MIN((data_size - data_written), DATA_ALIGN); memcpy(write_buff, data + data_written, bytes_to_write); // write the buffer to storage - ret = ctx->storage.write(ctx->storage.ctx, next_free_offset, write_buff, - DATA_ALIGN); + ret = ctx->storage_impl.write(ctx->storage_impl.ctx, next_free_offset, write_buff, + DATA_ALIGN); if (ret != 0) { return ret; } @@ -148,3 +153,25 @@ int tlv_write(tlv_ctx *ctx, tlv_type type, uint8_t *data, uint16_t data_size) } return 0; } + +int tlv_read_start_marker(tlv_ctx *ctx, uint8_t *data, uint8_t data_size) +{ + if (ctx == NULL || ctx->storage_impl.read == NULL) { + return -EINVAL; + } + if (data_size != ctx->tlv_storage_start_marker_size) { + return -ENOMEM; + } + return ctx->storage_impl.read(ctx->storage_impl.ctx, ctx->start_offset, data, data_size); +} + +int tlv_write_start_marker(tlv_ctx *ctx, uint8_t *data, uint8_t data_size) +{ + if (ctx == NULL || ctx->storage_impl.write == NULL) { + return -EINVAL; + } + if (data_size != ctx->tlv_storage_start_marker_size) { + return -ENOMEM; + } + return ctx->storage_impl.write(ctx->storage_impl.ctx, ctx->start_offset, data, data_size); +} diff --git a/utils/tlv/tlv_flash_storage_impl.c b/utils/tlv/tlv_flash_storage_impl.c index 5830e3d1e0..5355dd414c 100644 --- a/utils/tlv/tlv_flash_storage_impl.c +++ b/utils/tlv/tlv_flash_storage_impl.c @@ -11,6 +11,7 @@ int tlv_storage_flash_write(void *ctx, uint32_t offset, uint8_t *data, uint32_t if (flash_dev == NULL) { return -ENODEV; } + flash_erase(flash_dev, offset, data_size); return flash_write(flash_dev, offset, data, data_size); }