Loading security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl +16 −20 Original line number Diff line number Diff line Loading @@ -30,26 +30,22 @@ parcelable DeviceInfo { * DeviceInfo is a CBOR Map structure described by the following CDDL. * * DeviceInfo = { * ? "brand" : tstr, * ? "manufacturer" : tstr, * ? "product" : tstr, * ? "model" : tstr, * ? "board" : tstr, * ? "vb_state" : "green" / "yellow" / "orange", // Taken from the AVB values * ? "bootloader_state" : "locked" / "unlocked", // Taken from the AVB values * ? "vbmeta_digest": bstr, // Taken from the AVB values * ? "os_version" : tstr, // Same as android.os.Build.VERSION.release * ? "system_patch_level" : uint, // YYYYMMDD * ? "boot_patch_level" : uint, // YYYYMMDD * ? "vendor_patch_level" : uint, // YYYYMMDD * "version" : 1, // The CDDL schema version. * "security_level" : "tee" / "strongbox" * "att_id_state": "locked" / "open", // Attestation IDs State. If "locked", this * // indicates a device's attestable IDs are * // factory-locked and immutable. If "open", * // this indicates the device is still in a * // provisionable state and the attestable IDs * // are not yet frozen. * "brand" : tstr, * "manufacturer" : tstr, * "product" : tstr, * "model" : tstr, * "device" : tstr, * "vb_state" : "green" / "yellow" / "orange", // Taken from the AVB values * "bootloader_state" : "locked" / "unlocked", // Taken from the AVB values * "vbmeta_digest": bstr, // Taken from the AVB values * "os_version" : tstr, // Same as android.os.Build.VERSION.release * "system_patch_level" : uint, // YYYYMMDD * "boot_patch_level" : uint, // YYYYMMDD * "vendor_patch_level" : uint, // YYYYMMDD * "version" : 2, // The CDDL schema version. * "security_level" : "tee" / "strongbox", * "fused": 1 / 0, // 1 if secure boot is enforced for the processor that the IRPC * // implementation is contained in. 0 otherwise. * } */ byte[] deviceInfo; Loading security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp +88 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,22 @@ using testing::MatchesRegex; using namespace remote_prov; using namespace keymaster; std::set<std::string> getAllowedVbStates() { return {"green", "yellow", "orange"}; } std::set<std::string> getAllowedBootloaderStates() { return {"locked", "unlocked"}; } std::set<std::string> getAllowedSecurityLevels() { return {"tee", "strongbox"}; } std::set<std::string> getAllowedAttIdStates() { return {"locked", "open"}; } bytevec string_to_bytevec(const char* s) { const uint8_t* p = reinterpret_cast<const uint8_t*>(s); return bytevec(p, p + strlen(s)); Loading Loading @@ -406,6 +422,8 @@ class CertificateRequestTest : public VtsRemotelyProvisionedComponentTests { ASSERT_TRUE(deviceInfoMap) << "Failed to parse deviceInfo: " << deviceInfoErrMsg; ASSERT_TRUE(deviceInfoMap->asMap()); checkDeviceInfo(deviceInfoMap->asMap()); auto& signingKey = bccContents->back().pubKey; auto macKey = verifyAndParseCoseSign1(signedMac->asArray(), signingKey, cppbor::Array() // SignedMacAad Loading @@ -432,6 +450,76 @@ class CertificateRequestTest : public VtsRemotelyProvisionedComponentTests { } } void checkType(const cppbor::Map* devInfo, uint8_t majorType, std::string entryName) { const auto& val = devInfo->get(entryName); ASSERT_TRUE(val) << entryName << " does not exist"; ASSERT_EQ(val->type(), majorType) << entryName << " has the wrong type."; switch (majorType) { case cppbor::TSTR: ASSERT_GT(val->asTstr()->value().size(), 0); break; case cppbor::BSTR: ASSERT_GT(val->asBstr()->value().size(), 0); break; default: break; } } void checkDeviceInfo(const cppbor::Map* deviceInfo) { const auto& version = deviceInfo->get("version"); ASSERT_TRUE(version); ASSERT_TRUE(version->asUint()); RpcHardwareInfo info; provisionable_->getHardwareInfo(&info); ASSERT_EQ(version->asUint()->value(), info.versionNumber); std::set<std::string> allowList; switch (version->asUint()->value()) { // These fields became mandated in version 2. case 2: checkType(deviceInfo, cppbor::TSTR, "brand"); checkType(deviceInfo, cppbor::TSTR, "manufacturer"); checkType(deviceInfo, cppbor::TSTR, "product"); checkType(deviceInfo, cppbor::TSTR, "model"); checkType(deviceInfo, cppbor::TSTR, "device"); // TODO: Refactor the KeyMint code that validates these fields and include it here. checkType(deviceInfo, cppbor::TSTR, "vb_state"); allowList = getAllowedVbStates(); ASSERT_NE(allowList.find(deviceInfo->get("vb_state")->asTstr()->value()), allowList.end()); checkType(deviceInfo, cppbor::TSTR, "bootloader_state"); allowList = getAllowedBootloaderStates(); ASSERT_NE(allowList.find(deviceInfo->get("bootloader_state")->asTstr()->value()), allowList.end()); checkType(deviceInfo, cppbor::BSTR, "vbmeta_digest"); checkType(deviceInfo, cppbor::TSTR, "os_version"); checkType(deviceInfo, cppbor::UINT, "system_patch_level"); checkType(deviceInfo, cppbor::UINT, "boot_patch_level"); checkType(deviceInfo, cppbor::UINT, "vendor_patch_level"); checkType(deviceInfo, cppbor::UINT, "fused"); ASSERT_LT(deviceInfo->get("fused")->asUint()->value(), 2); // Must be 0 or 1. checkType(deviceInfo, cppbor::TSTR, "security_level"); allowList = getAllowedSecurityLevels(); ASSERT_NE(allowList.find(deviceInfo->get("security_level")->asTstr()->value()), allowList.end()); break; case 1: checkType(deviceInfo, cppbor::TSTR, "security_level"); allowList = getAllowedSecurityLevels(); ASSERT_NE(allowList.find(deviceInfo->get("security_level")->asTstr()->value()), allowList.end()); if (version->asUint()->value() == 1) { checkType(deviceInfo, cppbor::TSTR, "att_id_state"); allowList = getAllowedAttIdStates(); ASSERT_NE(allowList.find(deviceInfo->get("att_id_state")->asTstr()->value()), allowList.end()); } break; default: FAIL() << "Unrecognized version: " << version->asUint()->value(); } } bytevec eekId_; size_t testEekLength_; EekChain testEekChain_; Loading Loading
security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl +16 −20 Original line number Diff line number Diff line Loading @@ -30,26 +30,22 @@ parcelable DeviceInfo { * DeviceInfo is a CBOR Map structure described by the following CDDL. * * DeviceInfo = { * ? "brand" : tstr, * ? "manufacturer" : tstr, * ? "product" : tstr, * ? "model" : tstr, * ? "board" : tstr, * ? "vb_state" : "green" / "yellow" / "orange", // Taken from the AVB values * ? "bootloader_state" : "locked" / "unlocked", // Taken from the AVB values * ? "vbmeta_digest": bstr, // Taken from the AVB values * ? "os_version" : tstr, // Same as android.os.Build.VERSION.release * ? "system_patch_level" : uint, // YYYYMMDD * ? "boot_patch_level" : uint, // YYYYMMDD * ? "vendor_patch_level" : uint, // YYYYMMDD * "version" : 1, // The CDDL schema version. * "security_level" : "tee" / "strongbox" * "att_id_state": "locked" / "open", // Attestation IDs State. If "locked", this * // indicates a device's attestable IDs are * // factory-locked and immutable. If "open", * // this indicates the device is still in a * // provisionable state and the attestable IDs * // are not yet frozen. * "brand" : tstr, * "manufacturer" : tstr, * "product" : tstr, * "model" : tstr, * "device" : tstr, * "vb_state" : "green" / "yellow" / "orange", // Taken from the AVB values * "bootloader_state" : "locked" / "unlocked", // Taken from the AVB values * "vbmeta_digest": bstr, // Taken from the AVB values * "os_version" : tstr, // Same as android.os.Build.VERSION.release * "system_patch_level" : uint, // YYYYMMDD * "boot_patch_level" : uint, // YYYYMMDD * "vendor_patch_level" : uint, // YYYYMMDD * "version" : 2, // The CDDL schema version. * "security_level" : "tee" / "strongbox", * "fused": 1 / 0, // 1 if secure boot is enforced for the processor that the IRPC * // implementation is contained in. 0 otherwise. * } */ byte[] deviceInfo; Loading
security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp +88 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,22 @@ using testing::MatchesRegex; using namespace remote_prov; using namespace keymaster; std::set<std::string> getAllowedVbStates() { return {"green", "yellow", "orange"}; } std::set<std::string> getAllowedBootloaderStates() { return {"locked", "unlocked"}; } std::set<std::string> getAllowedSecurityLevels() { return {"tee", "strongbox"}; } std::set<std::string> getAllowedAttIdStates() { return {"locked", "open"}; } bytevec string_to_bytevec(const char* s) { const uint8_t* p = reinterpret_cast<const uint8_t*>(s); return bytevec(p, p + strlen(s)); Loading Loading @@ -406,6 +422,8 @@ class CertificateRequestTest : public VtsRemotelyProvisionedComponentTests { ASSERT_TRUE(deviceInfoMap) << "Failed to parse deviceInfo: " << deviceInfoErrMsg; ASSERT_TRUE(deviceInfoMap->asMap()); checkDeviceInfo(deviceInfoMap->asMap()); auto& signingKey = bccContents->back().pubKey; auto macKey = verifyAndParseCoseSign1(signedMac->asArray(), signingKey, cppbor::Array() // SignedMacAad Loading @@ -432,6 +450,76 @@ class CertificateRequestTest : public VtsRemotelyProvisionedComponentTests { } } void checkType(const cppbor::Map* devInfo, uint8_t majorType, std::string entryName) { const auto& val = devInfo->get(entryName); ASSERT_TRUE(val) << entryName << " does not exist"; ASSERT_EQ(val->type(), majorType) << entryName << " has the wrong type."; switch (majorType) { case cppbor::TSTR: ASSERT_GT(val->asTstr()->value().size(), 0); break; case cppbor::BSTR: ASSERT_GT(val->asBstr()->value().size(), 0); break; default: break; } } void checkDeviceInfo(const cppbor::Map* deviceInfo) { const auto& version = deviceInfo->get("version"); ASSERT_TRUE(version); ASSERT_TRUE(version->asUint()); RpcHardwareInfo info; provisionable_->getHardwareInfo(&info); ASSERT_EQ(version->asUint()->value(), info.versionNumber); std::set<std::string> allowList; switch (version->asUint()->value()) { // These fields became mandated in version 2. case 2: checkType(deviceInfo, cppbor::TSTR, "brand"); checkType(deviceInfo, cppbor::TSTR, "manufacturer"); checkType(deviceInfo, cppbor::TSTR, "product"); checkType(deviceInfo, cppbor::TSTR, "model"); checkType(deviceInfo, cppbor::TSTR, "device"); // TODO: Refactor the KeyMint code that validates these fields and include it here. checkType(deviceInfo, cppbor::TSTR, "vb_state"); allowList = getAllowedVbStates(); ASSERT_NE(allowList.find(deviceInfo->get("vb_state")->asTstr()->value()), allowList.end()); checkType(deviceInfo, cppbor::TSTR, "bootloader_state"); allowList = getAllowedBootloaderStates(); ASSERT_NE(allowList.find(deviceInfo->get("bootloader_state")->asTstr()->value()), allowList.end()); checkType(deviceInfo, cppbor::BSTR, "vbmeta_digest"); checkType(deviceInfo, cppbor::TSTR, "os_version"); checkType(deviceInfo, cppbor::UINT, "system_patch_level"); checkType(deviceInfo, cppbor::UINT, "boot_patch_level"); checkType(deviceInfo, cppbor::UINT, "vendor_patch_level"); checkType(deviceInfo, cppbor::UINT, "fused"); ASSERT_LT(deviceInfo->get("fused")->asUint()->value(), 2); // Must be 0 or 1. checkType(deviceInfo, cppbor::TSTR, "security_level"); allowList = getAllowedSecurityLevels(); ASSERT_NE(allowList.find(deviceInfo->get("security_level")->asTstr()->value()), allowList.end()); break; case 1: checkType(deviceInfo, cppbor::TSTR, "security_level"); allowList = getAllowedSecurityLevels(); ASSERT_NE(allowList.find(deviceInfo->get("security_level")->asTstr()->value()), allowList.end()); if (version->asUint()->value() == 1) { checkType(deviceInfo, cppbor::TSTR, "att_id_state"); allowList = getAllowedAttIdStates(); ASSERT_NE(allowList.find(deviceInfo->get("att_id_state")->asTstr()->value()), allowList.end()); } break; default: FAIL() << "Unrecognized version: " << version->asUint()->value(); } } bytevec eekId_; size_t testEekLength_; EekChain testEekChain_; Loading