diff --git a/examples/platform/nxp/se05x/DeviceAttestationSe05xCredsExample.cpp b/examples/platform/nxp/se05x/DeviceAttestationSe05xCredsExample.cpp index b7be4c2ed91242..2dc9daaa0cad0f 100644 --- a/examples/platform/nxp/se05x/DeviceAttestationSe05xCredsExample.cpp +++ b/examples/platform/nxp/se05x/DeviceAttestationSe05xCredsExample.cpp @@ -30,8 +30,9 @@ #include -#define DEV_ATTESTATION_KEY_ID 0xDADADADA -#define DEV_ATTESTATION_CERT_ID 0xDADADADB +/* Device attestation key ids */ +#define DEV_ATTESTATION_KEY_SE05X_ID 0x7D300000 +#define DEV_ATTESTATION_CERT_SE05X_ID 0x7D300001 extern CHIP_ERROR se05xGetCertificate(uint32_t keyId, uint8_t * buf, size_t * buflen); @@ -57,8 +58,8 @@ CHIP_ERROR ExampleSe05xDACProvider::GetDeviceAttestationCert(MutableByteSpan & o return CopySpanToMutableSpan(DevelopmentCerts::kDacCert, out_dac_buffer); #else size_t buflen = out_dac_buffer.size(); - ChipLogDetail(Crypto, "Get certificate from se05x"); - ReturnErrorOnFailure(se05xGetCertificate(DEV_ATTESTATION_CERT_ID, out_dac_buffer.data(), &buflen)); + ChipLogDetail(Crypto, "Get DA certificate from se05x"); + ReturnErrorOnFailure(se05xGetCertificate(DEV_ATTESTATION_CERT_SE05X_ID, out_dac_buffer.data(), &buflen)); out_dac_buffer.reduce_size(buflen); return CHIP_NO_ERROR; #endif @@ -142,7 +143,7 @@ CHIP_ERROR ExampleSe05xDACProvider::SignWithDeviceAttestationKey(const ByteSpan 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.SetKeyId(DEV_ATTESTATION_KEY_SE05X_ID); keypair.provisioned_key = true; keypair.Initialize(); diff --git a/examples/platform/nxp/se05x/DeviceAttestationSe05xCredsExample.h b/examples/platform/nxp/se05x/DeviceAttestationSe05xCredsExample.h old mode 100644 new mode 100755 index 0c59700e57f8b8..77f42369d30ffb --- a/examples/platform/nxp/se05x/DeviceAttestationSe05xCredsExample.h +++ b/examples/platform/nxp/se05x/DeviceAttestationSe05xCredsExample.h @@ -30,6 +30,7 @@ namespace Examples { * storage abstractions. */ DeviceAttestationCredentialsProvider * GetExampleSe05xDACProvider(); +DeviceAttestationCredentialsProvider * GetExampleSe05xDACProviderv2(); } // namespace Examples } // namespace Credentials diff --git a/examples/platform/nxp/se05x/DeviceAttestationSe05xCredsExample_v2.cpp b/examples/platform/nxp/se05x/DeviceAttestationSe05xCredsExample_v2.cpp new file mode 100644 index 00000000000000..ba214759dde8aa --- /dev/null +++ b/examples/platform/nxp/se05x/DeviceAttestationSe05xCredsExample_v2.cpp @@ -0,0 +1,298 @@ +/* + * + * 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. + */ +#include "DeviceAttestationSe05xCredsExample.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if CHIP_CRYPTO_HSM +#include +#endif + +#ifdef ENABLE_HSM_DEVICE_ATTESTATION + +#include + +/* Device attestation key ids */ +#define DEV_ATTESTATION_KEY_SE05X_ID 0x7D300000 +#define DEV_ATTESTATION_CERT_SE05X_ID 0x7D300001 + +/* Device attestation key ids (Used with internal sign) */ +#define CD_DEV_ATTESTATION_KEY_SE05X_ID 0x7D300002 +#define NOCSR_DEV_ATTESTATION_KEY_SE05X_ID 0x7D300004 + +/* Device attestation data ids (for Cert decl) */ +#define CD_CERT_DECLARATION_DATA_SE05X_ID 0x7D300009 +#define CD_ATTEST_NONCE_DATA_SE05X_ID 0x7D30000C +#define CD_TIME_STAMP_LEN_SE05X_ID 0x7D30000E +#define CD_TIME_STAMP_DATA_SE05X_ID 0x7D30000F +#define CD_ATTEST_CHALLENGE_SE05X_ID 0x7D300011 + +/* Device attestation data ids (for CSR) */ +#define NOCSR_CSR_LEN_SE05X_ID 0x7D300014 +#define NOCSR_CSR_DATA_SE05X_ID 0x7D300015 +#define NOCSR_CSR_NONCE_DATA_SE05X_ID 0x7D300018 +#define NOCSR_ATTEST_CHALLENGE_SE05X_ID 0x7D30001A + +extern CHIP_ERROR se05xGetCertificate(uint32_t keyId, uint8_t * buf, size_t * buflen); +extern CHIP_ERROR se05xSetCertificate(uint32_t keyId, const uint8_t * buf, size_t buflen); +extern CHIP_ERROR se05xPerformInternalSign(uint32_t keyId, uint8_t * sigBuf, size_t * sigBufLen); +extern void se05x_delete_key(uint32_t keyid); + +namespace chip { +namespace Credentials { +namespace Examples { + +namespace { + +class ExampleSe05xDACProviderv2 : 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 ExampleSe05xDACProviderv2::GetDeviceAttestationCert(MutableByteSpan & out_dac_buffer) +{ +#if 0 + return CopySpanToMutableSpan(DevelopmentCerts::kDacCert, out_dac_buffer); +#else + size_t buflen = out_dac_buffer.size(); + ChipLogDetail(Crypto, "Get DA certificate from se05x"); + ReturnErrorOnFailure(se05xGetCertificate(DEV_ATTESTATION_CERT_SE05X_ID, out_dac_buffer.data(), &buflen)); + out_dac_buffer.reduce_size(buflen); + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR ExampleSe05xDACProviderv2::GetProductAttestationIntermediateCert(MutableByteSpan & out_pai_buffer) +{ + return CopySpanToMutableSpan(ByteSpan(DevelopmentCerts::kPaiCert), out_pai_buffer); +} + +CHIP_ERROR ExampleSe05xDACProviderv2::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 +#if 0 + const uint8_t kCdForAllExamples[541] = { + 0x30, 0x82, 0x02, 0x19, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x0a, 0x30, + 0x82, 0x02, 0x06, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, + 0x01, 0x30, 0x82, 0x01, 0x71, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x01, 0x62, + 0x04, 0x82, 0x01, 0x5e, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xf1, 0xff, 0x36, 0x02, 0x05, 0x00, 0x80, 0x05, 0x01, 0x80, + 0x05, 0x02, 0x80, 0x05, 0x03, 0x80, 0x05, 0x04, 0x80, 0x05, 0x05, 0x80, 0x05, 0x06, 0x80, 0x05, 0x07, 0x80, 0x05, 0x08, + 0x80, 0x05, 0x09, 0x80, 0x05, 0x0a, 0x80, 0x05, 0x0b, 0x80, 0x05, 0x0c, 0x80, 0x05, 0x0d, 0x80, 0x05, 0x0e, 0x80, 0x05, + 0x0f, 0x80, 0x05, 0x10, 0x80, 0x05, 0x11, 0x80, 0x05, 0x12, 0x80, 0x05, 0x13, 0x80, 0x05, 0x14, 0x80, 0x05, 0x15, 0x80, + 0x05, 0x16, 0x80, 0x05, 0x17, 0x80, 0x05, 0x18, 0x80, 0x05, 0x19, 0x80, 0x05, 0x1a, 0x80, 0x05, 0x1b, 0x80, 0x05, 0x1c, + 0x80, 0x05, 0x1d, 0x80, 0x05, 0x1e, 0x80, 0x05, 0x1f, 0x80, 0x05, 0x20, 0x80, 0x05, 0x21, 0x80, 0x05, 0x22, 0x80, 0x05, + 0x23, 0x80, 0x05, 0x24, 0x80, 0x05, 0x25, 0x80, 0x05, 0x26, 0x80, 0x05, 0x27, 0x80, 0x05, 0x28, 0x80, 0x05, 0x29, 0x80, + 0x05, 0x2a, 0x80, 0x05, 0x2b, 0x80, 0x05, 0x2c, 0x80, 0x05, 0x2d, 0x80, 0x05, 0x2e, 0x80, 0x05, 0x2f, 0x80, 0x05, 0x30, + 0x80, 0x05, 0x31, 0x80, 0x05, 0x32, 0x80, 0x05, 0x33, 0x80, 0x05, 0x34, 0x80, 0x05, 0x35, 0x80, 0x05, 0x36, 0x80, 0x05, + 0x37, 0x80, 0x05, 0x38, 0x80, 0x05, 0x39, 0x80, 0x05, 0x3a, 0x80, 0x05, 0x3b, 0x80, 0x05, 0x3c, 0x80, 0x05, 0x3d, 0x80, + 0x05, 0x3e, 0x80, 0x05, 0x3f, 0x80, 0x05, 0x40, 0x80, 0x05, 0x41, 0x80, 0x05, 0x42, 0x80, 0x05, 0x43, 0x80, 0x05, 0x44, + 0x80, 0x05, 0x45, 0x80, 0x05, 0x46, 0x80, 0x05, 0x47, 0x80, 0x05, 0x48, 0x80, 0x05, 0x49, 0x80, 0x05, 0x4a, 0x80, 0x05, + 0x4b, 0x80, 0x05, 0x4c, 0x80, 0x05, 0x4d, 0x80, 0x05, 0x4e, 0x80, 0x05, 0x4f, 0x80, 0x05, 0x50, 0x80, 0x05, 0x51, 0x80, + 0x05, 0x52, 0x80, 0x05, 0x53, 0x80, 0x05, 0x54, 0x80, 0x05, 0x55, 0x80, 0x05, 0x56, 0x80, 0x05, 0x57, 0x80, 0x05, 0x58, + 0x80, 0x05, 0x59, 0x80, 0x05, 0x5a, 0x80, 0x05, 0x5b, 0x80, 0x05, 0x5c, 0x80, 0x05, 0x5d, 0x80, 0x05, 0x5e, 0x80, 0x05, + 0x5f, 0x80, 0x05, 0x60, 0x80, 0x05, 0x61, 0x80, 0x05, 0x62, 0x80, 0x05, 0x63, 0x80, 0x18, 0x24, 0x03, 0x16, 0x2c, 0x04, + 0x13, 0x5a, 0x49, 0x47, 0x32, 0x30, 0x31, 0x34, 0x32, 0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x34, + 0x24, 0x05, 0x00, 0x24, 0x06, 0x00, 0x25, 0x07, 0x94, 0x26, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, 0x01, + 0x03, 0x80, 0x14, 0x62, 0xfa, 0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a, 0xdd, 0xf5, 0x04, + 0xf3, 0x71, 0x60, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x20, 0x24, 0xe5, 0xd1, 0xf4, 0x7a, 0x7d, + 0x7b, 0x0d, 0x20, 0x6a, 0x26, 0xef, 0x69, 0x9b, 0x7c, 0x97, 0x57, 0xb7, 0x2d, 0x46, 0x90, 0x89, 0xde, 0x31, 0x92, 0xe6, + 0x78, 0xc7, 0x45, 0xe7, 0xf6, 0x0c, 0x02, 0x21, 0x00, 0xf8, 0xaa, 0x2f, 0xa7, 0x11, 0xfc, 0xb7, 0x9b, 0x97, 0xe3, 0x97, + 0xce, 0xda, 0x66, 0x7b, 0xae, 0x46, 0x4e, 0x2b, 0xd3, 0xff, 0xdf, 0xc3, 0xcc, 0xed, 0x7a, 0xa8, 0xca, 0x5f, 0x4c, 0x1a, + 0x7c, + }; + + return CopySpanToMutableSpan(ByteSpan{ kCdForAllExamples }, out_cd_buffer); + +#else + size_t buflen = out_cd_buffer.size(); + ChipLogDetail(Crypto, "Get certificate declaration from se05x"); + ReturnErrorOnFailure(se05xGetCertificate(CD_CERT_DECLARATION_DATA_SE05X_ID, out_cd_buffer.data(), &buflen)); + out_cd_buffer.reduce_size(buflen); + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR ExampleSe05xDACProviderv2::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 ExampleSe05xDACProviderv2::SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, + MutableByteSpan & out_signature_buffer) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + VerifyOrReturnError(IsSpanUsable(out_signature_buffer), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsSpanUsable(message_to_sign), CHIP_ERROR_INVALID_ARGUMENT); + + ChipLogDetail(Crypto, "Sign using DA key from se05x (Using internal sign)"); + + TLV::TLVReader msg_reader; + TLV::TLVReader tagReader; + + msg_reader.Init(message_to_sign); + + /* To be removed. Use common key id to sign message */ + static bool sign_cert_decl_attest = 1; + + if (sign_cert_decl_attest) + { + /* Check if certificate declaration tag is present and Skip certificate declaration tag */ + ReturnErrorOnFailure(TLV::Utilities::Find(msg_reader, TLV::ContextTag(1), tagReader)); + + ReturnErrorOnFailure(TLV::Utilities::Find(msg_reader, TLV::ContextTag(2), tagReader)); + uint8_t attlen = tagReader.GetLength(); + VerifyOrReturnError(attlen > 0, CHIP_ERROR_INVALID_TLV_TAG); + /* Get attestation nonce */ + ByteSpan attest_nonce; + ReturnErrorOnFailure(tagReader.Get(attest_nonce)); + /* Set attestation nonce */ + VerifyOrReturnError(CHIP_NO_ERROR == + se05xSetCertificate(CD_ATTEST_NONCE_DATA_SE05X_ID, attest_nonce.data(), attest_nonce.size()), + CHIP_ERROR_INTERNAL); + + ReturnErrorOnFailure(TLV::Utilities::Find(msg_reader, TLV::ContextTag(3), tagReader)); + uint8_t tslen = tagReader.GetLength(); + if (tslen > 0) + { + ByteSpan time_stamp; + ReturnErrorOnFailure(tagReader.Get(time_stamp)); + /* Set time stamp data */ + VerifyOrReturnError(CHIP_NO_ERROR == + se05xSetCertificate(CD_TIME_STAMP_DATA_SE05X_ID, time_stamp.data(), time_stamp.size()), + CHIP_ERROR_INTERNAL); + } + /* Set time stamp length */ + VerifyOrReturnError(CHIP_NO_ERROR == se05xSetCertificate(CD_TIME_STAMP_LEN_SE05X_ID, &tslen, 1), CHIP_ERROR_INTERNAL); + + if ((tagReader.GetRemainingLength() + 1 /* End container */) >= 16) + { + /* Set attestation challenge */ + VerifyOrReturnError(CHIP_NO_ERROR == + se05xSetCertificate(CD_ATTEST_CHALLENGE_SE05X_ID, (message_to_sign.end() - 16), 16), + CHIP_ERROR_INTERNAL); + } + } + else + { + ReturnErrorOnFailure(TLV::Utilities::Find(msg_reader, TLV::ContextTag(1), tagReader)); + uint8_t csrlen = tagReader.GetLength(); + VerifyOrReturnError(csrlen > 0, CHIP_ERROR_INVALID_TLV_TAG); + ByteSpan csr_data; + /* Get nocsr */ + ReturnErrorOnFailure(tagReader.Get(csr_data)); + /* Set nocsr length */ + VerifyOrReturnError(CHIP_NO_ERROR == se05xSetCertificate(NOCSR_CSR_LEN_SE05X_ID, &csrlen, 1), CHIP_ERROR_INTERNAL); + /* Set nocsr data */ + se05x_delete_key(NOCSR_CSR_DATA_SE05X_ID); + VerifyOrReturnError(CHIP_NO_ERROR == se05xSetCertificate(NOCSR_CSR_DATA_SE05X_ID, csr_data.data(), csr_data.size()), + CHIP_ERROR_INTERNAL); + + ReturnErrorOnFailure(TLV::Utilities::Find(msg_reader, TLV::ContextTag(2), tagReader)); + uint8_t noncelen = tagReader.GetLength(); + VerifyOrReturnError(noncelen > 0, CHIP_ERROR_INVALID_TLV_TAG); + /* Get nocsr nonce */ + ByteSpan nocsr_nonce; + ReturnErrorOnFailure(tagReader.Get(nocsr_nonce)); + /* Set nocsr nonce data */ + VerifyOrReturnError(CHIP_NO_ERROR == + se05xSetCertificate(NOCSR_CSR_NONCE_DATA_SE05X_ID, nocsr_nonce.data(), nocsr_nonce.size()), + CHIP_ERROR_INTERNAL); + + if ((tagReader.GetRemainingLength() + 1 /* End container */) >= 16) + { + /* Set attestation challenge */ + VerifyOrReturnError(CHIP_NO_ERROR == + se05xSetCertificate(NOCSR_ATTEST_CHALLENGE_SE05X_ID, (message_to_sign.end() - 16), 16), + CHIP_ERROR_INTERNAL); + } + } + + uint8_t signature_se05x[Crypto::kMax_ECDSA_Signature_Length_Der] = { 0 }; + size_t signature_se05x_len = sizeof(signature_se05x); + + if (sign_cert_decl_attest) + { + err = se05xPerformInternalSign(CD_DEV_ATTESTATION_KEY_SE05X_ID, signature_se05x, &signature_se05x_len); + se05x_delete_key(CD_ATTEST_NONCE_DATA_SE05X_ID); + se05x_delete_key(CD_TIME_STAMP_LEN_SE05X_ID); + se05x_delete_key(CD_TIME_STAMP_DATA_SE05X_ID); + se05x_delete_key(CD_ATTEST_CHALLENGE_SE05X_ID); + sign_cert_decl_attest = 0; + } + else + { + err = se05xPerformInternalSign(NOCSR_DEV_ATTESTATION_KEY_SE05X_ID, signature_se05x, &signature_se05x_len); + se05x_delete_key(NOCSR_CSR_LEN_SE05X_ID); + se05x_delete_key(NOCSR_CSR_DATA_SE05X_ID); + se05x_delete_key(NOCSR_CSR_NONCE_DATA_SE05X_ID); + se05x_delete_key(NOCSR_ATTEST_CHALLENGE_SE05X_ID); + sign_cert_decl_attest = 1; + } + + ReturnErrorOnFailure(err); + + return chip::Crypto::EcdsaAsn1SignatureToRaw(chip::Crypto::kP256_FE_Length, ByteSpan{ signature_se05x, signature_se05x_len }, + out_signature_buffer); +} + +} // namespace + +DeviceAttestationCredentialsProvider * GetExampleSe05xDACProviderv2() +{ + static ExampleSe05xDACProviderv2 example_dac_provider; + + return &example_dac_provider; +} + +} // namespace Examples +} // namespace Credentials +} // namespace chip + +#endif //#ifdef ENABLE_HSM_DEVICE_ATTESTATION diff --git a/examples/platform/nxp/se05x/linux/AppMain.cpp b/examples/platform/nxp/se05x/linux/AppMain.cpp new file mode 100644 index 00000000000000..f0a49794dd32e2 --- /dev/null +++ b/examples/platform/nxp/se05x/linux/AppMain.cpp @@ -0,0 +1,448 @@ +/* + * + * Copyright (c) 2021-2022 Project CHIP Authors + * All rights reserved. + * + * 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE +#include "CommissionerMain.h" +#include +#include +#include +#include +#include +#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + +#if defined(ENABLE_CHIP_SHELL) +#include +#include +#include +#endif + +#if defined(PW_RPC_ENABLED) +#include +#endif + +#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED +#include "TraceDecoder.h" +#include "TraceHandlers.h" +#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +#include +#endif + +#include + +#include "AppMain.h" +#include "CommissionableInit.h" + +#if CHIP_CRYPTO_HSM +#include "DeviceAttestationSe05xCredsExample.h" +#include +#include +#endif + +using namespace chip; +using namespace chip::ArgParser; +using namespace chip::Credentials; +using namespace chip::DeviceLayer; +using namespace chip::Inet; +using namespace chip::Transport; +using namespace chip::app::Clusters; + +#if defined(ENABLE_CHIP_SHELL) +using chip::Shell::Engine; +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_WPA +/* + * The device shall check every kWiFiStartCheckTimeUsec whether Wi-Fi management + * has been fully initialized. If after kWiFiStartCheckAttempts Wi-Fi management + * still hasn't been initialized, the device configuration is reset, and device + * needs to be paired again. + */ +static constexpr useconds_t kWiFiStartCheckTimeUsec = 100 * 1000; // 100 ms +static constexpr uint8_t kWiFiStartCheckAttempts = 5; +#endif + +namespace { +// To hold SPAKE2+ verifier, discriminator, passcode +LinuxCommissionableDataProvider gCommissionableDataProvider; + +chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; + +void EventHandler(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg) +{ + (void) arg; + if (event->Type == DeviceLayer::DeviceEventType::kCHIPoBLEConnectionEstablished) + { + ChipLogProgress(DeviceLayer, "Receive kCHIPoBLEConnectionEstablished"); + } +} + +void Cleanup() +{ +#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED + chip::trace::DeInitTrace(); +#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED + + // TODO(16968): Lifecycle management of storage-using components like GroupDataProvider, etc +} + +} // namespace + +#if CHIP_DEVICE_CONFIG_ENABLE_WPA +static bool EnsureWiFiIsStarted() +{ + for (int cnt = 0; cnt < kWiFiStartCheckAttempts; cnt++) + { + if (DeviceLayer::ConnectivityMgrImpl().IsWiFiManagementStarted()) + { + return true; + } + + usleep(kWiFiStartCheckTimeUsec); + } + + return DeviceLayer::ConnectivityMgrImpl().IsWiFiManagementStarted(); +} +#endif + +int ChipLinuxAppInit(int argc, char * const argv[], OptionSet * customOptions) +{ + CHIP_ERROR err = CHIP_NO_ERROR; +#if CONFIG_NETWORK_LAYER_BLE + RendezvousInformationFlags rendezvousFlags = RendezvousInformationFlag::kBLE; +#else // CONFIG_NETWORK_LAYER_BLE + RendezvousInformationFlag rendezvousFlags = RendezvousInformationFlag::kOnNetwork; +#endif // CONFIG_NETWORK_LAYER_BLE + +#ifdef CONFIG_RENDEZVOUS_MODE + rendezvousFlags = static_cast(CONFIG_RENDEZVOUS_MODE); +#endif + + err = Platform::MemoryInit(); + SuccessOrExit(err); + + err = ParseArguments(argc, argv, customOptions); + SuccessOrExit(err); + +#ifdef CHIP_CONFIG_KVS_PATH + if (LinuxDeviceOptions::GetInstance().KVS == nullptr) + { + err = DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init(CHIP_CONFIG_KVS_PATH); + } + else + { + err = DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init(LinuxDeviceOptions::GetInstance().KVS); + } + SuccessOrExit(err); +#endif + + err = DeviceLayer::PlatformMgr().InitChipStack(); + SuccessOrExit(err); + + // Init the commissionable data provider based on command line options + // to handle custom verifiers, discriminators, etc. + err = chip::examples::InitCommissionableDataProvider(gCommissionableDataProvider, LinuxDeviceOptions::GetInstance()); + SuccessOrExit(err); + DeviceLayer::SetCommissionableDataProvider(&gCommissionableDataProvider); + + err = chip::examples::InitConfigurationManager(reinterpret_cast(ConfigurationMgr()), + LinuxDeviceOptions::GetInstance()); + SuccessOrExit(err); + + if (LinuxDeviceOptions::GetInstance().payload.rendezvousInformation.HasValue()) + { + rendezvousFlags = LinuxDeviceOptions::GetInstance().payload.rendezvousInformation.Value(); + } + + err = GetPayloadContents(LinuxDeviceOptions::GetInstance().payload, rendezvousFlags); + SuccessOrExit(err); + + ConfigurationMgr().LogDeviceConfig(); + + { + ChipLogProgress(NotSpecified, "==== Onboarding payload for Standard Commissioning Flow ===="); + PrintOnboardingCodes(LinuxDeviceOptions::GetInstance().payload); + } + + { + // For testing of manual pairing code with custom commissioning flow + ChipLogProgress(NotSpecified, "==== Onboarding payload for Custom Commissioning Flows ===="); + err = GetPayloadContents(LinuxDeviceOptions::GetInstance().payload, rendezvousFlags); + SuccessOrExit(err); + + LinuxDeviceOptions::GetInstance().payload.commissioningFlow = chip::CommissioningFlow::kCustom; + + PrintOnboardingCodes(LinuxDeviceOptions::GetInstance().payload); + } + +#if defined(PW_RPC_ENABLED) + rpc::Init(); + ChipLogProgress(NotSpecified, "PW_RPC initialized."); +#endif // defined(PW_RPC_ENABLED) + + DeviceLayer::PlatformMgrImpl().AddEventHandler(EventHandler, 0); + +#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED + if (LinuxDeviceOptions::GetInstance().traceStreamFilename.HasValue()) + { + const char * traceFilename = LinuxDeviceOptions::GetInstance().traceStreamFilename.Value().c_str(); + auto traceStream = new chip::trace::TraceStreamFile(traceFilename); + chip::trace::AddTraceStream(traceStream); + } + else if (LinuxDeviceOptions::GetInstance().traceStreamToLogEnabled) + { + auto traceStream = new chip::trace::TraceStreamLog(); + chip::trace::AddTraceStream(traceStream); + } + + if (LinuxDeviceOptions::GetInstance().traceStreamDecodeEnabled) + { + chip::trace::TraceDecoderOptions options; + options.mEnableProtocolInteractionModelResponse = false; + + chip::trace::TraceDecoder * decoder = new chip::trace::TraceDecoder(); + decoder->SetOptions(options); + chip::trace::AddTraceStream(decoder); + } + chip::trace::InitTrace(); +#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED + +#if CONFIG_NETWORK_LAYER_BLE + DeviceLayer::ConnectivityMgr().SetBLEDeviceName(nullptr); // Use default device name (CHIP-XXXX) + DeviceLayer::Internal::BLEMgrImpl().ConfigureBle(LinuxDeviceOptions::GetInstance().mBleDevice, false); + DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(true); +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_WPA + if (LinuxDeviceOptions::GetInstance().mWiFi) + { + DeviceLayer::ConnectivityMgrImpl().StartWiFiManagement(); + if (!EnsureWiFiIsStarted()) + { + ChipLogError(NotSpecified, "Wi-Fi Management taking too long to start - device configuration will be reset."); + } + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_WPA + +#if CHIP_ENABLE_OPENTHREAD + if (LinuxDeviceOptions::GetInstance().mThread) + { + SuccessOrExit(err = DeviceLayer::ThreadStackMgrImpl().InitThreadStack()); + ChipLogProgress(NotSpecified, "Thread initialized."); + } +#endif // CHIP_ENABLE_OPENTHREAD + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogProgress(NotSpecified, "Failed to init Linux App: %s ", ErrorStr(err)); + Cleanup(); + + // End the program with non zero error code to indicate a error. + return 1; + } + return 0; +} + +#ifdef ENABLE_HSM_EC_KEY + +struct CommonCaseDeviceServerInitParams_Se05x : public CommonCaseDeviceServerInitParams +{ + CHIP_ERROR InitializeStaticResourcesBeforeServerInit() override + { + static chip::KvsPersistentStorageDelegate sKvsPersistenStorageDelegate; + static chip::PersistentStorageOperationalKeystoreHSM sPersistentStorageOperationalKeystore; + static chip::Credentials::PersistentStorageOpCertStore sPersistentStorageOpCertStore; + static chip::Credentials::GroupDataProviderImpl sGroupDataProvider; + static IgnoreCertificateValidityPolicy sDefaultCertValidityPolicy; + +#if CHIP_CONFIG_ENABLE_SESSION_RESUMPTION + static chip::SimpleSessionResumptionStorage sSessionResumptionStorage; +#endif + static chip::app::DefaultAclStorage sAclStorage; + + // KVS-based persistent storage delegate injection + if (persistentStorageDelegate == nullptr) + { + chip::DeviceLayer::PersistedStorage::KeyValueStoreManager & kvsManager = + DeviceLayer::PersistedStorage::KeyValueStoreMgr(); + ReturnErrorOnFailure(sKvsPersistenStorageDelegate.Init(&kvsManager)); + this->persistentStorageDelegate = &sKvsPersistenStorageDelegate; + } + + // PersistentStorageDelegate "software-based" operational key access injection + if (this->operationalKeystore == nullptr) + { + // WARNING: PersistentStorageOperationalKeystore::Finish() is never called. It's fine for + // for examples and for now. + ReturnErrorOnFailure(sPersistentStorageOperationalKeystore.Init(this->persistentStorageDelegate)); + this->operationalKeystore = &sPersistentStorageOperationalKeystore; + } + + // OpCertStore can be injected but default to persistent storage default + // for simplicity of the examples. + if (this->opCertStore == nullptr) + { + // WARNING: PersistentStorageOpCertStore::Finish() is never called. It's fine for + // for examples and for now, since all storage is immediate for that impl. + ReturnErrorOnFailure(sPersistentStorageOpCertStore.Init(this->persistentStorageDelegate)); + this->opCertStore = &sPersistentStorageOpCertStore; + } + + // Group Data provider injection + sGroupDataProvider.SetStorageDelegate(this->persistentStorageDelegate); + ReturnErrorOnFailure(sGroupDataProvider.Init()); + this->groupDataProvider = &sGroupDataProvider; + +#if CHIP_CONFIG_ENABLE_SESSION_RESUMPTION + ReturnErrorOnFailure(sSessionResumptionStorage.Init(this->persistentStorageDelegate)); + this->sessionResumptionStorage = &sSessionResumptionStorage; +#else + this->sessionResumptionStorage = nullptr; +#endif + + // Inject access control delegate + this->accessDelegate = Access::Examples::GetAccessControlDelegate(); + + // Inject ACL storage. (Don't initialize it.) + this->aclStorage = &sAclStorage; + + // Inject certificate validation policy compatible with non-wall-clock-time-synced + // embedded systems. + this->certificateValidityPolicy = &sDefaultCertValidityPolicy; + + return CHIP_NO_ERROR; + } +}; + +#endif + +void ChipLinuxAppMainLoop() +{ +#ifdef ENABLE_HSM_EC_KEY + static CommonCaseDeviceServerInitParams_Se05x initParams; +#else + static chip::CommonCaseDeviceServerInitParams initParams; +#endif + VerifyOrDie(initParams.InitializeStaticResourcesBeforeServerInit() == CHIP_NO_ERROR); + +#if defined(ENABLE_CHIP_SHELL) + Engine::Root().Init(); + std::thread shellThread([]() { Engine::Root().RunMainLoop(); }); + Shell::RegisterCommissioneeCommands(); +#endif + initParams.operationalServicePort = CHIP_PORT; + initParams.userDirectedCommissioningPort = CHIP_UDC_PORT; + +#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE || CHIP_DEVICE_ENABLE_PORT_PARAMS + // use a different service port to make testing possible with other sample devices running on same host + initParams.operationalServicePort = LinuxDeviceOptions::GetInstance().securedDevicePort; + initParams.userDirectedCommissioningPort = LinuxDeviceOptions::GetInstance().unsecuredCommissionerPort; +#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + + initParams.interfaceId = LinuxDeviceOptions::GetInstance().interfaceId; + + if (LinuxDeviceOptions::GetInstance().mCSRResponseOptions.csrExistingKeyPair) + { + LinuxDeviceOptions::GetInstance().mCSRResponseOptions.badCsrOperationalKeyStoreForTest.Init( + initParams.persistentStorageDelegate); + initParams.operationalKeystore = &LinuxDeviceOptions::GetInstance().mCSRResponseOptions.badCsrOperationalKeyStoreForTest; + } + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan( + LinuxDeviceOptions::GetInstance().testEventTriggerEnableKey) }; + initParams.testEventTriggerDelegate = &testEventTriggerDelegate; +#endif + + // We need to set DeviceInfoProvider before Server::Init to setup the storage of DeviceInfoProvider properly. + DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); + + // Init ZCL Data Model and CHIP App Server + Server::GetInstance().Init(initParams); + + // Now that the server has started and we are done with our startup logging, + // log our discovery/onboarding information again so it's not lost in the + // noise. + ConfigurationMgr().LogDeviceConfig(); + + PrintOnboardingCodes(LinuxDeviceOptions::GetInstance().payload); + + // Initialize device attestation config +#ifdef ENABLE_HSM_DEVICE_ATTESTATION + SetDeviceAttestationCredentialsProvider(Examples::GetExampleSe05xDACProvider()); +#else + SetDeviceAttestationCredentialsProvider(LinuxDeviceOptions::GetInstance().dacProvider); +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + ChipLogProgress(AppServer, "Starting commissioner"); + VerifyOrReturn(InitCommissioner(LinuxDeviceOptions::GetInstance().securedCommissionerPort + 10, + LinuxDeviceOptions::GetInstance().unsecuredCommissionerPort) == CHIP_NO_ERROR); + ChipLogProgress(AppServer, "Started commissioner"); +#if defined(ENABLE_CHIP_SHELL) + Shell::RegisterControllerCommands(); +#endif // defined(ENABLE_CHIP_SHELL) +#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + + ApplicationInit(); + + DeviceLayer::PlatformMgr().RunEventLoop(); + +#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + ShutdownCommissioner(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + +#if defined(ENABLE_CHIP_SHELL) + shellThread.join(); +#endif + + Server::GetInstance().Shutdown(); + + DeviceLayer::PlatformMgr().Shutdown(); + + Cleanup(); +} diff --git a/examples/platform/nxp/se05x/linux/BUILD.gn b/examples/platform/nxp/se05x/linux/BUILD.gn new file mode 100644 index 00000000000000..4956883bcec584 --- /dev/null +++ b/examples/platform/nxp/se05x/linux/BUILD.gn @@ -0,0 +1,120 @@ +# Copyright (c) 2020 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}/examples/common/pigweed/pigweed_rpcs.gni") +import("${chip_root}/src/app/common_flags.gni") +import("${chip_root}/src/crypto/crypto.gni") +import("${chip_root}/src/lib/core/core.gni") +import("${chip_root}/src/lib/lib.gni") + +config("app-main-config") { + include_dirs = [ "." ] +} + +source_set("ota-test-event-trigger") { + sources = [ + "${chip_root}/src/app/clusters/ota-requestor/OTATestEventTriggerDelegate.h", + ] +} + +source_set("app-main") { + defines = [] + sources = [ + "${chip_root}/examples/platform/linux/AppMain.h", + "${chip_root}/examples/platform/linux/CommissionableInit.cpp", + "${chip_root}/examples/platform/linux/CommissionableInit.h", + "${chip_root}/examples/platform/linux/CommissioneeShellCommands.cpp", + "${chip_root}/examples/platform/linux/CommissioneeShellCommands.h", + "${chip_root}/examples/platform/linux/CommissionerMain.cpp", + "${chip_root}/examples/platform/linux/CommissionerMain.h", + "${chip_root}/examples/platform/linux/ControllerShellCommands.cpp", + "${chip_root}/examples/platform/linux/ControllerShellCommands.h", + "${chip_root}/examples/platform/linux/LinuxCommissionableDataProvider.cpp", + "${chip_root}/examples/platform/linux/LinuxCommissionableDataProvider.h", + "${chip_root}/examples/platform/linux/NamedPipeCommands.cpp", + "${chip_root}/examples/platform/linux/NamedPipeCommands.h", + "${chip_root}/examples/platform/linux/Options.cpp", + "${chip_root}/examples/platform/linux/Options.h", + "${chip_root}/examples/platform/linux/testing/CustomCSRResponse.cpp", + "${chip_root}/examples/platform/linux/testing/CustomCSRResponse.h", + "${chip_root}/examples/platform/linux/testing/CustomCSRResponseOperationalKeyStore.cpp", + "${chip_root}/examples/platform/linux/testing/CustomCSRResponseOperationalKeyStore.h", + "${chip_root}/examples/platform/nxp/se05x/DeviceAttestationSe05xCredsExample.cpp", + "${chip_root}/examples/platform/nxp/se05x/DeviceAttestationSe05xCredsExample_v2.cpp", + "AppMain.cpp", + ] + + include_dirs = [ + "${chip_root}/examples/platform/linux", + "${chip_root}/examples/platform/nxp/se05x", + ] + + defines = [] + + if (chip_enable_pw_rpc) { + defines += [ "PW_RPC_ENABLED" ] + } + if (chip_build_libshell) { + defines += [ "ENABLE_CHIP_SHELL" ] + } + + public_deps = [ + ":ota-test-event-trigger", + "${chip_root}/examples/providers:device_info_provider", + "${chip_root}/src/app/server", + "${chip_root}/src/credentials:default_attestation_verifier", + "${chip_root}/src/lib", + "${chip_root}/src/lib/shell", + "${chip_root}/src/lib/shell:shell_core", + ] + + if (chip_enable_transport_trace) { + public_deps += + [ "${chip_root}/examples/common/tracing:trace_handlers_decoder" ] + } + + public_configs = [ ":app-main-config" ] +} + +source_set("commissioner-main") { + defines = [] + sources = [ + "${chip_root}/examples/platform/linux/CommissionerMain.cpp", + "${chip_root}/examples/platform/linux/CommissionerMain.h", + ] + + defines = [] + + if (chip_enable_pw_rpc) { + defines += [ "PW_RPC_ENABLED" ] + } + if (chip_build_libshell) { + defines += [ "ENABLE_CHIP_SHELL" ] + } + + public_deps = [ + "${chip_root}/src/app/server", + "${chip_root}/src/credentials:default_attestation_verifier", + "${chip_root}/src/lib", + "${chip_root}/src/lib/shell", + "${chip_root}/src/lib/shell:shell_core", + ] + + if (chip_enable_transport_trace) { + public_deps += [ "${chip_root}/examples/common/tracing:trace_handlers" ] + } + + public_configs = [ ":app-main-config" ] +} diff --git a/examples/thermostat/nxp/linux-se05x/.gn b/examples/thermostat/nxp/linux-se05x/.gn new file mode 100644 index 00000000000000..5d1ce757507582 --- /dev/null +++ b/examples/thermostat/nxp/linux-se05x/.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2020 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/build.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + import("//args.gni") +} diff --git a/examples/thermostat/nxp/linux-se05x/BUILD.gn b/examples/thermostat/nxp/linux-se05x/BUILD.gn new file mode 100644 index 00000000000000..1f5851a30caeca --- /dev/null +++ b/examples/thermostat/nxp/linux-se05x/BUILD.gn @@ -0,0 +1,32 @@ +# Copyright (c) 2020 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/build.gni") +import("//build_overrides/chip.gni") + +executable("thermostat-se05x-app") { + sources = [ "${chip_root}/examples/thermostat/linux/main.cpp" ] + + include_dirs = [ "${chip_root}/examples/platform/linux" ] + + deps = [ + "${chip_root}/examples/platform/nxp/se05x/linux:app-main", + "${chip_root}/examples/thermostat/thermostat-common", + "${chip_root}/src/lib", + ] + + cflags = [ "-Wconversion" ] + + output_dir = root_out_dir +} diff --git a/examples/thermostat/nxp/linux-se05x/args.gni b/examples/thermostat/nxp/linux-se05x/args.gni new file mode 100644 index 00000000000000..7f8ae31b2a2a4b --- /dev/null +++ b/examples/thermostat/nxp/linux-se05x/args.gni @@ -0,0 +1,18 @@ +# Copyright (c) 2020 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}/config/standalone/args.gni") +chip_with_se05x = 1 +host = "host_linux" diff --git a/examples/thermostat/nxp/linux-se05x/build_overrides b/examples/thermostat/nxp/linux-se05x/build_overrides new file mode 120000 index 00000000000000..995884e6163eb5 --- /dev/null +++ b/examples/thermostat/nxp/linux-se05x/build_overrides @@ -0,0 +1 @@ +../../../build_overrides \ No newline at end of file diff --git a/examples/thermostat/nxp/linux-se05x/third_party/connectedhomeip b/examples/thermostat/nxp/linux-se05x/third_party/connectedhomeip new file mode 120000 index 00000000000000..59307833b4fee9 --- /dev/null +++ b/examples/thermostat/nxp/linux-se05x/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../.. \ No newline at end of file diff --git a/src/credentials/BUILD.gn b/src/credentials/BUILD.gn index 7e33874fe22402..b33a9bcdbf1b5d 100644 --- a/src/credentials/BUILD.gn +++ b/src/credentials/BUILD.gn @@ -69,10 +69,6 @@ static_library("credentials") { ] } - if (chip_with_se05x == 1) { - sources += [ "${chip_root}/examples/platform/nxp/se05x/DeviceAttestationSe05xCredsExample.cpp" ] - } - if (chip_device_platform == "esp32" || chip_device_platform == "nrfconnect" || chip_device_platform == "efr32") { defines = [ "CURRENT_TIME_NOT_IMPLEMENTED=1" ] diff --git a/src/crypto/BUILD.gn b/src/crypto/BUILD.gn index 0a2a49a1bc1a58..2ee770eb4045b2 100644 --- a/src/crypto/BUILD.gn +++ b/src/crypto/BUILD.gn @@ -58,10 +58,6 @@ buildconfig_header("crypto_buildconfig") { defines += [ "CHIP_CRYPTO_HSM=0" ] defines += [ "CHIP_CRYPTO_HSM_NXP=0" ] } - - if (chip_with_se05x_da == 1) { - defines += [ "ENABLE_HSM_DEVICE_ATTESTATION=1" ] - } } source_set("public_headers") { diff --git a/src/crypto/crypto.gni b/src/crypto/crypto.gni index 24498f5d9339b1..1c99fb9c85d2cd 100644 --- a/src/crypto/crypto.gni +++ b/src/crypto/crypto.gni @@ -16,5 +16,4 @@ declare_args() { # Crypto implementation: mbedtls, openssl, tinycrypt, boringssl, platform. chip_crypto = "" chip_with_se05x = 0 - chip_with_se05x_da = 0 } diff --git a/src/crypto/hsm/CHIPCryptoPALHsm_config.h b/src/crypto/hsm/CHIPCryptoPALHsm_config.h index 1c3b611be8c581..27d6eb2e1e33d2 100644 --- a/src/crypto/hsm/CHIPCryptoPALHsm_config.h +++ b/src/crypto/hsm/CHIPCryptoPALHsm_config.h @@ -25,7 +25,7 @@ /* * Enable HSM for SPAKE VERIFIER */ -#define ENABLE_HSM_SPAKE_VERIFIER 1 +#define ENABLE_HSM_SPAKE_VERIFIER 0 /* * Enable HSM for SPAKE PROVER @@ -59,6 +59,7 @@ #if ((CHIP_CRYPTO_HSM) && (ENABLE_HSM_GENERATE_EC_KEY)) #define ENABLE_HSM_EC_KEY //#define ENABLE_HSM_ECDSA_VERIFY +//#define ENABLE_HSM_DEVICE_ATTESTATION #endif #if ((CHIP_CRYPTO_HSM) && (ENABLE_HSM_PBKDF2_SHA256)) diff --git a/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_PBKDF.cpp b/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_PBKDF.cpp index a75a760318fda6..9fe746bc1718d7 100644 --- a/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_PBKDF.cpp +++ b/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_PBKDF.cpp @@ -50,6 +50,28 @@ CHIP_ERROR PBKDF2_sha256HSM::pbkdf2_sha256(const uint8_t * password, size_t plen VerifyOrReturnError(keyid != kKeyId_NotInitialized, CHIP_ERROR_HSM); + ChipLogDetail(Crypto, "Using se05x for pbkdf2 sha256"); + + static sss_policy_u commonPol; + commonPol.type = KPolicy_Common; + commonPol.auth_obj_id = 0; + commonPol.policy.common.req_Sm = 0; + commonPol.policy.common.can_Delete = 1; + commonPol.policy.common.can_Read = 1; + commonPol.policy.common.can_Write = 1; + + static sss_policy_u hmac_withPol; + hmac_withPol.type = KPolicy_Sym_Key; + hmac_withPol.auth_obj_id = 0; + hmac_withPol.policy.symmkey.can_Write = 1; + hmac_withPol.policy.symmkey.can_PBKDF = 1; + hmac_withPol.policy.symmkey.can_PBKDF = 1; + + sss_policy_t policy_for_hmac_key; + policy_for_hmac_key.nPolicies = 2; + policy_for_hmac_key.policies[0] = &hmac_withPol; + policy_for_hmac_key.policies[1] = &commonPol; + se05x_sessionOpen(); VerifyOrReturnError(gex_sss_chip_ctx.ks.session != NULL, CHIP_ERROR_INTERNAL); @@ -63,12 +85,14 @@ CHIP_ERROR PBKDF2_sha256HSM::pbkdf2_sha256(const uint8_t * password, size_t plen kKeyObject_Mode_Transient); VerifyOrReturnError(status == kStatus_SSS_Success, CHIP_ERROR_INTERNAL); - status = sss_key_store_set_key(&gex_sss_chip_ctx.ks, &hmacKeyObj, password, plen, plen * 8, NULL, 0); + status = sss_key_store_set_key(&gex_sss_chip_ctx.ks, &hmacKeyObj, password, plen, plen * 8, &policy_for_hmac_key, + sizeof(policy_for_hmac_key)); VerifyOrReturnError(status == kStatus_SSS_Success, CHIP_ERROR_INTERNAL); - const smStatus_t smStatus = - Se05x_API_PBKDF2(&((sss_se05x_session_t *) &gex_sss_chip_ctx.session)->s_ctx, keyid, kSE05x_Pbkdf2_HMAC_SHA256, salt, slen, - (uint16_t) iteration_count, (uint16_t) key_length, output, (size_t *) &key_length); + const smStatus_t smStatus = Se05x_API_PBKDF2_extended( + &((sss_se05x_session_t *) &gex_sss_chip_ctx.session)->s_ctx, keyid, salt, slen, 0, /*saltID*/ + (uint16_t) iteration_count, kSE05x_MACAlgo_HMAC_SHA256, (uint16_t) key_length, 0, /* derivedSessionKeyID */ + output, (size_t *) &key_length); VerifyOrExit(smStatus == SM_OK, error = CHIP_ERROR_INTERNAL); error = CHIP_NO_ERROR; exit: diff --git a/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_Spake2p.cpp b/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_Spake2p.cpp index 346ff8342641ce..48c7b021ef3e96 100644 --- a/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_Spake2p.cpp +++ b/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_Spake2p.cpp @@ -261,8 +261,8 @@ CHIP_ERROR Spake2pHSM_P256_SHA256_HKDF_HMAC::BeginVerifier(const uint8_t * my_id SE05x_SPAKE2PLUS_DEVICE_TYPE_B); VerifyOrReturnError(smstatus == SM_OK, CHIP_ERROR(chip::ChipError::Range::kPlatform, smstatus)); - ReturnErrorOnFailure(se05x_set_key(w0in_id_v, w0in_mod, w0in_mod_len, kSSS_KeyPart_Default, kSSS_CipherType_HMAC)); - ReturnErrorOnFailure(se05x_set_key(Lin_id_v, Lin, Lin_len, kSSS_KeyPart_Default, kSSS_CipherType_HMAC)); + ReturnErrorOnFailure(se05x_set_key_for_spake(w0in_id_v, w0in_mod, w0in_mod_len, kSSS_KeyPart_Default, kSSS_CipherType_HMAC)); + ReturnErrorOnFailure(se05x_set_key_for_spake(Lin_id_v, Lin, Lin_len, kSSS_KeyPart_Default, kSSS_CipherType_HMAC)); smstatus = Se05x_API_PAKEInitDevice(&((sss_se05x_session_t *) &gex_sss_chip_ctx.session)->s_ctx, hsm_pake_context.spake_objId, (uint8_t *) hsm_pake_context.spake_context, hsm_pake_context.spake_context_len, @@ -321,8 +321,8 @@ CHIP_ERROR Spake2pHSM_P256_SHA256_HKDF_HMAC::BeginProver(const uint8_t * my_iden SE05x_SPAKE2PLUS_DEVICE_TYPE_A); VerifyOrReturnError(smstatus == SM_OK, CHIP_ERROR(chip::ChipError::Range::kPlatform, smstatus)); - ReturnErrorOnFailure(se05x_set_key(w0in_id_p, w0in_mod, w0in_mod_len, kSSS_KeyPart_Default, kSSS_CipherType_HMAC)); - ReturnErrorOnFailure(se05x_set_key(w1in_id_p, w1in_mod, w1in_mod_len, kSSS_KeyPart_Default, kSSS_CipherType_HMAC)); + ReturnErrorOnFailure(se05x_set_key_for_spake(w0in_id_p, w0in_mod, w0in_mod_len, kSSS_KeyPart_Default, kSSS_CipherType_HMAC)); + ReturnErrorOnFailure(se05x_set_key_for_spake(w1in_id_p, w1in_mod, w1in_mod_len, kSSS_KeyPart_Default, kSSS_CipherType_HMAC)); smstatus = Se05x_API_PAKEInitDevice(&((sss_se05x_session_t *) &gex_sss_chip_ctx.session)->s_ctx, hsm_pake_context.spake_objId, (uint8_t *) hsm_pake_context.spake_context, hsm_pake_context.spake_context_len, diff --git a/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_utils.cpp b/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_utils.cpp index abedf608fc7c3f..2545ecf5a657c1 100644 --- a/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_utils.cpp +++ b/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_utils.cpp @@ -146,7 +146,8 @@ void se05x_delete_key(uint32_t keyid) } /* Set key in se05x */ -CHIP_ERROR se05x_set_key(uint32_t keyid, const uint8_t * key, size_t keylen, sss_key_part_t keyPart, sss_cipher_type_t cipherType) +CHIP_ERROR se05x_set_key_for_spake(uint32_t keyid, const uint8_t * key, size_t keylen, sss_key_part_t keyPart, + sss_cipher_type_t cipherType) { sss_status_t status = kStatus_SSS_Success; sss_object_t keyObject = { 0 }; @@ -167,10 +168,10 @@ CHIP_ERROR se05x_set_key(uint32_t keyid, const uint8_t * key, size_t keylen, sss commonPol.policy.common.can_Write = 1; static sss_policy_u hmac_withPol; - hmac_withPol.type = KPolicy_Asym_Key; - hmac_withPol.auth_obj_id = 0; - hmac_withPol.policy.asymmkey.can_Write = 1; - hmac_withPol.policy.asymmkey.can_KA = 1; + hmac_withPol.type = KPolicy_Sym_Key; + hmac_withPol.auth_obj_id = 0; + hmac_withPol.policy.symmkey.can_Write = 1; + hmac_withPol.policy.symmkey.can_KA = 1; sss_policy_t policy_for_hmac_key; policy_for_hmac_key.nPolicies = 2; @@ -236,6 +237,42 @@ CHIP_ERROR se05xGetCertificate(uint32_t keyId, uint8_t * buf, size_t * buflen) return CHIP_NO_ERROR; } +CHIP_ERROR se05xSetCertificate(uint32_t keyId, const uint8_t * buf, size_t buflen) +{ + sss_object_t keyObject = { 0 }; + sss_status_t status = kStatus_SSS_Fail; + + status = sss_key_object_init(&keyObject, &gex_sss_chip_ctx.ks); + VerifyOrReturnError(status == kStatus_SSS_Success, CHIP_ERROR_INTERNAL); + + status = sss_key_object_allocate_handle(&keyObject, keyId, kSSS_KeyPart_Default, kSSS_CipherType_Certificate, buflen, + kKeyObject_Mode_Transient); + VerifyOrReturnError(status == kStatus_SSS_Success, CHIP_ERROR_INTERNAL); + + status = sss_key_store_set_key(&gex_sss_chip_ctx.ks, &keyObject, buf, buflen, buflen * 8, NULL, 0); + VerifyOrReturnError(status == kStatus_SSS_Success, CHIP_ERROR_INTERNAL); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR se05xPerformInternalSign(uint32_t keyId, uint8_t * sigBuf, size_t * sigBufLen) +{ +#if SSS_HAVE_APPLET_SE051_H + smStatus_t status = SM_NOT_OK; + sss_se05x_session_t * pSe05xCtx = (sss_se05x_session_t *) &gex_sss_chip_ctx.session; + uint8_t hashData[chip::Crypto::kSHA256_Hash_Length] = { 0 }; + size_t hashDataLen = sizeof(hashData); + + status = Se05x_API_ECDSA_Internal_Sign(&(pSe05xCtx->s_ctx), keyId, kSE05x_ECSignatureAlgo_SHA_256, sigBuf, sigBufLen, hashData, + &hashDataLen); + VerifyOrReturnError(status == SM_OK, CHIP_ERROR_INTERNAL); + return CHIP_NO_ERROR; +#else + /* Enable Se051H to use internal sign */ + return CHIP_ERROR_INTERNAL; +#endif +} + #if ENABLE_REENTRANCY /* Init crypto object mutext */ diff --git a/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_utils.h b/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_utils.h index e5e3bb12ce9ba7..75e59a64109649 100644 --- a/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_utils.h +++ b/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_utils.h @@ -77,7 +77,8 @@ void se05x_sessionOpen(void); void se05x_delete_key(uint32_t keyid); /* Set key in se05x */ -CHIP_ERROR se05x_set_key(uint32_t keyid, const uint8_t * key, size_t keylen, sss_key_part_t keyPart, sss_cipher_type_t cipherType); +CHIP_ERROR se05x_set_key_for_spake(uint32_t keyid, const uint8_t * key, size_t keylen, sss_key_part_t keyPart, + sss_cipher_type_t cipherType); #if ENABLE_REENTRANCY diff --git a/src/crypto/hsm/nxp/README.md b/src/crypto/hsm/nxp/README.md index ffc859346374c1..0a6d492cdf72d3 100644 --- a/src/crypto/hsm/nxp/README.md +++ b/src/crypto/hsm/nxp/README.md @@ -24,7 +24,6 @@ Following are the list operations supported by secure element. ``` chip_with_se05x=1 ==> To enable Se05x host = "host_k32w" ==> To set host -chip_with_se05x_da=1 ==> To enable device attestation using se05x. Provision key at key id = '0xDADADADA'. Also enable `ENABLE_HSM_GENERATE_EC_KEY` in CHIPCryptoPALHsm_config.h file. ``` ## Known Limitations: diff --git a/third_party/simw-top-mini/repo b/third_party/simw-top-mini/repo index aa51a4c0e93257..bb2b2e95335394 160000 --- a/third_party/simw-top-mini/repo +++ b/third_party/simw-top-mini/repo @@ -1 +1 @@ -Subproject commit aa51a4c0e9325761cba47c07b9f3d1d4343f84f1 +Subproject commit bb2b2e95335394c999812de97a8bec73d7c6dc1a