Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add hardware-based security support for the i.MX series chips. #37974

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -354,3 +354,10 @@
url = https://github.com/paullouisageneau/libdatachannel.git
platforms = linux
recursive = true
[submodule "third_party/libtrustymatter/repo"]
path = third_party/libtrustymatter/repo
url = https://github.com/nxp-imx/libtrustymatter
[submodule "repo"]
path = third_party/imx-secure-enclave/repo
url = ssh://[email protected]/lfac/secure_enclave.git
branch = lf-6.12.3_1.0.0
38 changes: 38 additions & 0 deletions examples/platform/linux/AppMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* 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.
*
* Copyright 2023 NXP
*/

#include <platform/CHIPDeviceLayer.h>
Expand Down Expand Up @@ -126,6 +128,26 @@
#include <platform/Linux/NetworkCommissioningDriver.h>
#endif // CHIP_DEVICE_LAYER_TARGET_LINUX

#if CHIP_ATTESTATION_TRUSTY_OS
#include "DeviceAttestationCredsTrusty.h"
using namespace chip::Credentials::Trusty;
#endif

#if CHIP_OP_KEYSTORE_TRUSTY_OS
#include "PersistentStorageOperationalKeystoreTrusty.h"
using namespace chip::Trusty;
#endif

#if CHIP_ATTESTATION_ELE
#include "DeviceAttestationCredsEle.h"
using namespace chip::Credentials::ele;
#endif

#if CHIP_OP_KEYSTORE_ELE
#include "PersistentStorageOperationalKeystoreEle.h"
using namespace chip::ele;
#endif

using namespace chip;
using namespace chip::ArgParser;
using namespace chip::Credentials;
Expand Down Expand Up @@ -556,6 +578,16 @@ void ChipLinuxAppMainLoop(AppMainLoopImplementation * impl)
}
#endif // CHIP_CONFIG_TERMS_AND_CONDITIONS_REQUIRED

#if CHIP_OP_KEYSTORE_TRUSTY_OS
static chip::Trusty::PersistentStorageOperationalKeystoreTrusty sPersistentStorageOperationalKeystore;
initParams.operationalKeystore = &sPersistentStorageOperationalKeystore;
#endif

#if CHIP_OP_KEYSTORE_ELE
static chip::ele::PersistentStorageOperationalKeystoreEle sPersistentStorageOperationalKeystore;
initParams.operationalKeystore = &sPersistentStorageOperationalKeystore;
#endif

#if defined(ENABLE_CHIP_SHELL)
Engine::Root().Init();
Shell::RegisterCommissioneeCommands();
Expand Down Expand Up @@ -695,7 +727,13 @@ void ChipLinuxAppMainLoop(AppMainLoopImplementation * impl)
PrintOnboardingCodes(LinuxDeviceOptions::GetInstance().payload);

// Initialize device attestation config
#if CHIP_ATTESTATION_TRUSTY_OS
SetDeviceAttestationCredentialsProvider(&TrustyDACProvider::GetTrustyDACProvider());
#elif CHIP_ATTESTATION_ELE
SetDeviceAttestationCredentialsProvider(&EleDACProvider::GetEleDACProvider());
#else
SetDeviceAttestationCredentialsProvider(LinuxDeviceOptions::GetInstance().dacProvider);
#endif

#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
ChipLogProgress(AppServer, "Starting commissioner");
Expand Down
48 changes: 48 additions & 0 deletions examples/platform/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import("${chip_root}/src/app/icd/icd.gni")
import("${chip_root}/src/lib/core/core.gni")
import("${chip_root}/src/lib/lib.gni")
import("${chip_root}/src/tracing/tracing_args.gni")
import("${chip_root}/src/lib/trusty.gni")
import("${chip_root}/src/lib/imx_ele.gni")

