blob: 4b7e6ed9e9ae9a9cb5ac1fa9e558370d6bf27c82 [file] [log] [blame]
/*
*
* Copyright (c) 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.
*/
#include "FactoryDataProvider.h"
#include <mbedtls/pk.h>
#include <platform/internal/CHIPDeviceLayerInternal.h>
namespace chip {
namespace DeviceLayer {
using namespace chip::DeviceLayer::Internal;
CHIP_ERROR FactoryDataProvider::GetCertificationDeclaration(MutableByteSpan & out_cd_buffer)
{
size_t read_size;
ReturnErrorOnFailure(CYW30739Config::ReadConfigValueBin(CYW30739Config::kConfigKey_CertDeclaration, out_cd_buffer.data(),
out_cd_buffer.size(), read_size));
out_cd_buffer.reduce_size(read_size);
return CHIP_NO_ERROR;
}
CHIP_ERROR FactoryDataProvider::GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer)
{
out_firmware_info_buffer.reduce_size(0);
return CHIP_NO_ERROR;
}
CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & out_dac_buffer)
{
size_t read_size;
ReturnErrorOnFailure(CYW30739Config::ReadConfigValueBin(CYW30739Config::kConfigKey_DAC, out_dac_buffer.data(),
out_dac_buffer.size(), read_size));
out_dac_buffer.reduce_size(read_size);
return CHIP_NO_ERROR;
}
CHIP_ERROR FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & out_pai_buffer)
{
size_t read_size;
ReturnErrorOnFailure(CYW30739Config::ReadConfigValueBin(CYW30739Config::kConfigKey_PAICert, out_pai_buffer.data(),
out_pai_buffer.size(), read_size));
out_pai_buffer.reduce_size(read_size);
return CHIP_NO_ERROR;
}
CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & message_to_sign,
MutableByteSpan & out_signature_buffer)
{
Crypto::P256ECDSASignature signature;
Crypto::P256Keypair keypair;
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);
uint8_t dac_key_buffer[128];
MutableByteSpan dac_key_span(dac_key_buffer);
ReturnErrorOnFailure(GetDeviceAttestationCertKey(dac_key_span));
ReturnErrorOnFailure(LoadKeypairFromDer(dac_key_span, keypair));
ReturnErrorOnFailure(keypair.ECDSA_sign_msg(message_to_sign.data(), message_to_sign.size(), signature));
return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, out_signature_buffer);
}
CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCertKey(MutableByteSpan & out_key_buffer)
{
size_t read_size;
ReturnErrorOnFailure(CYW30739Config::ReadConfigValueBin(CYW30739Config::kConfigKey_DACKey, out_key_buffer.data(),
out_key_buffer.size(), read_size));
out_key_buffer.reduce_size(read_size);
return CHIP_NO_ERROR;
}
CHIP_ERROR FactoryDataProvider::LoadKeypairFromDer(const ByteSpan & der_buffer, Crypto::P256Keypair & keypair)
{
CHIP_ERROR error = CHIP_NO_ERROR;
int mbedtls_result = 0;
mbedtls_pk_context pk;
mbedtls_ecp_keypair * ecp;
Crypto::P256SerializedKeypair serializedKeypair;
MutableByteSpan public_key(serializedKeypair.Bytes(), Crypto::kP256_PublicKey_Length);
MutableByteSpan private_key(serializedKeypair.Bytes() + Crypto::kP256_PublicKey_Length, Crypto::kP256_PrivateKey_Length);
mbedtls_pk_init(&pk);
mbedtls_result = mbedtls_pk_parse_key(&pk, der_buffer.data(), der_buffer.size(), nullptr, 0);
VerifyOrExit(mbedtls_result == 0, error = CHIP_ERROR_INTERNAL);
ecp = mbedtls_pk_ec(pk);
VerifyOrExit(ecp != nullptr, error = CHIP_ERROR_INTERNAL);
size_t key_length;
mbedtls_result = mbedtls_ecp_point_write_binary(&ecp->grp, &ecp->Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &key_length, public_key.data(),
public_key.size());
VerifyOrExit(mbedtls_result == 0 && key_length == Crypto::kP256_PublicKey_Length, error = CHIP_ERROR_INTERNAL);
mbedtls_result = mbedtls_ecp_write_key(ecp, private_key.data(), private_key.size());
VerifyOrExit(mbedtls_result == 0, error = CHIP_ERROR_INTERNAL);
SuccessOrExit(error = serializedKeypair.SetLength(public_key.size() + private_key.size()));
SuccessOrExit(error = keypair.Deserialize(serializedKeypair));
exit:
if (mbedtls_result != 0)
{
ChipLogError(Crypto, "mbedtls result: 0x%04x", mbedtls_result);
}
mbedtls_pk_free(&pk);
return error;
}
} // namespace DeviceLayer
} // namespace chip