Loading security/keymint/support/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -114,6 +114,7 @@ cc_library { cc_test { name: "libkeymint_remote_prov_support_test", cpp_std: "c++20", srcs: ["remote_prov_utils_test.cpp"], static_libs: [ "android.hardware.security.rkp-V3-ndk", Loading security/keymint/support/fuzzer/keymint_remote_prov_fuzzer.cpp +6 −2 Original line number Diff line number Diff line Loading @@ -74,16 +74,20 @@ void KeyMintRemoteProv::process() { uint8_t challengeSize = mFdp.ConsumeIntegralInRange<uint8_t>(kMinSize, kChallengeSize); std::vector<uint8_t> challenge = mFdp.ConsumeBytes<uint8_t>(challengeSize); RpcHardwareInfo rpcHardwareInfo; gRPC->getHardwareInfo(&rpcHardwareInfo); std::vector<uint8_t> csr; gRPC->generateCertificateRequestV2(keysToSign, challenge, &csr); while (mFdp.remaining_bytes()) { auto invokeProvAPI = mFdp.PickValueInArray<const std::function<void()>>({ [&]() { verifyFactoryCsr(cborKeysToSign, csr, gRPC.get(), kServiceName, challenge); verifyFactoryCsr(cborKeysToSign, csr, rpcHardwareInfo, kServiceName, challenge); }, [&]() { verifyProductionCsr(cborKeysToSign, csr, gRPC.get(), kServiceName, challenge); verifyProductionCsr(cborKeysToSign, csr, rpcHardwareInfo, kServiceName, challenge); }, [&]() { isCsrWithProperDiceChain(csr, kServiceName); }, }); Loading security/keymint/support/include/remote_prov/MockIRemotelyProvisionedComponent.hdeleted 100644 → 0 +0 −52 Original line number Diff line number Diff line /* * Copyright 2024 The Android Open Source Project * * 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. */ #pragma once #include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h> #include <aidl/android/hardware/security/keymint/RpcHardwareInfo.h> #include <android-base/properties.h> #include <gmock/gmock.h> #include <gtest/gtest.h> #include <cstdint> namespace aidl::android::hardware::security::keymint::remote_prov { using ::ndk::ScopedAStatus; class MockIRemotelyProvisionedComponent : public IRemotelyProvisionedComponentDefault { public: MOCK_METHOD(ScopedAStatus, getHardwareInfo, (RpcHardwareInfo * _aidl_return), (override)); MOCK_METHOD(ScopedAStatus, generateEcdsaP256KeyPair, (bool in_testMode, MacedPublicKey* out_macedPublicKey, std::vector<uint8_t>* _aidl_return), (override)); MOCK_METHOD(ScopedAStatus, generateCertificateRequest, (bool in_testMode, const std::vector<MacedPublicKey>& in_keysToSign, const std::vector<uint8_t>& in_endpointEncryptionCertChain, const std::vector<uint8_t>& in_challenge, DeviceInfo* out_deviceInfo, ProtectedData* out_protectedData, std::vector<uint8_t>* _aidl_return), (override)); MOCK_METHOD(ScopedAStatus, generateCertificateRequestV2, (const std::vector<MacedPublicKey>& in_keysToSign, const std::vector<uint8_t>& in_challenge, std::vector<uint8_t>* _aidl_return), (override)); MOCK_METHOD(ScopedAStatus, getInterfaceVersion, (int32_t* _aidl_return), (override)); MOCK_METHOD(ScopedAStatus, getInterfaceHash, (std::string * _aidl_return), (override)); }; } // namespace aidl::android::hardware::security::keymint::remote_prov No newline at end of file security/keymint/support/include/remote_prov/remote_prov_utils.h +20 −17 Original line number Diff line number Diff line Loading @@ -153,7 +153,7 @@ JsonOutput jsonEncodeCsrWithBuild(const std::string& instance_name, const cppbor * is parsed in the manufacturing process. */ ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateFactoryDeviceInfo( const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable); const std::vector<uint8_t>& deviceInfoBytes, const RpcHardwareInfo& info); /** * Parses a DeviceInfo structure from the given CBOR data. The parsed data is then validated to Loading @@ -162,7 +162,7 @@ ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateFactoryDeviceInfo( * suitable for the end user. */ ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateProductionDeviceInfo( const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable); const std::vector<uint8_t>& deviceInfoBytes, const RpcHardwareInfo& info); /** * Verify the protected data as if the device is still early in the factory process and may not Loading @@ -171,36 +171,39 @@ ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateProductionDeviceInfo( ErrMsgOr<std::vector<BccEntryData>> verifyFactoryProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const std::vector<uint8_t>& challenge); const EekChain& eekChain, const std::vector<uint8_t>& eekId, const RpcHardwareInfo& info, const std::string& instanceName, const std::vector<uint8_t>& challenge); /** * Verify the protected data as if the device is a final production sample. */ ErrMsgOr<std::vector<BccEntryData>> verifyProductionProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowAnyMode = false); const EekChain& eekChain, const std::vector<uint8_t>& eekId, const RpcHardwareInfo& info, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowAnyMode = false); /** * Verify the CSR as if the device is still early in the factory process and may not * have all device identifiers provisioned yet. */ ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr( const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowDegenerate = true, ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr(const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, const RpcHardwareInfo& info, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowDegenerate = true, bool requireUdsCerts = false); /** * Verify the CSR as if the device is a final production sample. */ ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr( const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowAnyMode = false); ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr(const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, const RpcHardwareInfo& info, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowAnyMode = false); /** Checks whether the CSR has a proper DICE chain. */ ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& csr, Loading security/keymint/support/remote_prov_utils.cpp +38 −38 Original line number Diff line number Diff line Loading @@ -483,7 +483,7 @@ bool isTeeDeviceInfo(const cppbor::Map& devInfo) { } ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateDeviceInfo( const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& deviceInfoBytes, const RpcHardwareInfo& rpcHardwareInfo, bool isFactory) { const cppbor::Array kValidVbStates = {"green", "yellow", "orange"}; const cppbor::Array kValidBootloaderStates = {"locked", "unlocked"}; Loading Loading @@ -530,9 +530,7 @@ ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateDeviceInfo( return "DeviceInfo ordering is non-canonical."; } RpcHardwareInfo info; provisionable->getHardwareInfo(&info); if (info.versionNumber < 3) { if (rpcHardwareInfo.versionNumber < 3) { const std::unique_ptr<cppbor::Item>& version = parsed->get("version"); if (!version) { return "Device info is missing version"; Loading @@ -540,10 +538,10 @@ ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateDeviceInfo( if (!version->asUint()) { return "version must be an unsigned integer"; } if (version->asUint()->value() != info.versionNumber) { if (version->asUint()->value() != rpcHardwareInfo.versionNumber) { return "DeviceInfo version (" + std::to_string(version->asUint()->value()) + ") does not match the remotely provisioned component version (" + std::to_string(info.versionNumber) + ")."; std::to_string(rpcHardwareInfo.versionNumber) + ")."; } } // Bypasses the device info validation since the device info in AVF is currently Loading @@ -552,14 +550,14 @@ ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateDeviceInfo( // TODO(b/300911665): This check is temporary and will be replaced once the markers // on the DICE chain become available. We need to determine if the CSR is from the // RKP VM using the markers on the DICE chain. if (info.uniqueId == "AVF Remote Provisioning 1") { if (rpcHardwareInfo.uniqueId == "AVF Remote Provisioning 1") { return std::move(parsed); } std::string error; std::string tmp; std::set<std::string_view> previousKeys; switch (info.versionNumber) { switch (rpcHardwareInfo.versionNumber) { case 3: if (isTeeDeviceInfo(*parsed) && parsed->size() != kNumTeeDeviceInfoEntries) { error += fmt::format( Loading Loading @@ -626,7 +624,7 @@ ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateDeviceInfo( kValidAttIdStates); break; default: return "Unrecognized version: " + std::to_string(info.versionNumber); return "Unrecognized version: " + std::to_string(rpcHardwareInfo.versionNumber); } if (!error.empty()) { Loading @@ -637,13 +635,13 @@ ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateDeviceInfo( } ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateFactoryDeviceInfo( const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable) { return parseAndValidateDeviceInfo(deviceInfoBytes, provisionable, /*isFactory=*/true); const std::vector<uint8_t>& deviceInfoBytes, const RpcHardwareInfo& rpcHardwareInfo) { return parseAndValidateDeviceInfo(deviceInfoBytes, rpcHardwareInfo, /*isFactory=*/true); } ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateProductionDeviceInfo( const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable) { return parseAndValidateDeviceInfo(deviceInfoBytes, provisionable, /*isFactory=*/false); const std::vector<uint8_t>& deviceInfoBytes, const RpcHardwareInfo& rpcHardwareInfo) { return parseAndValidateDeviceInfo(deviceInfoBytes, rpcHardwareInfo, /*isFactory=*/false); } ErrMsgOr<bytevec> getSessionKey(ErrMsgOr<std::pair<bytevec, bytevec>>& senderPubkey, Loading @@ -661,8 +659,8 @@ ErrMsgOr<bytevec> getSessionKey(ErrMsgOr<std::pair<bytevec, bytevec>>& senderPub ErrMsgOr<std::vector<BccEntryData>> verifyProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const EekChain& eekChain, const std::vector<uint8_t>& eekId, const RpcHardwareInfo& rpcHardwareInfo, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool isFactory, bool allowAnyMode = false) { auto [parsedProtectedData, _, protDataErrMsg] = cppbor::parse(protectedData.protectedData); if (!parsedProtectedData) { Loading @@ -685,7 +683,7 @@ ErrMsgOr<std::vector<BccEntryData>> verifyProtectedData( return "The COSE_encrypt recipient does not match the expected EEK identifier"; } auto sessionKey = getSessionKey(senderPubkey, eekChain, supportedEekCurve); auto sessionKey = getSessionKey(senderPubkey, eekChain, rpcHardwareInfo.supportedEekCurve); if (!sessionKey) { return sessionKey.message(); } Loading Loading @@ -726,7 +724,7 @@ ErrMsgOr<std::vector<BccEntryData>> verifyProtectedData( } auto deviceInfoResult = parseAndValidateDeviceInfo(deviceInfo.deviceInfo, provisionable, isFactory); parseAndValidateDeviceInfo(deviceInfo.deviceInfo, rpcHardwareInfo, isFactory); if (!deviceInfoResult) { return deviceInfoResult.message(); } Loading Loading @@ -762,22 +760,22 @@ ErrMsgOr<std::vector<BccEntryData>> verifyProtectedData( ErrMsgOr<std::vector<BccEntryData>> verifyFactoryProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const EekChain& eekChain, const std::vector<uint8_t>& eekId, const RpcHardwareInfo& rpcHardwareInfo, const std::string& instanceName, const std::vector<uint8_t>& challenge) { return verifyProtectedData(deviceInfo, keysToSign, keysToSignMac, protectedData, eekChain, eekId, supportedEekCurve, provisionable, instanceName, challenge, eekId, rpcHardwareInfo, instanceName, challenge, /*isFactory=*/true); } ErrMsgOr<std::vector<BccEntryData>> verifyProductionProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const EekChain& eekChain, const std::vector<uint8_t>& eekId, const RpcHardwareInfo& rpcHardwareInfo, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowAnyMode) { return verifyProtectedData(deviceInfo, keysToSign, keysToSignMac, protectedData, eekChain, eekId, supportedEekCurve, provisionable, instanceName, challenge, eekId, rpcHardwareInfo, instanceName, challenge, /*isFactory=*/false, allowAnyMode); } Loading Loading @@ -912,7 +910,7 @@ std::optional<std::string> validateUdsCerts(const cppbor::Map& udsCerts, ErrMsgOr<std::unique_ptr<cppbor::Array>> parseAndValidateCsrPayload( const cppbor::Array& keysToSign, const std::vector<uint8_t>& csrPayload, IRemotelyProvisionedComponent* provisionable, bool isFactory) { const RpcHardwareInfo& rpcHardwareInfo, bool isFactory) { auto [parsedCsrPayload, _, errMsg] = cppbor::parse(csrPayload); if (!parsedCsrPayload) { return errMsg; Loading Loading @@ -949,7 +947,8 @@ ErrMsgOr<std::unique_ptr<cppbor::Array>> parseAndValidateCsrPayload( return "Keys must be an Array."; } auto result = parseAndValidateDeviceInfo(signedDeviceInfo->encode(), provisionable, isFactory); auto result = parseAndValidateDeviceInfo(signedDeviceInfo->encode(), rpcHardwareInfo, isFactory); if (!result) { return result.message(); } Loading Loading @@ -1100,13 +1099,12 @@ ErrMsgOr<bytevec> parseAndValidateAuthenticatedRequest(const std::vector<uint8_t ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyCsr( const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const RpcHardwareInfo& rpcHardwareInfo, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool isFactory, bool allowAnyMode = false, bool allowDegenerate = true, bool requireUdsCerts = false) { RpcHardwareInfo info; provisionable->getHardwareInfo(&info); if (info.versionNumber != 3) { return "Remotely provisioned component version (" + std::to_string(info.versionNumber) + if (rpcHardwareInfo.versionNumber != 3) { return "Remotely provisioned component version (" + std::to_string(rpcHardwareInfo.versionNumber) + ") does not match expected version (3)."; } Loading @@ -1117,22 +1115,24 @@ ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyCsr( return csrPayload.message(); } return parseAndValidateCsrPayload(keysToSign, *csrPayload, provisionable, isFactory); return parseAndValidateCsrPayload(keysToSign, *csrPayload, rpcHardwareInfo, isFactory); } ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr( const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const RpcHardwareInfo& rpcHardwareInfo, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowDegenerate, bool requireUdsCerts) { return verifyCsr(keysToSign, csr, provisionable, instanceName, challenge, /*isFactory=*/true, return verifyCsr(keysToSign, csr, rpcHardwareInfo, instanceName, challenge, /*isFactory=*/true, /*allowAnyMode=*/false, allowDegenerate, requireUdsCerts); } ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr( const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowAnyMode) { return verifyCsr(keysToSign, csr, provisionable, instanceName, challenge, /*isFactory=*/false, ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr(const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, const RpcHardwareInfo& rpcHardwareInfo, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowAnyMode) { return verifyCsr(keysToSign, csr, rpcHardwareInfo, instanceName, challenge, /*isFactory=*/false, allowAnyMode); } Loading Loading
security/keymint/support/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -114,6 +114,7 @@ cc_library { cc_test { name: "libkeymint_remote_prov_support_test", cpp_std: "c++20", srcs: ["remote_prov_utils_test.cpp"], static_libs: [ "android.hardware.security.rkp-V3-ndk", Loading
security/keymint/support/fuzzer/keymint_remote_prov_fuzzer.cpp +6 −2 Original line number Diff line number Diff line Loading @@ -74,16 +74,20 @@ void KeyMintRemoteProv::process() { uint8_t challengeSize = mFdp.ConsumeIntegralInRange<uint8_t>(kMinSize, kChallengeSize); std::vector<uint8_t> challenge = mFdp.ConsumeBytes<uint8_t>(challengeSize); RpcHardwareInfo rpcHardwareInfo; gRPC->getHardwareInfo(&rpcHardwareInfo); std::vector<uint8_t> csr; gRPC->generateCertificateRequestV2(keysToSign, challenge, &csr); while (mFdp.remaining_bytes()) { auto invokeProvAPI = mFdp.PickValueInArray<const std::function<void()>>({ [&]() { verifyFactoryCsr(cborKeysToSign, csr, gRPC.get(), kServiceName, challenge); verifyFactoryCsr(cborKeysToSign, csr, rpcHardwareInfo, kServiceName, challenge); }, [&]() { verifyProductionCsr(cborKeysToSign, csr, gRPC.get(), kServiceName, challenge); verifyProductionCsr(cborKeysToSign, csr, rpcHardwareInfo, kServiceName, challenge); }, [&]() { isCsrWithProperDiceChain(csr, kServiceName); }, }); Loading
security/keymint/support/include/remote_prov/MockIRemotelyProvisionedComponent.hdeleted 100644 → 0 +0 −52 Original line number Diff line number Diff line /* * Copyright 2024 The Android Open Source Project * * 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. */ #pragma once #include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h> #include <aidl/android/hardware/security/keymint/RpcHardwareInfo.h> #include <android-base/properties.h> #include <gmock/gmock.h> #include <gtest/gtest.h> #include <cstdint> namespace aidl::android::hardware::security::keymint::remote_prov { using ::ndk::ScopedAStatus; class MockIRemotelyProvisionedComponent : public IRemotelyProvisionedComponentDefault { public: MOCK_METHOD(ScopedAStatus, getHardwareInfo, (RpcHardwareInfo * _aidl_return), (override)); MOCK_METHOD(ScopedAStatus, generateEcdsaP256KeyPair, (bool in_testMode, MacedPublicKey* out_macedPublicKey, std::vector<uint8_t>* _aidl_return), (override)); MOCK_METHOD(ScopedAStatus, generateCertificateRequest, (bool in_testMode, const std::vector<MacedPublicKey>& in_keysToSign, const std::vector<uint8_t>& in_endpointEncryptionCertChain, const std::vector<uint8_t>& in_challenge, DeviceInfo* out_deviceInfo, ProtectedData* out_protectedData, std::vector<uint8_t>* _aidl_return), (override)); MOCK_METHOD(ScopedAStatus, generateCertificateRequestV2, (const std::vector<MacedPublicKey>& in_keysToSign, const std::vector<uint8_t>& in_challenge, std::vector<uint8_t>* _aidl_return), (override)); MOCK_METHOD(ScopedAStatus, getInterfaceVersion, (int32_t* _aidl_return), (override)); MOCK_METHOD(ScopedAStatus, getInterfaceHash, (std::string * _aidl_return), (override)); }; } // namespace aidl::android::hardware::security::keymint::remote_prov No newline at end of file
security/keymint/support/include/remote_prov/remote_prov_utils.h +20 −17 Original line number Diff line number Diff line Loading @@ -153,7 +153,7 @@ JsonOutput jsonEncodeCsrWithBuild(const std::string& instance_name, const cppbor * is parsed in the manufacturing process. */ ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateFactoryDeviceInfo( const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable); const std::vector<uint8_t>& deviceInfoBytes, const RpcHardwareInfo& info); /** * Parses a DeviceInfo structure from the given CBOR data. The parsed data is then validated to Loading @@ -162,7 +162,7 @@ ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateFactoryDeviceInfo( * suitable for the end user. */ ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateProductionDeviceInfo( const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable); const std::vector<uint8_t>& deviceInfoBytes, const RpcHardwareInfo& info); /** * Verify the protected data as if the device is still early in the factory process and may not Loading @@ -171,36 +171,39 @@ ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateProductionDeviceInfo( ErrMsgOr<std::vector<BccEntryData>> verifyFactoryProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const std::vector<uint8_t>& challenge); const EekChain& eekChain, const std::vector<uint8_t>& eekId, const RpcHardwareInfo& info, const std::string& instanceName, const std::vector<uint8_t>& challenge); /** * Verify the protected data as if the device is a final production sample. */ ErrMsgOr<std::vector<BccEntryData>> verifyProductionProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowAnyMode = false); const EekChain& eekChain, const std::vector<uint8_t>& eekId, const RpcHardwareInfo& info, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowAnyMode = false); /** * Verify the CSR as if the device is still early in the factory process and may not * have all device identifiers provisioned yet. */ ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr( const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowDegenerate = true, ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr(const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, const RpcHardwareInfo& info, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowDegenerate = true, bool requireUdsCerts = false); /** * Verify the CSR as if the device is a final production sample. */ ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr( const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowAnyMode = false); ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr(const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, const RpcHardwareInfo& info, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowAnyMode = false); /** Checks whether the CSR has a proper DICE chain. */ ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& csr, Loading
security/keymint/support/remote_prov_utils.cpp +38 −38 Original line number Diff line number Diff line Loading @@ -483,7 +483,7 @@ bool isTeeDeviceInfo(const cppbor::Map& devInfo) { } ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateDeviceInfo( const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& deviceInfoBytes, const RpcHardwareInfo& rpcHardwareInfo, bool isFactory) { const cppbor::Array kValidVbStates = {"green", "yellow", "orange"}; const cppbor::Array kValidBootloaderStates = {"locked", "unlocked"}; Loading Loading @@ -530,9 +530,7 @@ ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateDeviceInfo( return "DeviceInfo ordering is non-canonical."; } RpcHardwareInfo info; provisionable->getHardwareInfo(&info); if (info.versionNumber < 3) { if (rpcHardwareInfo.versionNumber < 3) { const std::unique_ptr<cppbor::Item>& version = parsed->get("version"); if (!version) { return "Device info is missing version"; Loading @@ -540,10 +538,10 @@ ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateDeviceInfo( if (!version->asUint()) { return "version must be an unsigned integer"; } if (version->asUint()->value() != info.versionNumber) { if (version->asUint()->value() != rpcHardwareInfo.versionNumber) { return "DeviceInfo version (" + std::to_string(version->asUint()->value()) + ") does not match the remotely provisioned component version (" + std::to_string(info.versionNumber) + ")."; std::to_string(rpcHardwareInfo.versionNumber) + ")."; } } // Bypasses the device info validation since the device info in AVF is currently Loading @@ -552,14 +550,14 @@ ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateDeviceInfo( // TODO(b/300911665): This check is temporary and will be replaced once the markers // on the DICE chain become available. We need to determine if the CSR is from the // RKP VM using the markers on the DICE chain. if (info.uniqueId == "AVF Remote Provisioning 1") { if (rpcHardwareInfo.uniqueId == "AVF Remote Provisioning 1") { return std::move(parsed); } std::string error; std::string tmp; std::set<std::string_view> previousKeys; switch (info.versionNumber) { switch (rpcHardwareInfo.versionNumber) { case 3: if (isTeeDeviceInfo(*parsed) && parsed->size() != kNumTeeDeviceInfoEntries) { error += fmt::format( Loading Loading @@ -626,7 +624,7 @@ ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateDeviceInfo( kValidAttIdStates); break; default: return "Unrecognized version: " + std::to_string(info.versionNumber); return "Unrecognized version: " + std::to_string(rpcHardwareInfo.versionNumber); } if (!error.empty()) { Loading @@ -637,13 +635,13 @@ ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateDeviceInfo( } ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateFactoryDeviceInfo( const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable) { return parseAndValidateDeviceInfo(deviceInfoBytes, provisionable, /*isFactory=*/true); const std::vector<uint8_t>& deviceInfoBytes, const RpcHardwareInfo& rpcHardwareInfo) { return parseAndValidateDeviceInfo(deviceInfoBytes, rpcHardwareInfo, /*isFactory=*/true); } ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateProductionDeviceInfo( const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable) { return parseAndValidateDeviceInfo(deviceInfoBytes, provisionable, /*isFactory=*/false); const std::vector<uint8_t>& deviceInfoBytes, const RpcHardwareInfo& rpcHardwareInfo) { return parseAndValidateDeviceInfo(deviceInfoBytes, rpcHardwareInfo, /*isFactory=*/false); } ErrMsgOr<bytevec> getSessionKey(ErrMsgOr<std::pair<bytevec, bytevec>>& senderPubkey, Loading @@ -661,8 +659,8 @@ ErrMsgOr<bytevec> getSessionKey(ErrMsgOr<std::pair<bytevec, bytevec>>& senderPub ErrMsgOr<std::vector<BccEntryData>> verifyProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const EekChain& eekChain, const std::vector<uint8_t>& eekId, const RpcHardwareInfo& rpcHardwareInfo, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool isFactory, bool allowAnyMode = false) { auto [parsedProtectedData, _, protDataErrMsg] = cppbor::parse(protectedData.protectedData); if (!parsedProtectedData) { Loading @@ -685,7 +683,7 @@ ErrMsgOr<std::vector<BccEntryData>> verifyProtectedData( return "The COSE_encrypt recipient does not match the expected EEK identifier"; } auto sessionKey = getSessionKey(senderPubkey, eekChain, supportedEekCurve); auto sessionKey = getSessionKey(senderPubkey, eekChain, rpcHardwareInfo.supportedEekCurve); if (!sessionKey) { return sessionKey.message(); } Loading Loading @@ -726,7 +724,7 @@ ErrMsgOr<std::vector<BccEntryData>> verifyProtectedData( } auto deviceInfoResult = parseAndValidateDeviceInfo(deviceInfo.deviceInfo, provisionable, isFactory); parseAndValidateDeviceInfo(deviceInfo.deviceInfo, rpcHardwareInfo, isFactory); if (!deviceInfoResult) { return deviceInfoResult.message(); } Loading Loading @@ -762,22 +760,22 @@ ErrMsgOr<std::vector<BccEntryData>> verifyProtectedData( ErrMsgOr<std::vector<BccEntryData>> verifyFactoryProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const EekChain& eekChain, const std::vector<uint8_t>& eekId, const RpcHardwareInfo& rpcHardwareInfo, const std::string& instanceName, const std::vector<uint8_t>& challenge) { return verifyProtectedData(deviceInfo, keysToSign, keysToSignMac, protectedData, eekChain, eekId, supportedEekCurve, provisionable, instanceName, challenge, eekId, rpcHardwareInfo, instanceName, challenge, /*isFactory=*/true); } ErrMsgOr<std::vector<BccEntryData>> verifyProductionProtectedData( const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData, const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const EekChain& eekChain, const std::vector<uint8_t>& eekId, const RpcHardwareInfo& rpcHardwareInfo, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowAnyMode) { return verifyProtectedData(deviceInfo, keysToSign, keysToSignMac, protectedData, eekChain, eekId, supportedEekCurve, provisionable, instanceName, challenge, eekId, rpcHardwareInfo, instanceName, challenge, /*isFactory=*/false, allowAnyMode); } Loading Loading @@ -912,7 +910,7 @@ std::optional<std::string> validateUdsCerts(const cppbor::Map& udsCerts, ErrMsgOr<std::unique_ptr<cppbor::Array>> parseAndValidateCsrPayload( const cppbor::Array& keysToSign, const std::vector<uint8_t>& csrPayload, IRemotelyProvisionedComponent* provisionable, bool isFactory) { const RpcHardwareInfo& rpcHardwareInfo, bool isFactory) { auto [parsedCsrPayload, _, errMsg] = cppbor::parse(csrPayload); if (!parsedCsrPayload) { return errMsg; Loading Loading @@ -949,7 +947,8 @@ ErrMsgOr<std::unique_ptr<cppbor::Array>> parseAndValidateCsrPayload( return "Keys must be an Array."; } auto result = parseAndValidateDeviceInfo(signedDeviceInfo->encode(), provisionable, isFactory); auto result = parseAndValidateDeviceInfo(signedDeviceInfo->encode(), rpcHardwareInfo, isFactory); if (!result) { return result.message(); } Loading Loading @@ -1100,13 +1099,12 @@ ErrMsgOr<bytevec> parseAndValidateAuthenticatedRequest(const std::vector<uint8_t ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyCsr( const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const RpcHardwareInfo& rpcHardwareInfo, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool isFactory, bool allowAnyMode = false, bool allowDegenerate = true, bool requireUdsCerts = false) { RpcHardwareInfo info; provisionable->getHardwareInfo(&info); if (info.versionNumber != 3) { return "Remotely provisioned component version (" + std::to_string(info.versionNumber) + if (rpcHardwareInfo.versionNumber != 3) { return "Remotely provisioned component version (" + std::to_string(rpcHardwareInfo.versionNumber) + ") does not match expected version (3)."; } Loading @@ -1117,22 +1115,24 @@ ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyCsr( return csrPayload.message(); } return parseAndValidateCsrPayload(keysToSign, *csrPayload, provisionable, isFactory); return parseAndValidateCsrPayload(keysToSign, *csrPayload, rpcHardwareInfo, isFactory); } ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr( const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const RpcHardwareInfo& rpcHardwareInfo, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowDegenerate, bool requireUdsCerts) { return verifyCsr(keysToSign, csr, provisionable, instanceName, challenge, /*isFactory=*/true, return verifyCsr(keysToSign, csr, rpcHardwareInfo, instanceName, challenge, /*isFactory=*/true, /*allowAnyMode=*/false, allowDegenerate, requireUdsCerts); } ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr( const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, IRemotelyProvisionedComponent* provisionable, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowAnyMode) { return verifyCsr(keysToSign, csr, provisionable, instanceName, challenge, /*isFactory=*/false, ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr(const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr, const RpcHardwareInfo& rpcHardwareInfo, const std::string& instanceName, const std::vector<uint8_t>& challenge, bool allowAnyMode) { return verifyCsr(keysToSign, csr, rpcHardwareInfo, instanceName, challenge, /*isFactory=*/false, allowAnyMode); } Loading