/* * * Copyright (c) 2022-2024 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 "CHIPDevicePlatformConfig.h" #include #include #if CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE #include #include #endif #include namespace chip { namespace { CHIP_ERROR LoadKeypairFromRaw(ByteSpan privateKey, ByteSpan publicKey, Crypto::P256Keypair & keypair) { Crypto::P256SerializedKeypair serializedKeypair; ReturnErrorOnFailure(serializedKeypair.SetLength(privateKey.size() + publicKey.size())); memcpy(serializedKeypair.Bytes(), publicKey.data(), publicKey.size()); memcpy(serializedKeypair.Bytes() + publicKey.size(), privateKey.data(), privateKey.size()); return keypair.Deserialize(serializedKeypair); } CHIP_ERROR GetFactoryDataString(const FactoryDataString & str, char * buf, size_t bufSize) { VerifyOrReturnError(bufSize >= str.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); VerifyOrReturnError(str.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(buf, str.data, str.len); buf[str.len] = 0; return CHIP_NO_ERROR; } } // namespace namespace DeviceLayer { template CHIP_ERROR FactoryDataProvider::Init() { uint8_t * factoryData = nullptr; size_t factoryDataSize; CHIP_ERROR error = mFlashFactoryData.ProtectFactoryDataPartitionAgainstWrite(); // Protection against write for external storage is not supported. if (error == CHIP_ERROR_NOT_IMPLEMENTED) { ChipLogProgress(DeviceLayer, "The device does not support hardware protection against write."); error = CHIP_NO_ERROR; } else if (error != CHIP_NO_ERROR) { ChipLogError(DeviceLayer, "Failed to protect the factory data partition."); return error; } error = mFlashFactoryData.GetFactoryDataPartition(factoryData, factoryDataSize); if (error != CHIP_NO_ERROR) { ChipLogError(DeviceLayer, "Failed to read factory data partition"); return error; } if (!ParseFactoryData(factoryData, factoryDataSize, &mFactoryData)) { ChipLogError(DeviceLayer, "Failed to parse factory data"); return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; } // Check if factory data version is correct if (mFactoryData.version != CONFIG_CHIP_FACTORY_DATA_VERSION) { ChipLogError(DeviceLayer, "Factory data version mismatch. Flash version: %d vs code version: %d", mFactoryData.version, CONFIG_CHIP_FACTORY_DATA_VERSION); return CHIP_ERROR_VERSION_MISMATCH; } return CHIP_NO_ERROR; } template CHIP_ERROR FactoryDataProvider::GetCertificationDeclaration(MutableByteSpan & outBuffer) { #if CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE VerifyOrReturnError(outBuffer.size() >= mFactoryData.certificate_declaration.len, CHIP_ERROR_BUFFER_TOO_SMALL); VerifyOrReturnError(mFactoryData.certificate_declaration.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(outBuffer.data(), mFactoryData.certificate_declaration.data, mFactoryData.certificate_declaration.len); outBuffer.reduce_size(mFactoryData.certificate_declaration.len); return CHIP_NO_ERROR; #endif constexpr uint8_t kCdForAllExamples[] = CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION; return CopySpanToMutableSpan(ByteSpan{ kCdForAllExamples }, outBuffer); } template CHIP_ERROR FactoryDataProvider::GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) { out_firmware_info_buffer.reduce_size(0); return CHIP_NO_ERROR; } template CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & outBuffer) { VerifyOrReturnError(outBuffer.size() >= mFactoryData.dac_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); VerifyOrReturnError(mFactoryData.dac_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(outBuffer.data(), mFactoryData.dac_cert.data, mFactoryData.dac_cert.len); outBuffer.reduce_size(mFactoryData.dac_cert.len); return CHIP_NO_ERROR; } template CHIP_ERROR FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) { VerifyOrReturnError(outBuffer.size() >= mFactoryData.pai_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); VerifyOrReturnError(mFactoryData.pai_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(outBuffer.data(), mFactoryData.pai_cert.data, mFactoryData.pai_cert.len); outBuffer.reduce_size(mFactoryData.pai_cert.len); return CHIP_NO_ERROR; } template CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) { Crypto::P256ECDSASignature signature; Crypto::P256Keypair keypair; VerifyOrReturnError(outSignBuffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL); VerifyOrReturnError(mFactoryData.dac_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); VerifyOrReturnError(mFactoryData.dac_priv_key.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); // Extract public key from DAC cert. ByteSpan dacCertSpan{ reinterpret_cast(mFactoryData.dac_cert.data), mFactoryData.dac_cert.len }; chip::Crypto::P256PublicKey dacPublicKey; ReturnErrorOnFailure(chip::Crypto::ExtractPubkeyFromX509Cert(dacCertSpan, dacPublicKey)); ReturnErrorOnFailure( LoadKeypairFromRaw(ByteSpan(reinterpret_cast(mFactoryData.dac_priv_key.data), mFactoryData.dac_priv_key.len), ByteSpan(dacPublicKey.Bytes(), dacPublicKey.Length()), keypair)); ReturnErrorOnFailure(keypair.ECDSA_sign_msg(messageToSign.data(), messageToSign.size(), signature)); return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer); } template CHIP_ERROR FactoryDataProvider::GetSetupDiscriminator(uint16_t & setupDiscriminator) { VerifyOrReturnError(mFactoryData.discriminatorPresent, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); setupDiscriminator = mFactoryData.discriminator; return CHIP_NO_ERROR; } template CHIP_ERROR FactoryDataProvider::SetSetupDiscriminator(uint16_t setupDiscriminator) { return CHIP_ERROR_NOT_IMPLEMENTED; } template CHIP_ERROR FactoryDataProvider::GetSpake2pIterationCount(uint32_t & iterationCount) { VerifyOrReturnError(mFactoryData.spake2_it != 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); iterationCount = mFactoryData.spake2_it; return CHIP_NO_ERROR; } template CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) { VerifyOrReturnError(saltBuf.size() >= mFactoryData.spake2_salt.len, CHIP_ERROR_BUFFER_TOO_SMALL); VerifyOrReturnError(mFactoryData.spake2_salt.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(saltBuf.data(), mFactoryData.spake2_salt.data, mFactoryData.spake2_salt.len); saltBuf.reduce_size(mFactoryData.spake2_salt.len); return CHIP_NO_ERROR; } template CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) { VerifyOrReturnError(verifierBuf.size() >= mFactoryData.spake2_verifier.len, CHIP_ERROR_BUFFER_TOO_SMALL); VerifyOrReturnError(mFactoryData.spake2_verifier.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(verifierBuf.data(), mFactoryData.spake2_verifier.data, mFactoryData.spake2_verifier.len); verifierLen = mFactoryData.spake2_verifier.len; verifierBuf.reduce_size(verifierLen); return CHIP_NO_ERROR; } template CHIP_ERROR FactoryDataProvider::GetSetupPasscode(uint32_t & setupPasscode) { VerifyOrReturnError(mFactoryData.passcode != 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); setupPasscode = mFactoryData.passcode; return CHIP_NO_ERROR; } template CHIP_ERROR FactoryDataProvider::SetSetupPasscode(uint32_t setupPasscode) { return CHIP_ERROR_NOT_IMPLEMENTED; } template CHIP_ERROR FactoryDataProvider::GetVendorName(char * buf, size_t bufSize) { return GetFactoryDataString(mFactoryData.vendor_name, buf, bufSize); } template CHIP_ERROR FactoryDataProvider::GetVendorId(uint16_t & vendorId) { VerifyOrReturnError(mFactoryData.vendorIdPresent, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); vendorId = mFactoryData.vendor_id; return CHIP_NO_ERROR; } template CHIP_ERROR FactoryDataProvider::GetProductName(char * buf, size_t bufSize) { return GetFactoryDataString(mFactoryData.product_name, buf, bufSize); } template CHIP_ERROR FactoryDataProvider::GetProductId(uint16_t & productId) { VerifyOrReturnError(mFactoryData.productIdPresent, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); productId = mFactoryData.product_id; return CHIP_NO_ERROR; } template CHIP_ERROR FactoryDataProvider::GetPartNumber(char * buf, size_t bufSize) { return GetFactoryDataString(mFactoryData.part_number, buf, bufSize); } template CHIP_ERROR FactoryDataProvider::GetProductURL(char * buf, size_t bufSize) { return GetFactoryDataString(mFactoryData.product_url, buf, bufSize); } template CHIP_ERROR FactoryDataProvider::GetProductLabel(char * buf, size_t bufSize) { return GetFactoryDataString(mFactoryData.product_label, buf, bufSize); } template CHIP_ERROR FactoryDataProvider::GetSerialNumber(char * buf, size_t bufSize) { return GetFactoryDataString(mFactoryData.sn, buf, bufSize); } template CHIP_ERROR FactoryDataProvider::GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) { VerifyOrReturnError(mFactoryData.date_year != 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); year = mFactoryData.date_year; month = mFactoryData.date_month; day = mFactoryData.date_day; return CHIP_NO_ERROR; } template CHIP_ERROR FactoryDataProvider::GetHardwareVersion(uint16_t & hardwareVersion) { VerifyOrReturnError(mFactoryData.hwVerPresent, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); hardwareVersion = mFactoryData.hw_ver; return CHIP_NO_ERROR; } template CHIP_ERROR FactoryDataProvider::GetHardwareVersionString(char * buf, size_t bufSize) { return GetFactoryDataString(mFactoryData.hw_ver_str, buf, bufSize); } template CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) { VerifyOrReturnError(uniqueIdSpan.size() >= mFactoryData.rd_uid.len, CHIP_ERROR_BUFFER_TOO_SMALL); VerifyOrReturnError(mFactoryData.rd_uid.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(uniqueIdSpan.data(), mFactoryData.rd_uid.data, mFactoryData.rd_uid.len); return CHIP_NO_ERROR; } template CHIP_ERROR FactoryDataProvider::GetEnableKey(MutableByteSpan & enableKey) { VerifyOrReturnError(mFactoryData.enable_key.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); VerifyOrReturnError(enableKey.size() >= mFactoryData.enable_key.len / 2, CHIP_ERROR_BUFFER_TOO_SMALL); Encoding::HexToBytes((const char *) mFactoryData.enable_key.data, mFactoryData.enable_key.len, enableKey.data(), enableKey.size()); enableKey.reduce_size(mFactoryData.enable_key.len / 2); return CHIP_NO_ERROR; } // Fully instantiate the template class in whatever compilation unit includes this file. // template class FactoryDataProvider; template class FactoryDataProvider; } // namespace DeviceLayer } // namespace chip