blob: 7da95e29b4e027eb917daf2e5f27455904ba8bd8 [file] [log] [blame]
/*
*
* Copyright (c) 2023 Project CHIP Authors
* Copyright 2023 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 "FactoryDataProviderFwkImpl.h"
#include "fwk_factory_data_provider.h"
namespace chip {
namespace DeviceLayer {
FactoryDataProviderImpl FactoryDataProviderImpl::sInstance;
CHIP_ERROR FactoryDataProviderImpl::SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length,
uint32_t * contentAddr)
{
CHIP_ERROR err = CHIP_ERROR_NOT_FOUND;
uint32_t readLen = 0;
uint8_t * ramBufferAddr = FDP_SearchForId(searchedType, pBuf, bufLength, &readLen);
if (ramBufferAddr != NULL)
{
if (contentAddr != NULL)
*contentAddr = (uint32_t) ramBufferAddr;
err = CHIP_NO_ERROR;
}
length = readLen;
return err;
}
CHIP_ERROR FactoryDataProviderImpl::SignWithDacKey(const ByteSpan & digestToSign, MutableByteSpan & outSignBuffer)
{
Crypto::P256ECDSASignature signature;
Crypto::P256Keypair keypair;
VerifyOrReturnError(IsSpanUsable(outSignBuffer), CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(IsSpanUsable(digestToSign), CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(outSignBuffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL);
// In a non-exemplary implementation, the public key is not needed here. It is used here merely because
// Crypto::P256Keypair is only (currently) constructable from raw keys if both private/public keys are present.
Crypto::P256PublicKey dacPublicKey;
uint16_t certificateSize = 0;
uint32_t certificateAddr;
ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacCertificateId, NULL, 0, certificateSize, &certificateAddr));
MutableByteSpan dacCertSpan((uint8_t *) certificateAddr, certificateSize);
/* Extract Public Key of DAC certificate from itself */
ReturnErrorOnFailure(Crypto::ExtractPubkeyFromX509Cert(dacCertSpan, dacPublicKey));
/* Get private key of DAC certificate from reserved section */
uint16_t keySize = 0;
uint32_t keyAddr;
ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacPrivateKeyId, NULL, 0, keySize, &keyAddr));
MutableByteSpan dacPrivateKeySpan((uint8_t *) keyAddr, keySize);
ReturnErrorOnFailure(LoadKeypairFromRaw(ByteSpan(dacPrivateKeySpan.data(), dacPrivateKeySpan.size()),
ByteSpan(dacPublicKey.Bytes(), dacPublicKey.Length()), keypair));
ReturnErrorOnFailure(keypair.ECDSA_sign_msg(digestToSign.data(), digestToSign.size(), signature));
return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer);
}
CHIP_ERROR FactoryDataProviderImpl::LoadKeypairFromRaw(ByteSpan privateKey, ByteSpan publicKey, Crypto::P256Keypair & keypair)
{
Crypto::P256SerializedKeypair serialized_keypair;
ReturnErrorOnFailure(serialized_keypair.SetLength(privateKey.size() + publicKey.size()));
memcpy(serialized_keypair.Bytes(), publicKey.data(), publicKey.size());
memcpy(serialized_keypair.Bytes() + publicKey.size(), privateKey.data(), privateKey.size());
return keypair.Deserialize(serialized_keypair);
}
CHIP_ERROR FactoryDataProviderImpl::Init(void)
{
/*
* Currently the fwk_factory_data_provider module supports only ecb mode.
* Therefore return an error if encrypt mode is not ecb
*/
if (pAesKey == NULL || encryptMode != encrypt_ecb)
{
return CHIP_ERROR_INVALID_ARGUMENT;
}
if (FDP_Init(pAesKey) < 0)
{
return CHIP_ERROR_INTERNAL;
}
return CHIP_NO_ERROR;
}
CHIP_ERROR FactoryDataProviderImpl::SetAes128Key(const uint8_t * keyAes128)
{
CHIP_ERROR error = CHIP_ERROR_INVALID_ARGUMENT;
if (keyAes128 != nullptr)
{
pAesKey = keyAes128;
error = CHIP_NO_ERROR;
}
return error;
}
CHIP_ERROR FactoryDataProviderImpl::SetEncryptionMode(EncryptionMode mode)
{
CHIP_ERROR error = CHIP_ERROR_INVALID_ARGUMENT;
/*
* Currently the fwk_factory_data_provider module supports only ecb mode.
* Therefore return an error if encrypt mode is not ecb
*/
if (mode == encrypt_ecb)
{
encryptMode = mode;
error = CHIP_NO_ERROR;
}
return error;
}
} // namespace DeviceLayer
} // namespace chip