if (current_os != "nuttx") {
import("//build_overrides/jsoncpp.gni")
Expand Down Expand Up @@ -96,6 +98,24 @@ source_set("app-main") {
"testing/CustomCSRResponseOperationalKeyStore.h",
]

if (chip_with_trusty_os == 1) {
sources += [
"DeviceAttestationCredsTrusty.cpp",
"DeviceAttestationCredsTrusty.h",
"PersistentStorageOperationalKeystoreTrusty.cpp",
"PersistentStorageOperationalKeystoreTrusty.h",
]
}

if (chip_with_imx_ele == 1) {
sources += [
"DeviceAttestationCredsEle.cpp",
"DeviceAttestationCredsEle.h",
"PersistentStorageOperationalKeystoreEle.cpp",
"PersistentStorageOperationalKeystoreEle.h",
]
}

public_deps = [
":boolean-state-configuration-test-event-trigger",
":commissioner-main",
Expand All @@ -122,6 +142,34 @@ source_set("app-main") {
public_deps += [ jsoncpp_root ]
}

if (chip_with_trusty_os == 1) {
public_deps += [ "${chip_root}/third_party/libtrustymatter" ]
}

if (chip_with_imx_ele == 1) {
public_deps += [ "${chip_root}/third_party/imx-secure-enclave:libelematter" ]
}

if (chip_with_trusty_os == 1) {
defines += [ "CHIP_ATTESTATION_TRUSTY_OS=1" ]
} else {
defines += [ "CHIP_ATTESTATION_TRUSTY_OS=0" ]
}

if (chip_with_trusty_os == 1) {
defines += [ "CHIP_OP_KEYSTORE_TRUSTY_OS=1" ]
} else {
defines += [ "CHIP_OP_KEYSTORE_TRUSTY_OS=0" ]
}

if (chip_with_imx_ele == 1) {
defines += [ "CHIP_OP_KEYSTORE_ELE=1" ]
defines += [ "CHIP_ATTESTATION_ELE=1" ]
} else {
defines += [ "CHIP_OP_KEYSTORE_ELE=0" ]
defines += [ "CHIP_ATTESTATION_ELE=0" ]
}

if (chip_enable_pw_rpc) {
defines += [ "PW_RPC_ENABLED" ]
}
Expand Down
207 changes: 207 additions & 0 deletions examples/platform/linux/DeviceAttestationCredsEle.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
/*
*
* Copyright (c) 2021-2022 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.
*
* Copyright 2023 NXP
*/
#include "DeviceAttestationCredsEle.h"

#include <crypto/CHIPCryptoPAL.h>
#include <lib/core/CHIPError.h>
#include <lib/support/Span.h>

#define KEY_STORE_ID (0xBBBB)
#define AUTHEN_NONCE (0x2222)
#define PAI_DATA_ID 0x1111
#define DAC_DATA_ID 0x1112
#define CD_DATA_ID 0x1113
#define DAC_PRIVATE_KEY_ID 0x1114

namespace chip {
namespace Credentials {
namespace ele {

EleDACProvider::EleDACProvider()
{
hsm_err_t err;

// open the session
open_session_args_t open_session_args = {0};
open_session_args.mu_type = HSM1;
err = hsm_open_session(&open_session_args, &hsm_session_hdl);
if (err != HSM_NO_ERROR) {
ChipLogDetail(Crypto, "ELE device attestation session open failed. ret: 0x%x\n", err);
return;
} else {
ChipLogDetail(Crypto, "ELE device attestation session open successfully.\n");
}

// open the keystore
open_svc_key_store_args_t open_svc_key_store_args = {0};
open_svc_key_store_args.key_store_identifier = KEY_STORE_ID;
open_svc_key_store_args.authentication_nonce = AUTHEN_NONCE;
// try to create a new keystore, if it already exist, open it
open_svc_key_store_args.flags = (HSM_SVC_KEY_STORE_FLAGS_CREATE | HSM_SVC_KEY_STORE_FLAGS_STRICT_OPERATION);
err = hsm_open_key_store_service(hsm_session_hdl, &open_svc_key_store_args, &key_store_hdl);
if (err == HSM_KEY_STORE_CONFLICT) {
ChipLogDetail(Crypto, "device attestation keystore already existed, open it...\n");
open_svc_key_store_args.flags = HSM_SVC_KEY_STORE_FLAGS_LOAD;
err = hsm_open_key_store_service(hsm_session_hdl, &open_svc_key_store_args, &key_store_hdl);
if (err != HSM_NO_ERROR) {
ChipLogDetail(Crypto, "device attestation keystore open failed. ret:0x%x\n", err);
return;
} else
ChipLogDetail(Crypto, "device attestation keystore open successfully.\n");
} else {
ChipLogDetail(Crypto, "device attestation keystore created successfully.\n");
}
}

EleDACProvider::~EleDACProvider()
{
hsm_err_t err;

ChipLogDetail(Crypto, "close all ELE device attestation services.\n");

err = hsm_close_key_store_service(key_store_hdl);
key_store_hdl = 0;
ChipLogDetail(Crypto, "close device attestation key store service returns:0x%x\n", err);

err = hsm_close_session(hsm_session_hdl);
hsm_session_hdl = 0;
ChipLogDetail(Crypto, "close ELE device attestation session returns:0x%x\n", err);
}

CHIP_ERROR EleDACProvider::GetDeviceAttestationCert(MutableByteSpan & out_dac_buffer)
{
op_data_storage_args_t data_storage_args;
hsm_err_t err;

data_storage_args.svc_flags = 0;
data_storage_args.data = out_dac_buffer.data();
data_storage_args.data_size = out_dac_buffer.size();
data_storage_args.data_id = DAC_DATA_ID;
data_storage_args.flags |= HSM_OP_DATA_STORAGE_FLAGS_RETRIEVE;
err = hsm_data_ops(key_store_hdl, &data_storage_args);
if (err) {
ChipLogDetail(Crypto, "ELE get DAC failed. ret: 0x%x\n", err);
return CHIP_ERROR_CERT_LOAD_FAILED;
}

out_dac_buffer.reduce_size(data_storage_args.exp_output_size);
return CHIP_NO_ERROR;
}

CHIP_ERROR EleDACProvider::GetProductAttestationIntermediateCert(MutableByteSpan & out_pai_buffer)
{
op_data_storage_args_t data_storage_args;
hsm_err_t err;

data_storage_args.svc_flags = 0;
data_storage_args.data = out_pai_buffer.data();
data_storage_args.data_size = out_pai_buffer.size();
data_storage_args.data_id = PAI_DATA_ID;
data_storage_args.flags |= HSM_OP_DATA_STORAGE_FLAGS_RETRIEVE;
err = hsm_data_ops(key_store_hdl, &data_storage_args);
if (err) {
ChipLogDetail(Crypto, "ELE get PAI failed. ret: 0x%x\n", err);
return CHIP_ERROR_CERT_LOAD_FAILED;
}

out_pai_buffer.reduce_size(data_storage_args.exp_output_size);
return CHIP_NO_ERROR;
}

CHIP_ERROR EleDACProvider::GetCertificationDeclaration(MutableByteSpan & out_cd_buffer)
{
op_data_storage_args_t data_storage_args;
hsm_err_t err;

data_storage_args.svc_flags = 0;
data_storage_args.data = out_cd_buffer.data();
data_storage_args.data_size = out_cd_buffer.size();
data_storage_args.data_id = CD_DATA_ID;
data_storage_args.flags |= HSM_OP_DATA_STORAGE_FLAGS_RETRIEVE;
err = hsm_data_ops(key_store_hdl, &data_storage_args);
if (err) {
ChipLogDetail(Crypto, "ELE get CD failed. ret: 0x%x\n", err);
return CHIP_ERROR_CERT_LOAD_FAILED;
}

out_cd_buffer.reduce_size(data_storage_args.exp_output_size);
return CHIP_NO_ERROR;
}

CHIP_ERROR EleDACProvider::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 EleDACProvider::SignWithDeviceAttestationKey(const ByteSpan & message_to_sign,
MutableByteSpan & out_signature_buffer)
{
open_svc_sign_gen_args_t open_sig_gen_args;
op_generate_sign_args_t sig_gen_args;
uint8_t signature[64];
hsm_hdl_t sig_gen_hdl;
size_t out_size = 0;
hsm_err_t hsmret;

VerifyOrReturnError(IsSpanUsable(out_signature_buffer), CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(IsSpanUsable(message_to_sign), CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(out_signature_buffer.size() >= sizeof(signature), CHIP_ERROR_BUFFER_TOO_SMALL);

// open signature generation service
memset(&open_sig_gen_args, 0, sizeof(open_sig_gen_args));
hsmret = hsm_open_signature_generation_service(key_store_hdl, &open_sig_gen_args, &sig_gen_hdl);
if (hsmret != HSM_NO_ERROR) {
ChipLogDetail(Crypto, "open signature generation service failed. ret:0x%x\n", hsmret);
return CHIP_ERROR_HSM;
}

// generate signature
memset(&sig_gen_args, 0, sizeof(sig_gen_args));
sig_gen_args.key_identifier = DAC_PRIVATE_KEY_ID;
sig_gen_args.scheme_id = HSM_SIGNATURE_SCHEME_ECDSA_SHA256;
sig_gen_args.message = (uint8_t *)(message_to_sign.data());
sig_gen_args.signature = signature;
sig_gen_args.message_size = message_to_sign.size();
sig_gen_args.signature_size = sizeof(signature);
sig_gen_args.flags = HSM_OP_GENERATE_SIGN_FLAGS_INPUT_MESSAGE;
hsmret = hsm_generate_signature(sig_gen_hdl, &sig_gen_args);
hsm_close_signature_generation_service(sig_gen_hdl);
if (hsmret != HSM_NO_ERROR) {
ChipLogDetail(Crypto, "generate signature failed. ret:0x%x\n", hsmret);
return CHIP_ERROR_HSM;
}

memcpy(out_signature_buffer.data(), signature, sizeof(signature));
out_signature_buffer.reduce_size(sizeof(signature));
return CHIP_NO_ERROR;
}

EleDACProvider & EleDACProvider::GetEleDACProvider()
{
static EleDACProvider ele_dac_provider;

return ele_dac_provider;
}

} // namespace Trusty
} // namespace Credentials
} // namespace chip
Loading
Loading