/* * * 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 "CHIPDevicePlatformConfig.h" #include #ifdef 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, static_cast(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) { #ifdef CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE size_t cdLen = 0; if (Internal::ZephyrConfig::ReadConfigValueBin(Internal::ZephyrConfig::kConfigKey_CertificationDeclaration, reinterpret_cast(outBuffer.data()), outBuffer.size(), cdLen) == CHIP_NO_ERROR) { outBuffer.reduce_size(cdLen); 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; CHIP_ERROR err = CHIP_NO_ERROR; #ifdef CONFIG_CHIP_CRYPTO_PSA psa_key_id_t keyId = 0; #endif VerifyOrExit(outSignBuffer.size() >= signature.Capacity(), err = CHIP_ERROR_BUFFER_TOO_SMALL); VerifyOrExit(mFactoryData.dac_cert.data, err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); VerifyOrExit(mFactoryData.dac_priv_key.data, err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); #ifdef CONFIG_CHIP_CRYPTO_PSA { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_reset_key_attributes(&attributes); psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); psa_set_key_bits(&attributes, kDACPrivateKeyLength * 8); psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE); VerifyOrExit(psa_import_key(&attributes, reinterpret_cast(mFactoryData.dac_priv_key.data), kDACPrivateKeyLength, &keyId) == PSA_SUCCESS, err = CHIP_ERROR_INTERNAL); size_t outputLen = 0; psa_status_t status = psa_sign_message(keyId, PSA_ALG_ECDSA(PSA_ALG_SHA_256), messageToSign.data(), messageToSign.size(), signature.Bytes(), signature.Capacity(), &outputLen); VerifyOrExit(!status, err = CHIP_ERROR_INTERNAL); VerifyOrExit(outputLen == chip::Crypto::kP256_ECDSA_Signature_Length_Raw, err = CHIP_ERROR_INTERNAL); err = signature.SetLength(outputLen); VerifyOrExit(err == CHIP_NO_ERROR, ); } #else { // Extract public key from DAC cert. ByteSpan dacCertSpan{ reinterpret_cast(mFactoryData.dac_cert.data), mFactoryData.dac_cert.len }; chip::Crypto::P256PublicKey dacPublicKey; err = chip::Crypto::ExtractPubkeyFromX509Cert(dacCertSpan, dacPublicKey); VerifyOrExit(err == CHIP_NO_ERROR, ); err = LoadKeypairFromRaw(ByteSpan(reinterpret_cast(mFactoryData.dac_priv_key.data), mFactoryData.dac_priv_key.len), ByteSpan(dacPublicKey.Bytes(), dacPublicKey.Length()), keypair); VerifyOrExit(err == CHIP_NO_ERROR, ); err = keypair.ECDSA_sign_msg(messageToSign.data(), messageToSign.size(), signature); VerifyOrExit(err == CHIP_NO_ERROR, ); } #endif exit: #ifdef CONFIG_CHIP_CRYPTO_PSA psa_destroy_key(keyId); #endif if (err != CHIP_NO_ERROR) { return err; } 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); uniqueIdSpan.reduce_size(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, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(enableKey.data(), mFactoryData.enable_key.data, mFactoryData.enable_key.len); enableKey.reduce_size(mFactoryData.enable_key.len); return CHIP_NO_ERROR; } template CHIP_ERROR FactoryDataProvider::GetProductFinish(app::Clusters::BasicInformation::ProductFinishEnum * finish) { VerifyOrReturnError(finish, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(mFactoryData.productFinishPresent, CHIP_ERROR_NOT_IMPLEMENTED); *finish = static_cast(mFactoryData.product_finish); return CHIP_NO_ERROR; } template CHIP_ERROR FactoryDataProvider::GetProductPrimaryColor(app::Clusters::BasicInformation::ColorEnum * primaryColor) { VerifyOrReturnError(primaryColor, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(mFactoryData.primaryColorPresent, CHIP_ERROR_NOT_IMPLEMENTED); *primaryColor = static_cast(mFactoryData.primary_color); return CHIP_NO_ERROR; } template CHIP_ERROR FactoryDataProvider::GetUserData(MutableByteSpan & userData) { VerifyOrReturnError(mFactoryData.user.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); VerifyOrReturnError(userData.size() >= mFactoryData.user.len, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(userData.data(), mFactoryData.user.data, mFactoryData.user.len); userData.reduce_size(mFactoryData.user.len); return CHIP_NO_ERROR; } template CHIP_ERROR FactoryDataProvider::GetUserKey(const char * userKey, void * buf, size_t & len) { VerifyOrReturnError(mFactoryData.user.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); VerifyOrReturnError(buf, CHIP_ERROR_BUFFER_TOO_SMALL); bool success = FindUserDataEntry(&mFactoryData, userKey, buf, len, &len); VerifyOrReturnError(success, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); return CHIP_NO_ERROR; } // Fully instantiate the template class in whatever compilation unit includes this file. template class FactoryDataProvider; #if defined(USE_PARTITION_MANAGER) && USE_PARTITION_MANAGER == 1 && (defined(CONFIG_CHIP_QSPI_NOR) || defined(CONFIG_CHIP_SPI_NOR)) template class FactoryDataProvider; #endif // if defined(USE_PARTITION_MANAGER) && USE_PARTITION_MANAGER == 1 (defined(CONFIG_CHIP_QSPI_NOR) || // defined(CONFIG_CHIP_SPI_NOR)) } // namespace DeviceLayer } // namespace chip