diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index 97778a6b01f282..722e7804bc327c 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -633,6 +633,8 @@ HomePods hostapd hostname href +HSM +hsm HTTPS HW hwadr @@ -939,6 +941,7 @@ objcopy OccupancySensing OctetString OECORE +OID ol Onboarding onboardingcodes @@ -958,6 +961,7 @@ openweave OperationalCredentials operationalDataset opkg +OPTIGA optionMask optionOverride optionsMask @@ -1367,6 +1371,7 @@ transitionTime TransportMgrBase TriggerEffect TRNG +trustm TrustedRootCertificates tsan TSG diff --git a/.gitmodules b/.gitmodules index d368b904833686..1f0ea8aee593a2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -293,3 +293,7 @@ path = third_party/imgui/repo url = https://github.com/ocornut/imgui platforms = linux +[submodule "third_party/infineon/trustm/optiga-trust-m"] + path = third_party/infineon/trustm/optiga-trust-m + url = https://github.com/Infineon/optiga-trust-m + platforms = infineon diff --git a/docs/guides/README.md b/docs/guides/README.md index 67bb8b66001830..3c9e3809e017de 100644 --- a/docs/guides/README.md +++ b/docs/guides/README.md @@ -6,6 +6,7 @@ - [Apple - Testing with iPhone, iPad, macOS, Apple TV, HomePod, Watch, etc](./darwin.md) - [Espressif (ESP32) - Getting Started Guide](./esp32/README.md) - [Infineon PSoC6 - Software Update](./infineon_psoc6_software_update.md) +- [Infineon Trust M Provisioning](./infineon_trustm_provisioning.md) - [Linux - Simulated Devices](./simulated_device_linux.md) - [mbedOS - Adding a new target](./mbedos_add_new_target.md) - [mbedOS - Commissioning](./mbedos_commissioning.md) diff --git a/docs/guides/infineon_trustm_provisioning.md b/docs/guides/infineon_trustm_provisioning.md new file mode 100644 index 00000000000000..fdb9bfe8d6c676 --- /dev/null +++ b/docs/guides/infineon_trustm_provisioning.md @@ -0,0 +1,61 @@ +# Infineon OPTIGA™ Trust M Provisioning for Matter + +To use Infineon OPTIGA™ Trust M for device attestation, Provisioning for +OPTIGA™ Trust M with Matter test device Attestation certificate is needed. + +## Hardware setup: + +[Raspberry Pi 4](https://www.raspberrypi.com/products/raspberry-pi-4-model-b/) + +[OPTIGA™ Trust M S2GO](https://www.infineon.com/cms/en/product/evaluation-boards/s2go-security-optiga-m/) + +[Shield2Go Adapter for Raspberry Pi](https://www.infineon.com/cms/en/product/evaluation-boards/s2go-adapter-rasp-pi-iot/) +or Jumping Wire + +## Provisioning for OPTIGA™ Trust M + +The +[Linux Tools for OPTIGA™ Trust M ](https://github.com/Infineon/linux-optiga-trust-m) +can be used to perform provisioning by following the steps mentioned below. + +- Set up chip-tool on Raspberry Pi 4 by following the instruction listed at + [Building chip-tool on Raspberry Pi ](https://github.com/project-chip/connectedhomeip/blob/master/docs/guides/BUILDING.md#installing-prerequisites-on-raspberry-pi-4) +- Clone the repo from Infineon Public GitHub + +``` + $ git clone --recurse-submodules https://github.com/Infineon/linux-optiga-trust-m.git +``` + +- Build the Linux tools for OPTIGA™ Trust M + +``` + $ cd linux-optiga-trust-m/ + $ ./trustm_installation_aarch64_script.sh +``` + +- Run the script to generate Matter test DAC for lock-app using the public key + extracted from the Infineon pre-provisioned Certificate and store it into + 0xe0e3 + +``` +$ cd scripts/matter_provisioning/ +$ ./matter_dac_provisioning.sh +``` + +_Note:_ + +_By running this example matter_dac_provisioning.sh, the steps shown below are +executed:_ + +_Step1: Extract the public key from the Infineon pre-provisioned +Certificate(0xe0e0) using openssl command._ + +_Step2: Generate DAC test certificate using the extracted public key, Signed by +[Matter test PAI](https://github.com/project-chip/connectedhomeip/blob/v1.1-branch/credentials/development/attestation/Matter-Development-PAI-FFF1-noPID-Cert.pem)_. +Please note that production devices cannot re-use these test keys/certificates. + +_Step3: Write DAC test certificate into OPTIGA™ Trust M certificate slot +0xe0e3_ + +_Step4: Write Matter test PAI into OPTIGA™ Trust M certificate slot 0xe0e8 +and test CD into OPTIGA™ Trust M Arbitrary OID 0xf1e0._ diff --git a/examples/lock-app/infineon/psoc6/BUILD.gn b/examples/lock-app/infineon/psoc6/BUILD.gn index b575a7517cd4e9..4422ab57702de8 100644 --- a/examples/lock-app/infineon/psoc6/BUILD.gn +++ b/examples/lock-app/infineon/psoc6/BUILD.gn @@ -15,9 +15,10 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") import("//build_overrides/psoc6.gni") - import("${build_root}/config/defaults.gni") +import("${chip_root}/src/crypto/crypto.gni") import("${chip_root}/src/platform/device.gni") +import("${chip_root}/third_party/infineon/trustm/trustm_config.gni") import("${psoc6_sdk_build_root}/psoc6_executable.gni") import("${psoc6_sdk_build_root}/psoc6_sdk.gni") @@ -109,6 +110,7 @@ psoc6_executable("lock_app") { "${chip_root}/examples/providers:device_info_provider", "${chip_root}/src/lib", "${chip_root}/src/setup_payload", + "${chip_root}/third_party/infineon/trustm:optiga-trust-m", ] include_dirs += [ @@ -117,6 +119,14 @@ psoc6_executable("lock_app") { "${psoc6_project_dir}/include", ] + if (chip_enable_infineon_trustm) { + include_dirs += [ "${chip_root}/third_party/infineon/trustm" ] + } + + if (chip_enable_infineon_trustm_da) { + include_dirs += [ "${chip_root}/examples/platform/infineon/trustm" ] + } + sources = [ "${examples_plat_dir}/LEDWidget.cpp", "${examples_plat_dir}/init_psoc6Platform.cpp", diff --git a/examples/lock-app/infineon/psoc6/README.md b/examples/lock-app/infineon/psoc6/README.md index 7adc1b9b41b481..8b8ffd4b30a24f 100644 --- a/examples/lock-app/infineon/psoc6/README.md +++ b/examples/lock-app/infineon/psoc6/README.md @@ -14,6 +14,8 @@ An example showing the use of Matter on the Infineon CY8CKIT-062S2-43012 board. - [Notes](#notes) - [Cluster control](#cluster-control) - [Factory Reset](#factory-reset) + - [Building with OPTIGA™ Trust M as HSM](#build-trustm-hsm) + - [OPTIGA™ Trust M Provisioning](#provisioning-trustm) - [OTA Software Update](#ota-software-update)
@@ -55,6 +57,10 @@ will then join the network. $ cd ~/connectedhomeip $ rm -rf out/ +_To build with Infineon Hardware Security Module-OPTIGA™ Trust M for Device +attestation and other security use cases, please refer to the +[Building with OPTIGA™ Trust M as HSM](#build-trustm-hsm) for more instructions_ + ## Flashing the Application - Put CY8CKIT-062S2-43012 board on KitProg3 CMSIS-DAP Mode by pressing the @@ -128,10 +134,71 @@ commands. These power cycle the BlueTooth hardware and disable BR/EDR mode. on the board. All the data configured on the device during the initial commissioning will be deleted and device will be ready for commissioning again. - - Pressing the button again within 5 seconds will cancel the factory reset of the board. +## + +## Building with OPTIGA™ Trust M as HSM + +Infineon Hardware Security Module-OPTIGA™ Trust M is a high-end security +solution that provides an anchor of trust for connecting IoT devices to the +cloud, giving every IoT device its own unique identity. + +For different security use cases, please set the flags in +CHIPCryptoPALHsm*config.h which is located at */src/crypto/hsm/\_ + +For device attestation please enable the flag ENABLE*HSM_DEVICE_ATTESTATION in +CHIPCryptoPALHsm_config.h which is located at */src/crypto/hsm/\_ + +- Supported hardware setup: + [CY8CKIT-062S2-43012](https://www.cypress.com/CY8CKIT-062S2-43012) + + [OPTIGA™ Trust M S2GO](https://www.infineon.com/cms/en/product/evaluation-boards/s2go-security-optiga-m/) + + [MY IOT ADAPTER](https://www.infineon.com/cms/en/product/evaluation-boards/my-iot-adapter/) + +- Building + + Follow the steps to build: + + ``` + $ cd examples/lock-app/infineon/psoc6 + $ source third_party/conenctedhomeip/scripts/activate.sh + $ export PSOC6_BOARD=CY8CKIT-062S2-43012 + ``` + + Note: export PSOC6_BOARD=CY8CKIT-062S2-43012 is used to set up the + development platform and environment to use CY8CKIT-062S2-43012 board for + code compilation. + + To enable OPTIGA™ Trust M for device attestation use case: + + ``` + $ gn gen out/debug --args="chip_enable_infineon_trustm=true chip_enable_infineon_trustm_da=true" + $ ninja -C out/debug + ``` + +- To delete generated executable, libraries and object files use: + + $ cd examples/lock-app/infineon/psoc6 + $ rm -rf out/ + +- Proceed to OPTIGA™ Trust M Provisioning section to complete the credential + storage into HSM. + +### + +### OPTIGA™ Trust M Provisioning + +For the description of OPTIGA™ Trust M Provisioning with test DAC generation and +PAI and CD storage, please refer to +[Infineon OPTIGA™ Trust M Provisioning](../../../../docs/guides/infineon_trustm_provisioning.md) + +After completing OPTIGA™ Trust M Provisioning, proceed to +[Flashing the Application](#flashing-the-application) section to continue with +subsequent steps. + ## OTA Software Update For the description of Software Update process with infineon PSoC6 example diff --git a/examples/lock-app/infineon/psoc6/args.gni b/examples/lock-app/infineon/psoc6/args.gni index b65d0d8885e25d..97481474a627f8 100644 --- a/examples/lock-app/infineon/psoc6/args.gni +++ b/examples/lock-app/infineon/psoc6/args.gni @@ -19,3 +19,5 @@ import("${chip_root}/src/platform/Infineon/PSOC6/args.gni") psoc6_target_project = get_label_info(":lock_app_sdk_sources", "label_no_toolchain") +chip_enable_infineon_trustm = false +chip_enable_infineon_trustm_da = false diff --git a/examples/lock-app/infineon/psoc6/src/AppTask.cpp b/examples/lock-app/infineon/psoc6/src/AppTask.cpp index b5bd7a4edf2dcf..d38eef77ab1ab3 100644 --- a/examples/lock-app/infineon/psoc6/src/AppTask.cpp +++ b/examples/lock-app/infineon/psoc6/src/AppTask.cpp @@ -45,6 +45,14 @@ #include #include +#if CHIP_CRYPTO_HSM +#include +#endif + +#ifdef ENABLE_HSM_DEVICE_ATTESTATION +#include "DeviceAttestationCredsExampleTrustM.h" +#endif + /* OTA related includes */ #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR #include @@ -155,7 +163,12 @@ static void InitServer(intptr_t context) chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); // Initialize device attestation config +#ifdef ENABLE_HSM_DEVICE_ATTESTATION + SetDeviceAttestationCredentialsProvider(Examples::GetExampleTrustMDACProvider()); +#else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif + #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR GetAppTask().InitOTARequestor(); #endif diff --git a/examples/platform/infineon/trustm/DeviceAttestationCredsExampleTrustM.cpp b/examples/platform/infineon/trustm/DeviceAttestationCredsExampleTrustM.cpp new file mode 100644 index 00000000000000..454fbe9f89fdf5 --- /dev/null +++ b/examples/platform/infineon/trustm/DeviceAttestationCredsExampleTrustM.cpp @@ -0,0 +1,141 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "DeviceAttestationCredsExampleTrustM.h" + +#include +#include +#include +#include +#include + +#if CHIP_CRYPTO_HSM +#include +#endif + +#ifdef ENABLE_HSM_DEVICE_ATTESTATION + +#include + +/* Device attestation key ids for Trust M */ +#define DEV_ATTESTATION_KEY_ID 0xE0F0 +#define DEV_ATTESTATION_CERT_ID 0xE0E3 +#define PAI_CERT_ID 0xE0E8 +#define CERT_DECLARATION_ID 0xF1E0 + +namespace chip { +namespace Credentials { +namespace Examples { + +namespace { + +class ExampleTrustMDACProvider : public DeviceAttestationCredentialsProvider +{ +public: + CHIP_ERROR GetCertificationDeclaration(MutableByteSpan & out_cd_buffer) override; + CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override; + CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & out_dac_buffer) override; + CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & out_pai_buffer) override; + CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, MutableByteSpan & out_signature_buffer) override; +}; + +CHIP_ERROR ExampleTrustMDACProvider::GetDeviceAttestationCert(MutableByteSpan & out_dac_buffer) +{ + uint16_t buflen = (uint16_t) out_dac_buffer.size(); + ChipLogDetail(Crypto, "Get DAC certificate from trustm"); + ReturnErrorOnFailure(trustmGetCertificate(DEV_ATTESTATION_CERT_ID, out_dac_buffer.data(), &buflen)); + out_dac_buffer.reduce_size(buflen); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ExampleTrustMDACProvider::GetProductAttestationIntermediateCert(MutableByteSpan & out_pai_buffer) +{ + uint16_t buflen = (uint16_t) out_pai_buffer.size(); + ChipLogDetail(Crypto, "Get PAI certificate from trustm"); + ReturnErrorOnFailure(trustmGetCertificate(PAI_CERT_ID, out_pai_buffer.data(), &buflen)); + out_pai_buffer.reduce_size(buflen); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ExampleTrustMDACProvider::GetCertificationDeclaration(MutableByteSpan & out_cd_buffer) +{ + //-> format_version = 1 + //-> vendor_id = 0xFFF1 + //-> product_id_array = [ 0x8000, 0x8001, 0x8002, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, 0x8008, 0x8009, 0x800A, 0x800B, + // 0x800C, 0x800D, 0x800E, 0x800F, 0x8010, 0x8011, 0x8012, 0x8013, 0x8014, 0x8015, 0x8016, 0x8017, 0x8018, 0x8019, 0x801A, + // 0x801B, 0x801C, 0x801D, 0x801E, 0x801F, 0x8020, 0x8021, 0x8022, 0x8023, 0x8024, 0x8025, 0x8026, 0x8027, 0x8028, 0x8029, + // 0x802A, 0x802B, 0x802C, 0x802D, 0x802E, 0x802F, 0x8030, 0x8031, 0x8032, 0x8033, 0x8034, 0x8035, 0x8036, 0x8037, 0x8038, + // 0x8039, 0x803A, 0x803B, 0x803C, 0x803D, 0x803E, 0x803F, 0x8040, 0x8041, 0x8042, 0x8043, 0x8044, 0x8045, 0x8046, 0x8047, + // 0x8048, 0x8049, 0x804A, 0x804B, 0x804C, 0x804D, 0x804E, 0x804F, 0x8050, 0x8051, 0x8052, 0x8053, 0x8054, 0x8055, 0x8056, + // 0x8057, 0x8058, 0x8059, 0x805A, 0x805B, 0x805C, 0x805D, 0x805E, 0x805F, 0x8060, 0x8061, 0x8062, 0x8063 ] + //-> device_type_id = 0x0016 + //-> certificate_id = "ZIG20142ZB330003-24" + //-> security_level = 0 + //-> security_information = 0 + //-> version_number = 0x2694 + //-> certification_type = 0 + //-> dac_origin_vendor_id is not present + //-> dac_origin_product_id is not present + size_t buflen = out_cd_buffer.size(); + ChipLogDetail(Crypto, "Get certificate declaration from trustm"); + ReturnErrorOnFailure(trustmGetCertificate(CERT_DECLARATION_ID, out_cd_buffer.data(), (uint16_t *) &buflen)); + out_cd_buffer.reduce_size(buflen); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ExampleTrustMDACProvider::GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) +{ + // TODO: We need a real example FirmwareInformation to be populated. + out_firmware_info_buffer.reduce_size(0); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR ExampleTrustMDACProvider::SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, + MutableByteSpan & out_signature_buffer) +{ + Crypto::P256ECDSASignature signature; + Crypto::P256KeypairHSM keypair; + + ChipLogDetail(Crypto, "Sign using DA key from trustm"); + + VerifyOrReturnError(IsSpanUsable(out_signature_buffer), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsSpanUsable(message_to_sign), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(out_signature_buffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL); + + keypair.SetKeyId(DEV_ATTESTATION_KEY_ID); + keypair.provisioned_key = true; + keypair.Initialize(Crypto::ECPKeyTarget::ECDSA); + + ReturnErrorOnFailure(keypair.ECDSA_sign_msg(message_to_sign.data(), message_to_sign.size(), signature)); + + return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, out_signature_buffer); +} + +} // namespace + +DeviceAttestationCredentialsProvider * GetExampleTrustMDACProvider() +{ + static ExampleTrustMDACProvider example_dac_provider; + + return &example_dac_provider; +} + +} // namespace Examples +} // namespace Credentials +} // namespace chip + +#endif //#ifdef ENABLE_HSM_DEVICE_ATTESTATION diff --git a/examples/platform/infineon/trustm/DeviceAttestationCredsExampleTrustM.h b/examples/platform/infineon/trustm/DeviceAttestationCredsExampleTrustM.h new file mode 100644 index 00000000000000..19f5b644f98bc0 --- /dev/null +++ b/examples/platform/infineon/trustm/DeviceAttestationCredsExampleTrustM.h @@ -0,0 +1,36 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include + +namespace chip { +namespace Credentials { +namespace Examples { + +/** + * @brief Get implementation of a sample DAC provider to validate device + * attestation procedure. + * + * @returns a singleton DeviceAttestationCredentialsProvider that relies on no + * storage abstractions. + */ +DeviceAttestationCredentialsProvider * GetExampleTrustMDACProvider(); + +} // namespace Examples +} // namespace Credentials +} // namespace chip diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index afeff7ef8a2b73..300d9b9e18a11f 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -345,6 +345,7 @@ def BuildInfineonTarget(): # modifiers target.AppendModifier('ota', enable_ota_requestor=True) target.AppendModifier('updateimage', update_image=True) + target.AppendModifier('trustm', enable_trustm=True) return target diff --git a/scripts/build/builders/infineon.py b/scripts/build/builders/infineon.py index 1783faefa0ef75..4f74d14c592924 100644 --- a/scripts/build/builders/infineon.py +++ b/scripts/build/builders/infineon.py @@ -80,7 +80,8 @@ def __init__(self, app: InfineonApp = InfineonApp.LOCK, board: InfineonBoard = InfineonBoard.PSOC6BOARD, enable_ota_requestor: bool = False, - update_image: bool = False): + update_image: bool = False, + enable_trustm: bool = False): super(InfineonBuilder, self).__init__( root=app.BuildRoot(root), runner=runner) @@ -92,6 +93,9 @@ def __init__(self, self.extra_gn_options.append('chip_enable_ota_requestor=true') if update_image: self.extra_gn_options.append('build_update_image=true') + if enable_trustm: + self.extra_gn_options.append('chip_enable_infineon_trustm=true') + self.extra_gn_options.append('chip_enable_infineon_trustm_da=true') def GnBuildArgs(self): return self.extra_gn_options diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index b117fe363a994d..5ce1ff8edd328b 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -11,7 +11,7 @@ linux-fake-tests[-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-covera linux-{x64,arm64}-{rpc-console,all-clusters,all-clusters-minimal,chip-tool,thermostat,java-matter-controller,minmdns,light,lock,shell,ota-provider,ota-requestor,simulated-app1,simulated-app2,python-bindings,tv-app,tv-casting-app,bridge,dynamic-bridge,tests,chip-cert,address-resolve-tool,contact-sensor}[-nodeps][-platform-mdns][-minmdns-verbose][-libnl][-same-event-loop][-no-interactive][-ipv6only][-no-ble][-no-wifi][-no-thread][-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-coverage][-dmalloc][-clang][-test][-rpc][-with-ui] linux-x64-efr32-test-runner[-clang] imx-{chip-tool,lighting-app,thermostat,all-clusters-app,all-clusters-minimal-app,ota-provider-app}[-release] -infineon-psoc6-{lock,light,all-clusters,all-clusters-minimal}[-ota][-updateimage] +infineon-psoc6-{lock,light,all-clusters,all-clusters-minimal}[-ota][-updateimage][-trustm] k32w-{light,shell,lock,contact}[-se05x][-no-ble][-no-ota][-low-power][-nologs][-crypto-platform][-tokenizer] mbed-cy8cproto_062_4343w-{lock,light,all-clusters,all-clusters-minimal,pigweed,shell}[-release][-develop][-debug] mw320-all-clusters-app diff --git a/src/credentials/BUILD.gn b/src/credentials/BUILD.gn index da66062ad93dc2..841d3292a5b790 100644 --- a/src/credentials/BUILD.gn +++ b/src/credentials/BUILD.gn @@ -79,6 +79,10 @@ static_library("credentials") { ] } + if (chip_enable_infineon_trustm_da == true) { + sources += [ "${chip_root}/examples/platform/infineon/trustm/DeviceAttestationCredsExampleTrustM.cpp" ] + } + if (chip_device_platform == "esp32" || chip_device_platform == "nrfconnect" || chip_device_platform == "efr32" || chip_device_platform == "openiotsdk") { defines = [ "CURRENT_TIME_NOT_IMPLEMENTED=1" ] diff --git a/src/crypto/BUILD.gn b/src/crypto/BUILD.gn index d97c89737c15bc..1f6360ba7840c8 100644 --- a/src/crypto/BUILD.gn +++ b/src/crypto/BUILD.gn @@ -59,9 +59,13 @@ buildconfig_header("crypto_buildconfig") { if (chip_with_se05x == 1) { defines += [ "CHIP_CRYPTO_HSM=1" ] defines += [ "CHIP_CRYPTO_HSM_NXP=1" ] + } else if (chip_enable_infineon_trustm == true) { + defines += [ "CHIP_CRYPTO_HSM=1" ] + defines += [ "CHIP_CRYPTO_HSM_INFINEON=1" ] } else { defines += [ "CHIP_CRYPTO_HSM=0" ] defines += [ "CHIP_CRYPTO_HSM_NXP=0" ] + defines += [ "CHIP_CRYPTO_HSM_INFINEON=0" ] } } @@ -192,4 +196,16 @@ static_library("crypto") { public_deps += [ "${chip_root}/third_party/simw-top-mini:se05x" ] public_configs += [ "${chip_root}/third_party/simw-top-mini:se05x_config" ] } + + if (chip_enable_infineon_trustm == true) { + sources += [ + "hsm/infineon/CHIPCryptoPALHsm_HKDF_trustm.cpp", + "hsm/infineon/CHIPCryptoPALHsm_HMAC_trustm.cpp", + "hsm/infineon/CHIPCryptoPALHsm_P256_trustm.cpp", + "hsm/infineon/CHIPCryptoPALHsm_utils_trustm.cpp", + ] + public_deps += [ "${chip_root}/third_party/infineon/trustm:optiga-trust-m" ] + public_configs += + [ "${chip_root}/third_party/infineon/trustm:trustm_config" ] + } } diff --git a/src/crypto/crypto.gni b/src/crypto/crypto.gni index 4fc63b800826b8..0a4ef3ee62b1ad 100644 --- a/src/crypto/crypto.gni +++ b/src/crypto/crypto.gni @@ -16,6 +16,8 @@ declare_args() { # Crypto implementation: mbedtls, openssl, boringssl, platform. chip_crypto = "" chip_with_se05x = 0 + chip_enable_infineon_trustm = false + chip_enable_infineon_trustm_da = false # Compile mbedtls externally. Only used if chip_crypto == "mbedtls" chip_external_mbedtls = false diff --git a/src/crypto/hsm/infineon/CHIPCryptoPALHsm_HKDF_trustm.cpp b/src/crypto/hsm/infineon/CHIPCryptoPALHsm_HKDF_trustm.cpp new file mode 100644 index 00000000000000..6e74521291d66b --- /dev/null +++ b/src/crypto/hsm/infineon/CHIPCryptoPALHsm_HKDF_trustm.cpp @@ -0,0 +1,102 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * HSM based implementation of CHIP crypto primitives + * Based on configurations in CHIPCryptoPALHsm_config.h file, + * chip crypto apis use either HSM or rollback to software implementation. + */ + +#include "CHIPCryptoPALHsm_utils_trustm.h" +#include "optiga/optiga_util.h" +#include "optiga_crypt.h" +#include "optiga_lib_types.h" +#include + +static const uint8_t metadata[] = { + // Metadata tag in the data object + 0x20, + 0x06, + // Data object type set to PRESSEC + 0xE8, + 0x01, + 0x21, + 0xD3, + 0x01, + 0x00, +}; + +#if ENABLE_HSM_HKDF_SHA256 + +namespace chip { +namespace Crypto { + +CHIP_ERROR HKDF_shaHSM::HKDF_SHA256(const uint8_t * secret, const size_t secret_length, const uint8_t * salt, + const size_t salt_length, const uint8_t * info, const size_t info_length, uint8_t * out_buffer, + size_t out_length) +{ + CHIP_ERROR error = CHIP_ERROR_INTERNAL; + optiga_lib_status_t return_status = OPTIGA_LIB_BUSY; + + uint16_t salt_length_u16 = static_cast(salt_length); + uint16_t info_length_u16 = static_cast(info_length); + uint16_t out_length_u16 = static_cast(out_length); + uint16_t secret_length_u16 = static_cast(secret_length); + + if (salt_length > 64 || info_length > 80 || secret_length > 256 || out_length > 768) + { + /* Length not supported by trustm. Rollback to SW */ + return HKDF_sha::HKDF_SHA256(secret, secret_length, salt, salt_length, info, info_length, out_buffer, out_length); + } + + // Salt is optional + if (salt_length > 0) + { + VerifyOrReturnError(salt != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + } + VerifyOrReturnError(info_length > 0, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(info != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(out_length > 0, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(out_buffer != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(secret != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + + // Trust M init + trustm_Open(); + // Write metada + write_metadata(TRUSTM_HKDF_OID_KEY, metadata, sizeof(metadata)); + // Write the secret key + write_data(TRUSTM_HKDF_OID_KEY, secret, secret_length_u16); + + return_status = OPTIGA_LIB_BUSY; + + return_status = deriveKey_HKDF(salt, salt_length_u16, info, info_length_u16, out_length_u16, TRUE, out_buffer); + + VerifyOrExit(return_status == OPTIGA_LIB_SUCCESS, error = CHIP_ERROR_INTERNAL); + error = CHIP_NO_ERROR; + +exit: + if (error != CHIP_NO_ERROR) + { + trustm_close(); + } + return error; +} +} // namespace Crypto +} // namespace chip + +#endif //#if ENABLE_HSM_HKDF_SHA256 diff --git a/src/crypto/hsm/infineon/CHIPCryptoPALHsm_HMAC_trustm.cpp b/src/crypto/hsm/infineon/CHIPCryptoPALHsm_HMAC_trustm.cpp new file mode 100644 index 00000000000000..714e16300ef5d9 --- /dev/null +++ b/src/crypto/hsm/infineon/CHIPCryptoPALHsm_HMAC_trustm.cpp @@ -0,0 +1,97 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * HSM based implementation of CHIP crypto primitives + * Based on configurations in CHIPCryptoPALHsm_config.h file, + * chip crypto apis use either HSM or rollback to software implementation. + */ + +#include "CHIPCryptoPALHsm_utils_trustm.h" +#include "optiga/optiga_util.h" +#include "optiga_crypt.h" +#include "optiga_lib_types.h" +#include + +static const uint8_t metadata_hmac[] = { + // Metadata tag in the data object + 0x20, + 0x06, + // Data object type set to PRESSEC + 0xE8, + 0x01, + 0x21, + 0xD3, + 0x01, + 0x00, +}; + +#if ENABLE_HSM_HMAC_SHA256 + +namespace chip { +namespace Crypto { + +CHIP_ERROR HMAC_shaHSM::HMAC_SHA256(const uint8_t * key, size_t key_length, const uint8_t * message, size_t message_length, + uint8_t * out_buffer, size_t out_length) + +{ + CHIP_ERROR error = CHIP_ERROR_INTERNAL; + optiga_lib_status_t return_status = OPTIGA_LIB_BUSY; + + uint16_t key_length_u16 = static_cast(key_length); + uint32_t message_length_u32 = static_cast(message_length); + uint32_t out_length_u32 = static_cast(out_length); + + if (key_length > 64) + { + return HMAC_sha::HMAC_SHA256(key, key_length, message, message_length, out_buffer, out_length); + } + VerifyOrReturnError(key_length > 0, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(message != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(message_length > 0, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(out_length > 0, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(out_buffer != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(key != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + + // Trust M init + trustm_Open(); + // Write metada for secret OID + write_metadata(TRUSTM_HMAC_OID_KEY, metadata_hmac, sizeof(metadata_hmac)); + // Update the secret key + write_data(TRUSTM_HMAC_OID_KEY, key, key_length_u16); + + // Start HMAC operation + return_status = OPTIGA_LIB_BUSY; + + // What is the max length supported ? + return_status = hmac_sha256(OPTIGA_HMAC_SHA_256, message, message_length_u32, out_buffer, &out_length_u32); + + VerifyOrExit(return_status == OPTIGA_LIB_SUCCESS, error = CHIP_ERROR_INTERNAL); + error = CHIP_NO_ERROR; + +exit: + if (error != CHIP_NO_ERROR) + { + trustm_close(); + } + return error; +} +} // namespace Crypto +} // namespace chip + +#endif // #if ENABLE_HSM_HMAC_SHA256 diff --git a/src/crypto/hsm/infineon/CHIPCryptoPALHsm_P256_trustm.cpp b/src/crypto/hsm/infineon/CHIPCryptoPALHsm_P256_trustm.cpp new file mode 100644 index 00000000000000..e5aab885b4ee23 --- /dev/null +++ b/src/crypto/hsm/infineon/CHIPCryptoPALHsm_P256_trustm.cpp @@ -0,0 +1,278 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * HSM based implementation of CHIP crypto primitives + * Based on configurations in CHIPCryptoPALHsm_config.h file, + * chip crypto apis use either HSM or rollback to software implementation. + */ + +#include "CHIPCryptoPALHsm_utils_trustm.h" +#include "optiga/optiga_util.h" +#include "optiga_crypt.h" +#include "optiga_lib_common.h" +#include "optiga_lib_types.h" +#include + +#define NIST256_HEADER_OFFSET 26 + +#if ENABLE_HSM_GENERATE_EC_KEY + +namespace chip { +namespace Crypto { + +P256KeypairHSM::~P256KeypairHSM() {} + +CHIP_ERROR P256KeypairHSM::Initialize(ECPKeyTarget key_target) +{ + CHIP_ERROR error = CHIP_ERROR_INTERNAL; + optiga_lib_status_t return_status = OPTIGA_LIB_BUSY; + uint8_t pubkey[128] = { + 0, + }; + uint16_t pubKeyLen = sizeof(pubkey); + + if (keyid == 0) + { + ChipLogDetail(Crypto, "Keyid not set !. Set key id using 'SetKeyId' member class !"); + return CHIP_ERROR_INTERNAL; + } + + // Trust M init + trustm_Open(); + if (provisioned_key == false) + { + // Trust M ECC 256 Key Gen + ChipLogDetail(Crypto, "Generating NIST256 key in Trust M !"); + uint8_t key_usage = (optiga_key_usage_t)(OPTIGA_KEY_USAGE_SIGN | OPTIGA_KEY_USAGE_AUTHENTICATION); + return_status = trustm_ecc_keygen(OPTIGA_KEY_ID_E0F2, key_usage, OPTIGA_ECC_CURVE_NIST_P_256, pubkey, pubKeyLen); + VerifyOrExit(return_status == OPTIGA_LIB_SUCCESS, error = CHIP_ERROR_INTERNAL); + } + else + { + // Read out the public Key stored + ChipLogDetail(Crypto, "Provisioned_key - %lx !", keyid); + trustmGetKey(TRUSTM_P256_PUBKEY_OID_KEY, pubkey, &pubKeyLen); + + /* Set the public key */ + P256PublicKeyHSM & public_key = const_cast(Pubkey()); + VerifyOrReturnError((size_t) pubKeyLen > NIST256_HEADER_OFFSET, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(((size_t) pubKeyLen - NIST256_HEADER_OFFSET) <= kP256_PublicKey_Length, CHIP_ERROR_INTERNAL); + memcpy((void *) Uint8::to_const_uchar(public_key), pubkey, pubKeyLen); + public_key.SetPublicKeyId(keyid); + } + error = CHIP_NO_ERROR; +exit: + if (error != CHIP_NO_ERROR) + { + trustm_close(); + } + return error; +} +CHIP_ERROR P256KeypairHSM::ECDSA_sign_msg(const uint8_t * msg, size_t msg_length, P256ECDSASignature & out_signature) const +{ + CHIP_ERROR error = CHIP_ERROR_INTERNAL; + + uint8_t signature_trustm[kMax_ECDSA_Signature_Length_Der] = { 0 }; + uint16_t signature_trustm_len = (uint16_t) kMax_ECDSA_Signature_Length_Der; + uint8_t digest[32]; + uint8_t digest_length = sizeof(digest); + + memset(&digest[0], 0, sizeof(digest)); + MutableByteSpan out_raw_sig_span(out_signature.Bytes(), out_signature.Capacity()); + + optiga_lib_status_t return_status = OPTIGA_LIB_BUSY; + + VerifyOrReturnError(msg != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(msg_length > 0, CHIP_ERROR_INVALID_ARGUMENT); + + // Trust M Init + trustm_Open(); + // Hash to get the digest + Hash_SHA256(msg, msg_length, &digest[0]); + // Api call to calculate the signature + return_status = trustm_ecdsa_sign(OPTIGA_KEY_ID_E0F0, digest, digest_length, signature_trustm, &signature_trustm_len); + + VerifyOrExit(return_status == OPTIGA_LIB_SUCCESS, error = CHIP_ERROR_INTERNAL); + + error = EcdsaAsn1SignatureToRaw(kP256_FE_Length, ByteSpan{ signature_trustm, signature_trustm_len }, out_raw_sig_span); + + ChipLogError(NotSpecified, "EcdsaAsn1SignatureToRaw %" CHIP_ERROR_FORMAT, error.Format()); + + SuccessOrExit(error); + + SuccessOrExit(out_signature.SetLength(2 * kP256_FE_Length)); + + error = CHIP_NO_ERROR; + +exit: + if (error != CHIP_NO_ERROR) + { + trustm_close(); + } + return error; +} + +CHIP_ERROR P256KeypairHSM::ECDH_derive_secret(const P256PublicKey & remote_public_key, P256ECDHDerivedSecret & out_secret) const +{ + // Use the software based one + return P256Keypair::ECDH_derive_secret(remote_public_key, out_secret); +} + +CHIP_ERROR P256PublicKeyHSM::ECDSA_validate_hash_signature(const uint8_t * hash, size_t hash_length, + const P256ECDSASignature & signature) const +{ + CHIP_ERROR error = CHIP_ERROR_INTERNAL; + optiga_lib_status_t return_status = OPTIGA_LIB_BUSY; + uint8_t signature_trustm[kMax_ECDSA_Signature_Length_Der] = { 0 }; + size_t signature_trustm_len = sizeof(signature_trustm); + MutableByteSpan out_der_sig_span(signature_trustm, signature_trustm_len); + + uint8_t hash_length_u8 = static_cast(hash_length); + uint16_t signature_trustm_len_u16 = static_cast(signature_trustm_len); + + VerifyOrReturnError(hash != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(hash_length > 0, CHIP_ERROR_INVALID_ARGUMENT); + ChipLogDetail(Crypto, "ECDSA_validate_hash_signature: Using TrustM for TrustM verify (hash) !"); + + // Trust M init + trustm_Open(); + error = EcdsaRawSignatureToAsn1(kP256_FE_Length, ByteSpan{ Uint8::to_const_uchar(signature.ConstBytes()), signature.Length() }, + out_der_sig_span); + SuccessOrExit(error); + + /* Set the public key */ + // P256PublicKeyHSM & public_key = const_cast(Pubkey()); + signature_trustm_len = out_der_sig_span.size(); + // ECC verify + return_status = trustm_ecdsa_verify((uint8_t *) hash, hash_length_u8, (uint8_t *) signature_trustm, signature_trustm_len_u16, + (uint8_t *) bytes, (uint8_t) kP256_PublicKey_Length); + + VerifyOrExit(return_status == OPTIGA_LIB_SUCCESS, error = CHIP_ERROR_INTERNAL); + +exit: + if (error != CHIP_NO_ERROR) + { + trustm_close(); + } + return error; +} + +CHIP_ERROR P256KeypairHSM::Serialize(P256SerializedKeypair & output) const +{ + const size_t len = output.Length() == 0 ? output.Capacity() : output.Length(); + Encoding::BufferWriter bbuf(output.Bytes(), len); + uint8_t privkey[kP256_PrivateKey_Length] = { + 0, + }; + + /* Set the public key */ + P256PublicKeyHSM & public_key = const_cast(Pubkey()); + bbuf.Put(Uint8::to_uchar(public_key), public_key.Length()); + + VerifyOrReturnError(bbuf.Available() == sizeof(privkey), CHIP_ERROR_INTERNAL); + VerifyOrReturnError(sizeof(privkey) >= 4, CHIP_ERROR_INTERNAL); + + /* When HSM is used for ECC key generation, store key info in private key buffer */ + Encoding::LittleEndian::BufferWriter privkey_bbuf(privkey, sizeof(privkey)); + privkey_bbuf.Put32(keyid); + + bbuf.Put(privkey, sizeof(privkey)); + VerifyOrReturnError(bbuf.Fit(), CHIP_ERROR_BUFFER_TOO_SMALL); + + output.SetLength(bbuf.Needed()); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR P256KeypairHSM::Deserialize(P256SerializedKeypair & input) +{ + /* Set the public key */ + P256PublicKeyHSM & public_key = const_cast(Pubkey()); + Encoding::BufferWriter bbuf((uint8_t *) Uint8::to_const_uchar(public_key), public_key.Length()); + + VerifyOrReturnError(input.Length() == public_key.Length() + kP256_PrivateKey_Length, CHIP_ERROR_INVALID_ARGUMENT); + bbuf.Put(input.ConstBytes(), public_key.Length()); + + /* Set private key info */ + VerifyOrReturnError(bbuf.Fit(), CHIP_ERROR_NO_MEMORY); + + /* When HSM is used for ECC key generation, key info in stored in private key buffer */ + const uint8_t * privkey = input.ConstBytes() + public_key.Length(); + keyid = Encoding::LittleEndian::Get32(privkey); + public_key.SetPublicKeyId(keyid); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR P256PublicKeyHSM::ECDSA_validate_msg_signature(const uint8_t * msg, size_t msg_length, + const P256ECDSASignature & signature) const +{ + CHIP_ERROR error = CHIP_ERROR_INTERNAL; + uint8_t signature_trustm[kMax_ECDSA_Signature_Length_Der] = { 0 }; + size_t signature_trustm_len = sizeof(signature_trustm); + uint8_t digest[32]; + uint8_t digest_length = sizeof(digest); + MutableByteSpan out_der_sig_span(signature_trustm, signature_trustm_len); + optiga_lib_status_t return_status = OPTIGA_LIB_BUSY; + uint16_t signature_trustm_len_u16 = static_cast(signature_trustm_len); + + VerifyOrReturnError(msg != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(msg_length > 0, CHIP_ERROR_INVALID_ARGUMENT); + + ChipLogDetail(Crypto, "ECDSA_validate_msg_signature: Using TrustM for TrustM verify (msg) !"); + + // Trust M init + trustm_Open(); + + error = EcdsaRawSignatureToAsn1(kP256_FE_Length, ByteSpan{ Uint8::to_const_uchar(signature.ConstBytes()), signature.Length() }, + out_der_sig_span); + SuccessOrExit(error); + + /* Set the public key */ + // P256PublicKeyHSM & public_key = const_cast(Pubkey()); + signature_trustm_len = out_der_sig_span.size(); + // Hash to get the digest + memset(&digest[0], 0, sizeof(digest)); + Hash_SHA256(msg, msg_length, &digest[0]); + // ECC verify + return_status = trustm_ecdsa_verify(digest, digest_length, (uint8_t *) signature_trustm, signature_trustm_len_u16, + (uint8_t *) bytes, (uint8_t) kP256_PublicKey_Length); + + VerifyOrExit(return_status == OPTIGA_LIB_SUCCESS, error = CHIP_ERROR_INTERNAL); + +exit: + if (error != CHIP_NO_ERROR) + { + trustm_close(); + } + return error; +} + +CHIP_ERROR P256KeypairHSM::NewCertificateSigningRequest(uint8_t * csr, size_t & csr_length) const +{ + MutableByteSpan out_csr(csr, csr_length); + CHIP_ERROR err = GenerateCertificateSigningRequest(this, out_csr); + csr_length = (CHIP_NO_ERROR == err) ? out_csr.size() : 0; + return err; +} + +} // namespace Crypto +} // namespace chip + +#endif //#if ENABLE_HSM_GENERATE_EC_KEY diff --git a/src/crypto/hsm/infineon/CHIPCryptoPALHsm_utils_trustm.cpp b/src/crypto/hsm/infineon/CHIPCryptoPALHsm_utils_trustm.cpp new file mode 100644 index 00000000000000..6378572574b3c0 --- /dev/null +++ b/src/crypto/hsm/infineon/CHIPCryptoPALHsm_utils_trustm.cpp @@ -0,0 +1,923 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * HSM based implementation of CHIP crypto primitives + * Based on configurations in CHIPCryptoPALHsm_config.h file, + * chip crypto apis use either HSM or rollback to software implementation. + */ + +/* OPTIGA(TM) Trust M includes */ +#include "CHIPCryptoPALHsm_utils_trustm.h" +#include "ifx_i2c_config.h" +#include "mbedtls/base64.h" +#include "optiga_crypt.h" +#include "optiga_lib_types.h" +#include "optiga_util.h" +#include "pal.h" +#include "pal_ifx_i2c_config.h" +#include "pal_os_event.h" +#include "pal_os_memory.h" +#include "pal_os_timer.h" +#include + +optiga_crypt_t * p_local_crypt = NULL; +optiga_util_t * p_local_util = NULL; +static bool trustm_isOpen = false; +#define ENABLE_HMAC_MULTI_STEP (0) +#define OPTIGA_UTIL_DER_BITSTRING_TAG (0x03) +#define OPTIGA_UTIL_DER_NUM_UNUSED_BITS (0x00) + +#if ENABLE_HMAC_MULTI_STEP +#define MAX_MAC_DATA_LEN 640 +#endif + +// ================================================================================ +// FreeRTOS Callbacks +// ================================================================================ + +/* This is a place from which we can poll the status of operation */ + +void vApplicationTickHook(void); + +void vApplicationTickHook(void) +{ + pal_os_event_trigger_registered_callback(); +} + +#define WAIT_FOR_COMPLETION(ret) \ + if (OPTIGA_LIB_SUCCESS != ret) \ + { \ + break; \ + } \ + while (optiga_lib_status == OPTIGA_LIB_BUSY) \ + { \ + pal_os_event_trigger_registered_callback(); \ + } \ + \ + if (OPTIGA_LIB_SUCCESS != optiga_lib_status) \ + { \ + ret = optiga_lib_status; \ + printf("Error: 0x%02X \r\n", optiga_lib_status); \ + break; \ + } + +#define CHECK_RESULT(expr) \ + optiga_lib_status_t return_status = (int32_t) OPTIGA_DEVICE_ERROR; \ + \ + do \ + { \ + optiga_lib_status = OPTIGA_LIB_BUSY; \ + return_status = expr; \ + WAIT_FOR_COMPLETION(return_status); \ + } while (0); \ + \ + return return_status; + +static volatile optiga_lib_status_t optiga_lib_status; + +static void optiga_util_callback(void * context, optiga_lib_status_t return_status) +{ + optiga_lib_status = return_status; +} + +// lint --e{818} suppress "argument "context" is not used in the sample provided" +static void optiga_crypt_callback(void * context, optiga_lib_status_t return_status) +{ + optiga_lib_status = return_status; + if (NULL != context) + { + // callback to upper layer here + } +} + +/* Open session to trustm */ +/********************************************************************** + * trustm_Open() + **********************************************************************/ +void trustm_Open(void) +{ + if (!trustm_isOpen) + { + optiga_lib_status_t return_status; + do + { + /** + * 1. Create OPTIGA Crypt Instance + */ + p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); + if (NULL == p_local_crypt) + { + break; + } + // printf("trustm created crypt Instance \r\n"); + /** + * 1. Create OPTIGA Util Instance + */ + p_local_util = optiga_util_create(0, optiga_util_callback, NULL); + if (NULL == p_local_util) + { + break; + } + // printf("trustm created util Instance \r\n"); + /** + * Open the application on OPTIGA which is a precondition to perform any other operations + * using optiga_util_open_application + */ + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_util_open_application(p_local_util, 0); // skip restore + while (optiga_lib_status == OPTIGA_LIB_BUSY) + ; + + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_util_open_application api returns error !!! + printf("optiga_util_open_application api returns error !!!\n"); + break; + } + + while (optiga_lib_status == OPTIGA_LIB_BUSY) + ; + if (OPTIGA_LIB_SUCCESS != optiga_lib_status) + { + // optiga_util_open_application failed + printf("optiga_util_open_application failed\n"); + break; + } + + // printf("trustm open application successful \r\n"); + + } while (0); + + // p_local_util and p_local_crypt instance can be destroyed + // if no close_application w.r.t hibernate is required to be performed + if (p_local_util || p_local_crypt) + { + optiga_util_destroy(p_local_util); + optiga_crypt_destroy(p_local_crypt); + } + trustm_isOpen = true; + } +} + +void trustm_close(void) +{ + optiga_lib_status_t return_status = OPTIGA_DEVICE_ERROR; + + do + { + /** + * Close the application on OPTIGA after all the operations are executed + * using optiga_util_close_application + */ + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_util_close_application(p_local_util, 0); + if (OPTIGA_LIB_SUCCESS != return_status) + break; + + while (optiga_lib_status == OPTIGA_LIB_BUSY) + { + pal_os_event_trigger_registered_callback(); + } + + // destroy util and crypt instances + optiga_util_destroy(p_local_util); + optiga_crypt_destroy(p_local_crypt); + pal_os_event_destroy(NULL); + + return_status = OPTIGA_LIB_SUCCESS; + } while (0); +} + +void read_certificate_from_optiga(uint16_t optiga_oid, char * cert_pem, uint16_t * cert_pem_length) +{ + size_t ifx_cert_b64_len = 0; + uint8_t ifx_cert_b64_temp[1200]; + uint16_t offset_to_write = 0, offset_to_read = 0; + uint16_t size_to_copy = 0; + optiga_lib_status_t return_status; + + optiga_util_t * me_util = NULL; + uint8_t ifx_cert_hex[1024]; + uint16_t ifx_cert_hex_len = sizeof(ifx_cert_hex); + + do + { + // Create an instance of optiga_util to read the certificate from OPTIGA. + me_util = optiga_util_create(0, optiga_util_callback, NULL); + if (!me_util) + { + optiga_lib_print_message("optiga_util_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_util_read_data(me_util, optiga_oid, 0, ifx_cert_hex, &ifx_cert_hex_len); + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_util_read_data api returns error !!! + optiga_lib_print_message("optiga_util_read_data api returns error !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + + while (optiga_lib_status == OPTIGA_LIB_BUSY) + ; + if (OPTIGA_LIB_SUCCESS != optiga_lib_status) + { + // optiga_util_read_data failed + optiga_lib_print_message("optiga_util_read_data failed", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + + // convert to PEM format + // If the first byte is TLS Identity Tag, than we need to skip 9 first bytes + offset_to_read = ifx_cert_hex[0] == 0xc0 ? 9 : 0; + mbedtls_base64_encode((unsigned char *) ifx_cert_b64_temp, sizeof(ifx_cert_b64_temp), &ifx_cert_b64_len, + ifx_cert_hex + offset_to_read, ifx_cert_hex_len - offset_to_read); + + memcpy(cert_pem, "-----BEGIN CERTIFICATE-----\n", 28); + offset_to_write += 28; + + // Properly copy certificate and format it as pkcs expects + for (offset_to_read = 0; offset_to_read < (uint16_t) ifx_cert_b64_len;) + { + // The last block of data usually is less than 64, thus we need to find the leftover + if ((offset_to_read + 64) >= (uint16_t) ifx_cert_b64_len) + size_to_copy = (uint16_t) ifx_cert_b64_len - offset_to_read; + else + size_to_copy = 64; + memcpy(cert_pem + offset_to_write, ifx_cert_b64_temp + offset_to_read, size_to_copy); + offset_to_write += size_to_copy; + offset_to_read += size_to_copy; + cert_pem[offset_to_write] = '\n'; + offset_to_write++; + } + + memcpy(cert_pem + offset_to_write, "-----END CERTIFICATE-----\n\0", 27); + + *cert_pem_length = offset_to_write + 27; + + } while (0); + + // me_util instance to be destroyed + if (me_util) + { + optiga_util_destroy(me_util); + } +} +void write_data(uint16_t optiga_oid, const uint8_t * p_data, uint16_t length) +{ + optiga_util_t * me_util = NULL; + optiga_lib_status_t return_status; + + do + { + // Create an instance of optiga_util to open the application on OPTIGA. + me_util = optiga_util_create(0, optiga_util_callback, NULL); + if (!me_util) + { + optiga_lib_print_message("optiga_util_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_util_write_data(me_util, optiga_oid, OPTIGA_UTIL_ERASE_AND_WRITE, 0, p_data, length); + { + if (OPTIGA_LIB_SUCCESS != return_status) + { + optiga_lib_print_message("optiga_util_wirte_data api returns error !!!", OPTIGA_UTIL_SERVICE, + OPTIGA_UTIL_SERVICE_COLOR); + break; + } + + while (OPTIGA_LIB_BUSY == optiga_lib_status) + { + // Wait until the optiga_util_write_data operation is completed + } + + if (OPTIGA_LIB_SUCCESS != optiga_lib_status) + { + optiga_lib_print_message("optiga_util_write_data failed", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + return_status = optiga_lib_status; + break; + } + else + { + optiga_lib_print_message("optiga_util_write_data successful", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + } + } + } while (0); + + // me_util instance can be destroyed + // if no close_application w.r.t hibernate is required to be performed + if (me_util) + { + optiga_util_destroy(me_util); + } +} + +void write_metadata(uint16_t optiga_oid, const uint8_t * p_data, uint8_t length) +{ + optiga_util_t * me_util = NULL; + optiga_lib_status_t return_status; + + do + { + // Create an instance of optiga_util to open the application on OPTIGA. + me_util = optiga_util_create(0, optiga_util_callback, NULL); + if (!me_util) + { + optiga_lib_print_message("optiga_util_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_util_write_metadata(me_util, optiga_oid, p_data, length); + { + if (OPTIGA_LIB_SUCCESS != return_status) + { + optiga_lib_print_message("optiga_util_wirte_data api returns error !!!", OPTIGA_UTIL_SERVICE, + OPTIGA_UTIL_SERVICE_COLOR); + break; + } + + while (OPTIGA_LIB_BUSY == optiga_lib_status) + { + // Wait until the optiga_util_write_metadata operation is completed + } + + if (OPTIGA_LIB_SUCCESS != optiga_lib_status) + { + optiga_lib_print_message("optiga_util_write_metadata failed", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + return_status = optiga_lib_status; + break; + } + else + { + optiga_lib_print_message("optiga_util_write_metadata successful", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + } + } + } while (0); + + // me_util instance can be destroyed + // if no close_application w.r.t hibernate is required to be performed + if (me_util) + { + optiga_util_destroy(me_util); + } +} + +optiga_lib_status_t deriveKey_HKDF(const uint8_t * salt, uint16_t salt_length, const uint8_t * info, uint16_t info_length, + uint16_t derived_key_length, bool_t export_to_host, uint8_t * derived_key) +{ + optiga_lib_status_t return_status; + + do + { + // Create an instance of optiga_crypt_t + p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); + if (NULL == p_local_crypt) + { + optiga_lib_print_message("optiga_crypt_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_crypt_hkdf(p_local_crypt, OPTIGA_HKDF_SHA_256, TRUSTM_HKDF_OID_KEY, /* Input secret OID */ + salt, salt_length, info, info_length, derived_key_length, TRUE, derived_key); + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_crypt_hkdf api returns error !!! + optiga_lib_print_message("optiga_crypt_hkdf api returns error !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + + while (optiga_lib_status == OPTIGA_LIB_BUSY) + ; + if (OPTIGA_LIB_SUCCESS != optiga_lib_status) + { + // optiga_crypt_hkdf failed + optiga_lib_print_message("optiga_crypt_hkdf failed", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + } while (0); + + if (p_local_crypt) + { + optiga_crypt_destroy(p_local_crypt); + } + return return_status; +} + +optiga_lib_status_t hmac_sha256(optiga_hmac_type_t type, const uint8_t * input_data, uint32_t input_data_length, uint8_t * mac, + uint32_t * mac_length) +{ + optiga_lib_status_t return_status; + + do + { + // Create an instance of optiga_crypt_t + p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); + if (NULL == p_local_crypt) + { + optiga_lib_print_message("optiga_crypt_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + + return_status = OPTIGA_LIB_BUSY; +#if ENABLE_HMAC_MULTI_STEP + // If the size is less than the max length supported + if (input_data_length <= MAX_MAC_DATA_LEN) + { + return_status = + optiga_crypt_hmac(p_local_crypt, type, TRUSTM_HMAC_OID_KEY, input_data, input_data_length, mac, mac_length); + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_crypt_hmac api returns error !!! + optiga_lib_print_message("optiga_crypt_hmac api returns error !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + } + else + { + // Calculate HMAC in multiple steps + uint32_t dataLenTemp = 0; + uint32_t remainingLen = input_data_length; + // Start the HMAC Operation + return_status = optiga_crypt_hmac_start(p_local_crypt, type, TRUSTM_HMAC_OID_KEY, input_data, MAX_MAC_DATA_LEN); + + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_crypt_hmac_start api returns error !!! + optiga_lib_print_message("optiga_crypt_hmac_start api returns error !!!", OPTIGA_UTIL_SERVICE, + OPTIGA_UTIL_SERVICE_COLOR); + break; + } + remainingLen = input_data_length - MAX_MAC_DATA_LEN; + + while (remainingLen > 0) + { + dataLenTemp = (remainingLen > MAX_MAC_DATA_LEN) ? MAX_MAC_DATA_LEN : remainingLen; + + if (remainingLen > MAX_MAC_DATA_LEN) + { + return_status = OPTIGA_LIB_BUSY; + // printf("HMAC Update\n"); + // Continue HMAC operation on input data + return_status = + optiga_crypt_hmac_update(p_local_crypt, (input_data + (input_data_length - remainingLen)), dataLenTemp); + remainingLen = remainingLen - dataLenTemp; + + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_crypt_hmac_update api returns error !!! + optiga_lib_print_message("optiga_crypt_hmac_update api returns error !!!", OPTIGA_UTIL_SERVICE, + OPTIGA_UTIL_SERVICE_COLOR); + break; + } + } + else + { + // End HMAC sequence and return the MAC generated + // printf("HMAC Finalize\n"); + return_status = OPTIGA_LIB_BUSY; + return_status = optiga_crypt_hmac_finalize(p_local_crypt, (input_data + (input_data_length - remainingLen)), + dataLenTemp, mac, mac_length); + + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_crypt_hmac_finalize api returns error !!! + optiga_lib_print_message("optiga_crypt_hmac_finalize api returns error !!!", OPTIGA_UTIL_SERVICE, + OPTIGA_UTIL_SERVICE_COLOR); + break; + } + } + } + } +#else + + return_status = optiga_crypt_hmac(p_local_crypt, type, TRUSTM_HMAC_OID_KEY, input_data, input_data_length, mac, mac_length); + // printf("Output Length %ld Input Length %ld \n", *mac_length, input_data_length); + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_crypt_hmac api returns error !!! + optiga_lib_print_message("optiga_crypt_hmac api returns error !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + + while (optiga_lib_status == OPTIGA_LIB_BUSY) + ; + if (OPTIGA_LIB_SUCCESS != optiga_lib_status) + { + // optiga_crypt_hkdf failed + optiga_lib_print_message("optiga_crypt_hkdf failed", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } +#endif + } while (0); + + if (p_local_crypt) + { + optiga_crypt_destroy(p_local_crypt); + } + return return_status; +} + +optiga_lib_status_t trustm_ecc_keygen(uint16_t optiga_key_id, uint8_t key_type, optiga_ecc_curve_t curve_id, uint8_t * pubkey, + uint16_t pubkey_length) +{ + optiga_lib_status_t return_status; + uint8_t header256[] = { 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, + 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07 }; + uint16_t i; + for (i = 0; i < sizeof(header256); i++) + { + pubkey[i] = header256[i]; + } + do + { + // Create an instance of optiga_crypt_t + p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); + if (NULL == p_local_crypt) + { + optiga_lib_print_message("optiga_crypt_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_crypt_ecc_generate_keypair(p_local_crypt, curve_id, key_type, FALSE, &optiga_key_id, (pubkey + i), + &pubkey_length); + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_crypt_ecc_generate_keypair api returns error !!! + optiga_lib_print_message("optiga_crypt_ecc_generate_keypair api returns error !!!", OPTIGA_UTIL_SERVICE, + OPTIGA_UTIL_SERVICE_COLOR); + break; + } + + while (optiga_lib_status == OPTIGA_LIB_BUSY) + ; + + } while (0); + + if (p_local_crypt) + { + optiga_crypt_destroy(p_local_crypt); + } + return return_status; +} +void trustmGetKey(uint16_t optiga_oid, uint8_t * pubkey, uint16_t * pubkeyLen) +{ + optiga_lib_status_t return_status; + uint16_t offset = 0; + do + { + // Create an instance of optiga_crypt_t + p_local_util = optiga_util_create(0, optiga_util_callback, NULL); + if (NULL == p_local_util) + { + optiga_lib_print_message("optiga_util_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_util_read_data(p_local_util, optiga_oid, offset, pubkey, pubkeyLen); + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_util_read_pubkey api returns error !!! + optiga_lib_print_message("optiga_util_read_pubkey returns error !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + + while (optiga_lib_status == OPTIGA_LIB_BUSY) + ; + + } while (0); + + if (p_local_util) + { + optiga_util_destroy(p_local_util); + } +} +optiga_lib_status_t trustm_hash(uint8_t * msg, uint16_t msg_length, uint8_t * digest, uint8_t digest_length) +{ + optiga_lib_status_t return_status; + hash_data_from_host_t hash_data_host; + do + { + // Create an instance of optiga_crypt_t + p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); + if (NULL == p_local_crypt) + { + optiga_lib_print_message("optiga_crypt_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + hash_data_host.buffer = msg; + hash_data_host.length = msg_length; + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_crypt_hash(p_local_crypt, OPTIGA_HASH_TYPE_SHA_256, OPTIGA_CRYPT_HOST_DATA, &hash_data_host, digest); + + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_crypt_ecdsa_sign api returns error !!! + optiga_lib_print_message("optiga_crypt_hash api returns error !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + while (optiga_lib_status == OPTIGA_LIB_BUSY) + ; + } while (0); + + if (p_local_crypt) + { + optiga_crypt_destroy(p_local_crypt); + } + return return_status; +} +optiga_lib_status_t trustm_ecdsa_sign(optiga_key_id_t optiga_key_id, uint8_t * digest, uint8_t digest_length, uint8_t * signature, + uint16_t * signature_length) +{ + optiga_lib_status_t return_status; + int i; + do + { + // Create an instance of optiga_crypt_t + p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); + if (NULL == p_local_crypt) + { + optiga_lib_print_message("optiga_crypt_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_crypt_ecdsa_sign(p_local_crypt, digest, digest_length, optiga_key_id, signature, signature_length); + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_crypt_ecdsa_sign api returns error !!! + optiga_lib_print_message("optiga_crypt_ecdsa_sign api returns error !!!", OPTIGA_UTIL_SERVICE, + OPTIGA_UTIL_SERVICE_COLOR); + break; + } + while (optiga_lib_status == OPTIGA_LIB_BUSY) + ; + + for (i = (*signature_length - 1); i >= 0; i--) + { + signature[i + 2] = signature[i]; + } + + signature[0] = 0x30; // Insert SEQUENCE + signature[1] = (uint8_t)(*signature_length); // insert length + *signature_length = *signature_length + 2; + + } while (0); + + if (p_local_crypt) + { + optiga_crypt_destroy(p_local_crypt); + } + return return_status; +} +void ecc_pub_key_bit(uint8_t * q_buffer, uint8_t q_length, uint8_t * pub_key_buffer, uint16_t * pub_key_length) +{ +#define OPTIGA_UTIL_ECC_DER_ADDITIONAL_LENGTH (0x02) + + uint16_t index = 0; + + pub_key_buffer[index++] = OPTIGA_UTIL_DER_BITSTRING_TAG; + pub_key_buffer[index++] = q_length + OPTIGA_UTIL_ECC_DER_ADDITIONAL_LENGTH; + pub_key_buffer[index++] = OPTIGA_UTIL_DER_NUM_UNUSED_BITS; + // Compression format. Supports only 04 [uncompressed] + pub_key_buffer[index++] = 0x04; + + pal_os_memcpy(&pub_key_buffer[index], q_buffer, q_length); + index += q_length; + + *pub_key_length = index; + +#undef OPTIGA_UTIL_ECC_DER_ADDITIONAL_LENGTH +} +optiga_lib_status_t trustm_ecdsa_verify(uint8_t * digest, uint8_t digest_length, uint8_t * signature, uint16_t signature_length, + uint8_t * ecc_pubkey, uint8_t ecc_pubkey_length) +{ + optiga_lib_status_t return_status; + uint8_t ecc_public_key[70] = { 0x00 }; + uint16_t i; + uint16_t ecc_public_key_length = 0; + ecc_pub_key_bit(ecc_pubkey, ecc_pubkey_length, ecc_public_key, &ecc_public_key_length); + + public_key_from_host_t public_key_details = { ecc_public_key, ecc_public_key_length, (uint8_t) OPTIGA_ECC_CURVE_NIST_P_256 }; + do + { + // Create an instance of optiga_crypt_t + p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); + + if (NULL == p_local_crypt) + { + optiga_lib_print_message("optiga_crypt_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + signature_length = signature[1]; + for (i = 0; i < signature_length; i++) + { + signature[i] = signature[i + 2]; + } + return_status = OPTIGA_LIB_BUSY; + return_status = optiga_crypt_ecdsa_verify(p_local_crypt, digest, digest_length, signature, signature_length, + OPTIGA_CRYPT_HOST_DATA, &public_key_details); + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_crypt_ecdsa_verify api returns error !!! + optiga_lib_print_message("optiga_crypt_ecdsa_verify api returns error !!!", OPTIGA_UTIL_SERVICE, + OPTIGA_UTIL_SERVICE_COLOR); + break; + } + while (optiga_lib_status == OPTIGA_LIB_BUSY) + ; + } while (0); + + if (p_local_crypt) + { + optiga_crypt_destroy(p_local_crypt); + } + return return_status; +} + +CHIP_ERROR trustmGetCertificate(uint16_t optiga_oid, uint8_t * buf, uint16_t * buflen) +{ + optiga_lib_status_t return_status; + VerifyOrReturnError(buf != nullptr, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(buflen != nullptr, CHIP_ERROR_INTERNAL); + + uint8_t ifx_cert_hex[1024]; + uint16_t ifx_cert_hex_len = sizeof(ifx_cert_hex); + + trustm_Open(); + do + { + // Create an instance of optiga_util to read the certificate from OPTIGA. + p_local_util = optiga_util_create(0, optiga_util_callback, NULL); + if (!p_local_util) + { + optiga_lib_print_message("optiga_util_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_util_read_data(p_local_util, optiga_oid, 0, ifx_cert_hex, &ifx_cert_hex_len); + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_util_read_data api returns error !!! + optiga_lib_print_message("optiga_util_read_data api returns error !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + while (optiga_lib_status == OPTIGA_LIB_BUSY) + ; + if (OPTIGA_LIB_SUCCESS != optiga_lib_status) + { + // optiga_util_read_data failed + optiga_lib_print_message("optiga_util_read_data failed", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + + memcpy(buf, ifx_cert_hex, ifx_cert_hex_len); + *buflen = ifx_cert_hex_len; + while (optiga_lib_status == OPTIGA_LIB_BUSY) + ; + if (OPTIGA_LIB_SUCCESS != optiga_lib_status) + { + // optiga_util_read_data failed + optiga_lib_print_message("optiga_util_read_data failed", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + } while (0); + + if (p_local_util) + { + optiga_util_destroy(p_local_util); + } + return CHIP_NO_ERROR; +} +optiga_lib_status_t trustm_ecdh_derive_secret(optiga_key_id_t optiga_key_id, uint8_t * public_key, uint16_t public_key_length, + uint8_t * shared_secret, uint8_t shared_secret_length) +{ + optiga_lib_status_t return_status; + static public_key_from_host_t public_key_details = { + (uint8_t *) public_key, + public_key_length, + (uint8_t) OPTIGA_ECC_CURVE_NIST_P_256, + }; + do + { + // Create an instance of optiga_crypt_t + p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); + + if (NULL == p_local_crypt) + { + optiga_lib_print_message("optiga_crypt_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + + return_status = OPTIGA_LIB_BUSY; + return_status = optiga_crypt_ecdh(p_local_crypt, optiga_key_id, &public_key_details, TRUE, shared_secret); + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_crypt_ecdsa_verify api returns error !!! + optiga_lib_print_message("optiga_crypt_ecdsa_verify api returns error !!!", OPTIGA_UTIL_SERVICE, + OPTIGA_UTIL_SERVICE_COLOR); + break; + } + while (optiga_lib_status == OPTIGA_LIB_BUSY) + ; + } while (0); + + if (p_local_crypt) + { + optiga_crypt_destroy(p_local_crypt); + } + return return_status; +} + +optiga_lib_status_t trustm_PBKDF2_HMAC(const unsigned char * salt, size_t slen, unsigned int iteration_count, uint32_t key_length, + unsigned char * output) +{ + optiga_lib_status_t return_status; + uint8_t md1[32]; + uint32_t md1_len = sizeof(md1); + uint8_t work[32]; + uint32_t work_len = sizeof(work); + + unsigned char * out_p = output; + do + { + // Create an instance of optiga_crypt_t + p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); + if (NULL == p_local_crypt) + { + optiga_lib_print_message("optiga_crypt_create failed!!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + + // Calculate U1, U1 ends up in work + return_status = + optiga_crypt_hmac(p_local_crypt, OPTIGA_HMAC_SHA_256, TRUSTM_HMAC_OID_KEY, salt, (uint32_t) slen, work, &work_len); + + if (OPTIGA_LIB_SUCCESS != return_status) + { + optiga_lib_print_message("optiga_crypt_hmac api returns error!!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + return_status = OPTIGA_LIB_BUSY; + memcpy(md1, work, md1_len); + for (unsigned int i = 1; i < iteration_count; i++) + { + // Calculated subsequent U, which ends up in md1 + return_status = optiga_crypt_hmac(p_local_crypt, OPTIGA_HMAC_SHA_256, TRUSTM_HMAC_OID_KEY, md1, md1_len, md1, &md1_len); + + if (OPTIGA_LIB_SUCCESS != return_status) + { + optiga_lib_print_message("optiga_crypt_hmac api returns error!!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + break; + } + return_status = OPTIGA_LIB_BUSY; + + // U1 xor U2 + for (int j = 0; j < (int) md1_len; j++) + { + work[j] ^= md1[j]; + } + } + + while (optiga_lib_status == OPTIGA_LIB_BUSY) + ; + + if (OPTIGA_LIB_SUCCESS != optiga_lib_status) + + { + + // optiga_crypt_hkdf failed + + optiga_lib_print_message("optiga_crypt_pbkdf_hmac failed failed", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + + break; + } + memcpy(out_p, work, key_length); + } while (0); + + if (p_local_crypt) + { + optiga_crypt_destroy(p_local_crypt); + } + return return_status; +} \ No newline at end of file diff --git a/src/crypto/hsm/infineon/CHIPCryptoPALHsm_utils_trustm.h b/src/crypto/hsm/infineon/CHIPCryptoPALHsm_utils_trustm.h new file mode 100644 index 00000000000000..379e0fd43316fd --- /dev/null +++ b/src/crypto/hsm/infineon/CHIPCryptoPALHsm_utils_trustm.h @@ -0,0 +1,74 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include +#include +#include + +#include "optiga_crypt.h" +#include +#include +#include +#include +#include +#include +/* trustm includes */ +#include "optiga_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern optiga_crypt_t * p_local_crypt; +extern optiga_util_t * p_local_util; + +#define TRUSTM_HKDF_OID_KEY (0xF1D8) +#define TRUSTM_HMAC_OID_KEY (0xF1D9) +#define TRUSTM_P256_PUBKEY_OID_KEY (0xF1DA) + +/* Open session to trustm */ +void trustm_Open(void); +void read_certificate_from_optiga(uint16_t optiga_oid, char * cert_pem, uint16_t * cert_pem_length); +void write_data(uint16_t optiga_oid, const uint8_t * p_data, uint16_t length); +void write_metadata(uint16_t optiga_oid, const uint8_t * p_data, uint8_t length); +void trustmGetKey(uint16_t optiga_oid, uint8_t * pubkey, uint16_t * pubKeyLen); +optiga_lib_status_t deriveKey_HKDF(const uint8_t * salt, uint16_t salt_length, const uint8_t * info, uint16_t info_length, + uint16_t derived_key_length, bool_t export_to_host, uint8_t * derived_key); +optiga_lib_status_t hmac_sha256(optiga_hmac_type_t type, const uint8_t * input_data, uint32_t input_data_length, uint8_t * mac, + uint32_t * mac_length); +optiga_lib_status_t trustm_ecc_keygen(uint16_t optiga_key_id, uint8_t key_type, optiga_ecc_curve_t curve_id, uint8_t * pubkey, + uint16_t pubkey_length); +optiga_lib_status_t trustm_hash(uint8_t * msg, uint16_t msg_length, uint8_t * digest, uint8_t digest_length); +optiga_lib_status_t trustm_ecdsa_sign(optiga_key_id_t optiga_key_id, uint8_t * digest, uint8_t digest_length, uint8_t * signature, + uint16_t * signature_length); +void ecc_public_key_in_bit(const uint8_t * q_buffer, uint8_t q_length, uint8_t * pub_key_buffer, uint16_t pub_key_length); +optiga_lib_status_t trustm_ecdsa_verify(uint8_t * digest, uint8_t digest_length, uint8_t * signature, uint16_t signature_length, + uint8_t * ecc_pubkey, uint8_t ecc_pubkey_length); +/* Close session to trustm */ +void trustm_close(void); +CHIP_ERROR trustmGetCertificate(uint16_t optiga_oid, uint8_t * buf, uint16_t * buflen); +optiga_lib_status_t trustm_ecdh_derive_secret(optiga_key_id_t optiga_key_id, uint8_t * public_key, uint16_t public_key_length, + uint8_t * shared_secret, uint8_t shared_secret_length); +optiga_lib_status_t trustm_PBKDF2_HMAC(const unsigned char * salt, size_t slen, unsigned int iteration_count, uint32_t key_length, + unsigned char * output); +#ifdef __cplusplus +} +#endif diff --git a/src/crypto/hsm/infineon/README.md b/src/crypto/hsm/infineon/README.md new file mode 100644 index 00000000000000..16dfb6fe36eace --- /dev/null +++ b/src/crypto/hsm/infineon/README.md @@ -0,0 +1,30 @@ +# Using trustm for crypto operations + +## Introduction + +CHIPCryptoPALHsm\_\*\_trustm.cpp file provides the integration of secure element +(trustm) in crypto layer of CHIP stack. By enabling the required directives in +CHIPCryptoPALHsm_config.h header file, required crypto operations can be +performed using trustm. By default, the secure element is enabled for HKDF, HMAC +(SHA256). + +Following are the list operations supported by secure element. + + 1. HKDF + 2. HMAC (SHA256) + 3. P256 + +## Build + +- Use the following gn build arguments to enable the secure element in crypto + layer, + +``` +chip_enable_infineon_trustm=true ==> To enable trustm crypto services as HSM +chip_enable_infineon_trustm_da=true ==> To use trustm to store device attestation credentials e.g. PAI, DAC and CD +host = "psoc6" ==> To set host +``` + +## Known Limitations: + +- None diff --git a/third_party/infineon/psoc6/BUILD.gn b/third_party/infineon/psoc6/BUILD.gn index 59464a8e2a7cf5..19fe610b1e6777 100644 --- a/third_party/infineon/psoc6/BUILD.gn +++ b/third_party/infineon/psoc6/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Project CHIP Authors +# Copyright (c) 2023 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/third_party/infineon/psoc6/psoc6_sdk/build/CY8CKIT-062S2-43012/Debug/GCC_ARM.json b/third_party/infineon/psoc6/psoc6_sdk/build/CY8CKIT-062S2-43012/Debug/GCC_ARM.json index e96bb45ea363fe..7c0a87a068c637 100644 --- a/third_party/infineon/psoc6/psoc6_sdk/build/CY8CKIT-062S2-43012/Debug/GCC_ARM.json +++ b/third_party/infineon/psoc6/psoc6_sdk/build/CY8CKIT-062S2-43012/Debug/GCC_ARM.json @@ -220,7 +220,11 @@ "-DCOMPONENT_SOFTFP", "-DCOMPONENT_WICED_BLE", "-DDEBUG", - "-DCY_SUPPORTS_DEVICE_VALIDATION" + "-DCY_SUPPORTS_DEVICE_VALIDATION", + "-DCY_CRYPTO_HAL_DISABLE", + "-DCOMPONENT_SECURE_SOCKETS", + "-DCOMPONENT_PSOC6_FREERTOS", + "-DOPTIGA_LIB_EXTERNAL=" ], "c_source": [ "./libs/abstraction-rtos/source/cy_worker_thread.c", diff --git a/third_party/infineon/psoc6/psoc6_sdk/build/CY8CKIT-062S2-43012/Release/GCC_ARM.json b/third_party/infineon/psoc6/psoc6_sdk/build/CY8CKIT-062S2-43012/Release/GCC_ARM.json index f31178e379e213..5882f13793e8b6 100644 --- a/third_party/infineon/psoc6/psoc6_sdk/build/CY8CKIT-062S2-43012/Release/GCC_ARM.json +++ b/third_party/infineon/psoc6/psoc6_sdk/build/CY8CKIT-062S2-43012/Release/GCC_ARM.json @@ -220,7 +220,11 @@ "-DCOMPONENT_SOFTFP", "-DCOMPONENT_WICED_BLE", "-DNDEBUG", - "-DCY_SUPPORTS_DEVICE_VALIDATION" + "-DCY_SUPPORTS_DEVICE_VALIDATION", + "-DCY_CRYPTO_HAL_DISABLE", + "-DCOMPONENT_SECURE_SOCKETS", + "-DCOMPONENT_PSOC6_FREERTOS", + "-DOPTIGA_LIB_EXTERNAL=" ], "c_source": [ "./libs/abstraction-rtos/source/cy_worker_thread.c", diff --git a/third_party/infineon/psoc6/psoc6_sdk/configs/FreeRTOSConfig.h b/third_party/infineon/psoc6/psoc6_sdk/configs/FreeRTOSConfig.h index 38e058fbec9fbf..8478bf2eecff3c 100644 --- a/third_party/infineon/psoc6/psoc6_sdk/configs/FreeRTOSConfig.h +++ b/third_party/infineon/psoc6/psoc6_sdk/configs/FreeRTOSConfig.h @@ -75,7 +75,13 @@ extern uint32_t SystemCoreClock; #define configTOTAL_HEAP_SIZE ((size_t)(CY_SRAM_SIZE - (64 * 1024))) /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 + +#ifdef ENABLE_HSM_DEVICE_ATTESTATION +#define configUSE_TICK_HOOK 1 +#else #define configUSE_TICK_HOOK 0 +#endif + #define configCHECK_FOR_STACK_OVERFLOW 2 #define configUSE_MALLOC_FAILED_HOOK 1 @@ -96,7 +102,7 @@ extern uint32_t SystemCoreClock; #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY 2 #define configTIMER_QUEUE_LENGTH 10 -#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2) +#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 6) /* Queue Creation Fix to not use static queue */ #define LWIP_FREERTOS_USE_STATIC_TCPIP_QUEUE 0 diff --git a/third_party/infineon/psoc6/psoc6_sdk/configs/optiga_lib_config_mtb.h b/third_party/infineon/psoc6/psoc6_sdk/configs/optiga_lib_config_mtb.h new file mode 100644 index 00000000000000..25251ba988392a --- /dev/null +++ b/third_party/infineon/psoc6/psoc6_sdk/configs/optiga_lib_config_mtb.h @@ -0,0 +1,196 @@ +/** + * \copyright + * MIT License + * + * Copyright (c) 2023 Infineon Technologies AG + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE + * + * \endcopyright + * + * \author Infineon Technologies AG + * + * \file optiga_lib_config_m_v3.h + * + * \brief This file is defines the compilation switches to build code with required features. + * + * \ingroup grOptigaLibCommon + * + * @{ + */ + +#ifndef _OPTIGA_LIB_CONFIG_M_V3_H_ +#define _OPTIGA_LIB_CONFIG_M_V3_H_ + +#include "cy_pdl.h" +#include "cybsp.h" +#include "cyhal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief OPTIGA CRYPT random number generation feature enable/disable macro */ +#define OPTIGA_CRYPT_RANDOM_ENABLED +/** @brief OPTIGA CRYPT hash feature enable/disable macro */ +#define OPTIGA_CRYPT_HASH_ENABLED +/** @brief OPTIGA CRYPT ECC generate keypair feature enable/disable macro */ +#define OPTIGA_CRYPT_ECC_GENERATE_KEYPAIR_ENABLED +/** @brief OPTIGA CRYPT ECDSA signature feature enable/disable macro */ +#define OPTIGA_CRYPT_ECDSA_SIGN_ENABLED +/** @brief OPTIGA CRYPT verify ECDSA signature feature enable/disable macro */ +#define OPTIGA_CRYPT_ECDSA_VERIFY_ENABLED +/** @brief OPTIGA CRYPT ECDH feature enable/disable macro */ +#define OPTIGA_CRYPT_ECDH_ENABLED +/** @brief OPTIGA CRYPT ECC 521 feature enable/disable macro */ +#define OPTIGA_CRYPT_ECC_NIST_P_521_ENABLED +/** @brief OPTIGA CRYPT ECC Brainpool feature enable/disable macro */ +#define OPTIGA_CRYPT_ECC_BRAINPOOL_P_R1_ENABLED +/** @brief OPTIGA CRYPT TLS PRF sha256 feature enable/disable macro */ +#define OPTIGA_CRYPT_TLS_PRF_SHA256_ENABLED +/** @brief OPTIGA CRYPT TLS PRF sha384 feature enable/disable macro */ +#define OPTIGA_CRYPT_TLS_PRF_SHA384_ENABLED +/** @brief OPTIGA CRYPT TLS PRF sha512 feature enable/disable macro */ +#define OPTIGA_CRYPT_TLS_PRF_SHA512_ENABLED +/** @brief OPTIGA CRYPT RSA generate keypair feature enable/disable macro */ +#define OPTIGA_CRYPT_RSA_GENERATE_KEYPAIR_ENABLED +/** @brief OPTIGA CRYPT RSA sign feature enable/disable macro */ +#define OPTIGA_CRYPT_RSA_SIGN_ENABLED +/** @brief OPTIGA CRYPT RSA verify sign feature enable/disable macro */ +#define OPTIGA_CRYPT_RSA_VERIFY_ENABLED +/** @brief OPTIGA CRYPT RSA Encrypt feature enable/disable macro */ +#define OPTIGA_CRYPT_RSA_ENCRYPT_ENABLED +/** @brief OPTIGA CRYPT RSA Decrypt feature enable/disable macro */ +#define OPTIGA_CRYPT_RSA_DECRYPT_ENABLED +/** @brief OPTIGA CRYPT RSA pre-master feature enable/disable macro */ +#define OPTIGA_CRYPT_RSA_PRE_MASTER_SECRET_ENABLED +/** @brief OPTIGA CRYPT RSA SSA with SHA512 as digest feature enable/disable macro */ +#define OPTIGA_CRYPT_RSA_SSA_SHA512_ENABLED +/** @brief OPTIGA CRYPT symmetric encrypt feature enable/disable macro */ +#define OPTIGA_CRYPT_SYM_ENCRYPT_ENABLED +/** @brief OPTIGA CRYPT symmetric decrypt feature enable/disable macro */ +#define OPTIGA_CRYPT_SYM_DECRYPT_ENABLED +/** @brief OPTIGA CRYPT HMAC feature enable/disable macro */ +#define OPTIGA_CRYPT_HMAC_ENABLED +/** @brief OPTIGA CRYPT HKDF feature enable/disable macro */ +#define OPTIGA_CRYPT_HKDF_ENABLED +/** @brief OPTIGA CRYPT symmetric generate key feature enable/disable macro */ +#define OPTIGA_CRYPT_SYM_GENERATE_KEY_ENABLED +/** @brief OPTIGA CRYPT generate auth code feature enable/disable macro */ +#define OPTIGA_CRYPT_GENERATE_AUTH_CODE_ENABLED +/** @brief OPTIGA CRYPT HMAC verify feature enable/disable macro */ +#define OPTIGA_CRYPT_HMAC_VERIFY_ENABLED +/** @brief OPTIGA CRYPT clear AUTO state feature enable/disable macro */ +#define OPTIGA_CRYPT_CLEAR_AUTO_STATE_ENABLED + +/** @brief OPTIGA COMMS shielded connection feature. + * To disable the feature, undefine the macro + */ +#define OPTIGA_COMMS_SHIELDED_CONNECTION + +/** @brief Default reset protection level for OPTIGA CRYPT and UTIL APIs */ +#define OPTIGA_COMMS_DEFAULT_PROTECTION_LEVEL OPTIGA_COMMS_NO_PROTECTION + +/** @brief NULL parameter check. + * To disable the check, undefine the macro + */ +#define OPTIGA_LIB_DEBUG_NULL_CHECK +/** @brief Maximum number of instance registration */ +#define OPTIGA_CMD_MAX_REGISTRATIONS (0x06) +/** @brief Maximum buffer size required to communicate with OPTIGA */ +#define OPTIGA_MAX_COMMS_BUFFER_SIZE (0x615) // 1557 in decimal + +/** @brief Macro to enable logger \n + * Enable macro OPTIGA_LIB_ENABLE_UTIL_LOGGING for Util Service layer logging \n + * Enable macro OPTIGA_LIB_ENABLE_CRYPT_LOGGING for Crypt Service layer logging \n + * Enable macro OPTIGA_LIB_ENABLE_CMD_LOGGING for Command layer logging \n + * Enable macro OPTIGA_LIB_ENABLE_COMMS_LOGGING for Communication layer logging */ +//#define OPTIGA_LIB_ENABLE_LOGGING +/** @brief Enable macro OPTIGA_PAL_INIT_ENABLED for calling pal_init functionality */ +#define OPTIGA_PAL_INIT_ENABLED +/// @cond +#ifdef OPTIGA_LIB_ENABLE_LOGGING +/** @brief Macro to enable logger for Util service */ +//#define OPTIGA_LIB_ENABLE_UTIL_LOGGING +/** @brief Macro to enable logger for Crypt service */ +//#define OPTIGA_LIB_ENABLE_CRYPT_LOGGING +/** @brief Macro to enable logger for Command layer */ +// #define OPTIGA_LIB_ENABLE_CMD_LOGGING +/** @brief Macro to enable logger for Communication layer */ +//#define OPTIGA_LIB_ENABLE_COMMS_LOGGING +#endif +/// @endcond + +/* Below are the example macros for protected update not for any feature */ +/** @brief OPTIGA UTIL confidentiality protected update feature enable/disable macro */ +#define EXAMPLE_OPTIGA_UTIL_PROTECTED_UPDATE_CONFIDENTIALITY_ENABLED +/** @brief OPTIGA UTIL key object protected update feature enable/disable macro */ +#define EXAMPLE_OPTIGA_UTIL_PROTECTED_UPDATE_OBJECT_KEY_ENABLED +/** @brief OPTIGA UTIL metadata object protected update feature enable/disable macro */ +#define EXAMPLE_OPTIGA_UTIL_PROTECTED_UPDATE_OBJECT_METADATA_ENABLED + +/* + * The following GPIO settings are only ModusToolbox and specific PSoC6 family board relevant + */ +//#if defined(CYBSP_TRUSTM_I2C_SCL) +// #define OPTIGA_TRUSTM_SCL CYBSP_TRUSTM_I2C_SCL +//#elif defined(CYBSP_I2C_SCL) +#define OPTIGA_TRUSTM_SCL CYBSP_I2C_SCL +//#else +// #error "You need to define the OPTIGA_TRUSTM_SCL macro for OPTIGA to know what to use for the communication" +//#endif + +//#if defined(CYBSP_TRUSTM_I2C_SDA) +// #define OPTIGA_TRUSTM_SDA CYBSP_TRUSTM_I2C_SDA +//#elif defined(CYBSP_I2C_SDA) +#define OPTIGA_TRUSTM_SDA CYBSP_I2C_SDA +//#else +// #error "You need to define the OPTIGA_TRUSTM_SDA macro for OPTIGA to know what to use for the communication" +//#endif + +#if defined(CYBSP_TRUSTM_RST) +#define OPTIGA_TRUSTM_RST CYBSP_TRUSTM_RST +#endif +#if defined(CYBSP_TRUSTM_VDD) +#define OPTIGA_TRUSTM_VDD CYBSP_TRUSTM_VDD +#endif + +/** @brief Default reset type in optiga_comms_open. \n + * Cold Reset - (0) : This is applicable if the host platform has GPIO option for RST and VDD. \n + * Soft Reset - (1) : This is applicable if the host platform doesn't have GPIO options for VDD and RST. \n + * Warm Reset - (2) : This is applicable if the host platform doesn't have GPIO option for VDD. \n + * Any other value will lead to error + */ +#if defined(CYBSP_TRUSTM_RST) || defined(CYBSP_TRUSTM_VDD) +#define OPTIGA_COMMS_DEFAULT_RESET_TYPE (0U) +#elif !defined(CYBSP_TRUSTM_RST) && !defined(CYBSP_TRUSTM_VDD) +#define OPTIGA_COMMS_DEFAULT_RESET_TYPE (1U) +#elif defined(CYBSP_TRUSTM_RST) && !defined(CYBSP_TRUSTM_VDD) +#define OPTIGA_COMMS_DEFAULT_RESET_TYPE (0U) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _OPTIGA_LIB_CONFIG_M_V3_H_*/ + +/** + * @} + */ diff --git a/third_party/infineon/trustm/BUILD.gn b/third_party/infineon/trustm/BUILD.gn new file mode 100644 index 00000000000000..70b0a6997b853b --- /dev/null +++ b/third_party/infineon/trustm/BUILD.gn @@ -0,0 +1,73 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("${chip_root}/src/platform/device.gni") +import("${chip_root}/third_party/infineon/trustm/trustm_config.gni") + +config("trustm_config") { + if (chip_trustm_da == 1) { + defines += [ "CHIP_TRUSTM_DA" ] + } + + include_dirs = [ + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/include", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/include/optiga", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/include/optiga/ifx_i2c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/include/optiga/comms", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/include/optiga/common", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/include/optiga/cmd", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/include/optiga/pal", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/externals/mbedtls/include", + "${chip_root}/third_party/infineon/trustm", + ] + if (chip_device_platform == "psoc6") { + include_dirs += [ "${chip_root}/third_party/infineon/trustm/optiga-trust-m/pal/COMPONENT_PSOC6_FREERTOS/COMPONENT_CM4" ] + } +} + +source_set("optiga-trust-m") { + sources = [ + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/cmd/optiga_cmd.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/common/optiga_lib_common.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/common/optiga_lib_logger.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/comms/ifx_i2c/ifx_i2c.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/comms/ifx_i2c/ifx_i2c_config.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/comms/ifx_i2c/ifx_i2c_data_link_layer.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/comms/ifx_i2c/ifx_i2c_physical_layer.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/comms/ifx_i2c/ifx_i2c_presentation_layer.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/comms/ifx_i2c/ifx_i2c_transport_layer.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/comms/optiga_comms_ifx_i2c.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/crypt/optiga_crypt.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/optiga/util/optiga_util.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/pal/pal_crypt_mbedtls.c", + ] + + if (chip_device_platform == "psoc6") { + sources += [ + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/pal/COMPONENT_PSOC6_FREERTOS/COMPONENT_CM4/pal.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/pal/COMPONENT_PSOC6_FREERTOS/COMPONENT_CM4/pal_gpio.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/pal/COMPONENT_PSOC6_FREERTOS/COMPONENT_CM4/pal_i2c.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/pal/COMPONENT_PSOC6_FREERTOS/COMPONENT_CM4/pal_ifx_i2c_config.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/pal/COMPONENT_PSOC6_FREERTOS/COMPONENT_CM4/pal_logger.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/pal/COMPONENT_PSOC6_FREERTOS/COMPONENT_CM4/pal_os_datastore.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/pal/COMPONENT_PSOC6_FREERTOS/COMPONENT_CM4/pal_os_event.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/pal/COMPONENT_PSOC6_FREERTOS/COMPONENT_CM4/pal_os_lock.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/pal/COMPONENT_PSOC6_FREERTOS/COMPONENT_CM4/pal_os_memory.c", + "${chip_root}/third_party/infineon/trustm/optiga-trust-m/pal/COMPONENT_PSOC6_FREERTOS/COMPONENT_CM4/pal_os_timer.c", + ] + } + public_deps = [ "${chip_root}/third_party/mbedtls:mbedtls" ] + configs += [ ":trustm_config" ] +} diff --git a/third_party/infineon/trustm/optiga-trust-m b/third_party/infineon/trustm/optiga-trust-m new file mode 160000 index 00000000000000..78011d1f7c3bdb --- /dev/null +++ b/third_party/infineon/trustm/optiga-trust-m @@ -0,0 +1 @@ +Subproject commit 78011d1f7c3bdb17164b453956b635b3cb327ae4 diff --git a/third_party/infineon/trustm/trustm_config.gni b/third_party/infineon/trustm/trustm_config.gni new file mode 100644 index 00000000000000..9a205ecd6a0753 --- /dev/null +++ b/third_party/infineon/trustm/trustm_config.gni @@ -0,0 +1,19 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration file + +declare_args() { + chip_trustm_da = 0 +}