-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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. #38050
base: master
Are you sure you want to change the base?
Changes from all commits
25c088a
e6e6c98
afe7e37
dcb20ef
8327226
e385c0f
ab42e1f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
# Copyright (c) 2020 Project CHIP Authors | ||
# Copyright 2025 NXP | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
|
@@ -17,7 +18,9 @@ import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni") | |
import("${chip_root}/src/app/common_flags.gni") | ||
import("${chip_root}/src/app/icd/icd.gni") | ||
import("${chip_root}/src/lib/core/core.gni") | ||
import("${chip_root}/src/lib/imx_ele.gni") | ||
import("${chip_root}/src/lib/lib.gni") | ||
import("${chip_root}/src/lib/trusty.gni") | ||
import("${chip_root}/src/tracing/tracing_args.gni") | ||
|
||
if (current_os != "nuttx") { | ||
|
@@ -96,6 +99,25 @@ 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 += [ | ||
#TODO enable this when official tool ready | ||
# "DeviceAttestationCredsEle.cpp", | ||
# "DeviceAttestationCredsEle.h", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This checks in unused code .... should this be instead created when this "imx ele" is available? How about having separate sub-folders of these, since this bit is iMX specific? |
||
"PersistentStorageOperationalKeystoreEle.cpp", | ||
"PersistentStorageOperationalKeystoreEle.h", | ||
] | ||
} | ||
|
||
public_deps = [ | ||
":boolean-state-configuration-test-event-trigger", | ||
":commissioner-main", | ||
|
@@ -122,6 +144,36 @@ 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" ] | ||
#TODO enable this when official tool ready | ||
# 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" ] | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
/* | ||
* | ||
* Copyright (c) 2021-2022 Project CHIP Authors | ||
* Copyright 2023, 2025 NXP | ||
* | ||
* 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 "DeviceAttestationCredsEle.h" | ||
|
||
#include <crypto/CHIPCryptoPAL.h> | ||
#include <lib/core/CHIPError.h> | ||
#include <lib/support/Span.h> | ||
|
||
#define KEY_STORE_ID (0xBBBB) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use C++ constants: use Add comments of what these magic numbers mean and why they exist. |
||
#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 ele | ||
} // namespace Credentials | ||
} // namespace chip |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gn supports booleans. Do not use integers as booleans.