Trusty KeyMint: support boot,vendor patchlevels
- Add CONFIGURE_{VENDOR,BOOT}_PATCHLEVEL messages to
keymaster_ipc.h
- Map CONFIGURE_{VENDOR,BOOT}_PATCHLEVEL messages through to
AndroidKeymaster::Configure{Vendor,Boot}Patchlevel()
- Implement {Get,Set}{Vendor,Boot}PatchLevels() methods for
TrustyKeymasterContext
- Optionally include {vendor,boot}_patchlevel in
TrustyKeymasterContext::SetAuthorizations().
- Optionally check {vendor,boot}_patchlevel in
TrustyKeymastercontext::UpgradeKeyBlob().
Test: pending device availability
Bug: 193423844
Change-Id: I13902cd6fd12620c0db0065750e1a6c9cfbf7df6
diff --git a/ipc/keymaster_ipc.cpp b/ipc/keymaster_ipc.cpp
index 97daa2e..0b74166 100644
--- a/ipc/keymaster_ipc.cpp
+++ b/ipc/keymaster_ipc.cpp
@@ -616,14 +616,26 @@
out, out_size);
case KM_GENERATE_RKP_KEY:
- LOG_D("Dispatching KM_GENERATE_RKP_KEY, side %d", payload_size);
+ LOG_D("Dispatching KM_GENERATE_RKP_KEY, size %d", payload_size);
return do_dispatch(&TrustyKeymaster::GenerateRkpKey, msg, payload_size,
out, out_size);
case KM_GENERATE_CSR:
- LOG_D("Dispatching KM_GENERATE_CSR, side %d", payload_size);
+ LOG_D("Dispatching KM_GENERATE_CSR, size %d", payload_size);
return do_dispatch(&TrustyKeymaster::GenerateCsr, msg, payload_size,
out, out_size);
+
+ case KM_CONFIGURE_VENDOR_PATCHLEVEL:
+ LOG_D("Dispatching KM_CONFIGURE_VENDOR_PATCHLEVEL, size %d",
+ payload_size);
+ return do_dispatch(&TrustyKeymaster::ConfigureVendorPatchlevel, msg,
+ payload_size, out, out_size);
+
+ case KM_CONFIGURE_BOOT_PATCHLEVEL:
+ LOG_D("Dispatching KM_CONFIGURE_BOOT_PATCHLEVEL, size %d",
+ payload_size);
+ return do_dispatch(&TrustyKeymaster::ConfigureBootPatchlevel, msg,
+ payload_size, out, out_size);
}
LOG_E("Cannot dispatch unknown command %d", msg->cmd);
diff --git a/ipc/keymaster_ipc.h b/ipc/keymaster_ipc.h
index 4915123..aa3025f 100644
--- a/ipc/keymaster_ipc.h
+++ b/ipc/keymaster_ipc.h
@@ -58,6 +58,7 @@
KM_DEVICE_LOCKED = (30 << KEYMASTER_REQ_SHIFT),
KM_GENERATE_RKP_KEY = (31 << KEYMASTER_REQ_SHIFT),
KM_GENERATE_CSR = (32 << KEYMASTER_REQ_SHIFT),
+ KM_CONFIGURE_VENDOR_PATCHLEVEL = (33 << KEYMASTER_REQ_SHIFT),
// Bootloader calls.
KM_SET_BOOT_PARAMS = (0x1000 << KEYMASTER_REQ_SHIFT),
@@ -72,6 +73,7 @@
KM_CLEAR_ATTESTATION_CERT_CHAIN = (0xa000 << KEYMASTER_REQ_SHIFT),
KM_SET_WRAPPED_ATTESTATION_KEY = (0xb000 << KEYMASTER_REQ_SHIFT),
KM_SET_ATTESTATION_IDS = (0xc000 << KEYMASTER_REQ_SHIFT),
+ KM_CONFIGURE_BOOT_PATCHLEVEL = (0xd0000 << KEYMASTER_REQ_SHIFT),
};
/**
diff --git a/trusty_keymaster_context.cpp b/trusty_keymaster_context.cpp
index d61ba46..1f7d96f 100644
--- a/trusty_keymaster_context.cpp
+++ b/trusty_keymaster_context.cpp
@@ -299,10 +299,17 @@
hw_enforced->push_back(TAG_ORIGIN, origin);
// these values will be 0 if not set by bootloader
- // TODO(swillden): set VENDOR and BOOT patchlevels.
hw_enforced->push_back(TAG_OS_VERSION, boot_params_.boot_os_version);
hw_enforced->push_back(TAG_OS_PATCHLEVEL, boot_params_.boot_os_patchlevel);
+ if (vendor_patchlevel_.has_value()) {
+ hw_enforced->push_back(TAG_VENDOR_PATCHLEVEL,
+ vendor_patchlevel_.value());
+ }
+ if (boot_patchlevel_.has_value()) {
+ hw_enforced->push_back(TAG_BOOT_PATCHLEVEL, boot_patchlevel_.value());
+ }
+
if (sw_enforced->is_valid() != AuthorizationSet::OK)
return TranslateAuthorizationSetError(sw_enforced->is_valid());
if (hw_enforced->is_valid() != AuthorizationSet::OK)
@@ -415,7 +422,13 @@
if (!UpgradeIntegerTag(TAG_OS_VERSION, boot_params_.boot_os_version,
&key->hw_enforced(), &set_changed) ||
!UpgradeIntegerTag(TAG_OS_PATCHLEVEL, boot_params_.boot_os_patchlevel,
- &key->hw_enforced(), &set_changed)) {
+ &key->hw_enforced(), &set_changed) ||
+ (vendor_patchlevel_.has_value() &&
+ !UpgradeIntegerTag(TAG_VENDOR_PATCHLEVEL, vendor_patchlevel_.value(),
+ &key->hw_enforced(), &set_changed)) ||
+ (boot_patchlevel_.has_value() &&
+ !UpgradeIntegerTag(TAG_BOOT_PATCHLEVEL, boot_patchlevel_.value(),
+ &key->hw_enforced(), &set_changed))) {
// One of the version fields would have been a downgrade. Not allowed.
return KM_ERROR_INVALID_ARGUMENT;
}
diff --git a/trusty_keymaster_context.h b/trusty_keymaster_context.h
index 11d1c77..c4bf4b3 100644
--- a/trusty_keymaster_context.h
+++ b/trusty_keymaster_context.h
@@ -150,6 +150,34 @@
return trusty_remote_provisioning_context_.get();
}
+ keymaster_error_t SetVendorPatchlevel(uint32_t vendor_patchlevel) override {
+ if (vendor_patchlevel_.has_value() &&
+ vendor_patchlevel != vendor_patchlevel_.value()) {
+ // Can't set patchlevel to a different value.
+ return KM_ERROR_INVALID_ARGUMENT;
+ }
+ vendor_patchlevel_ = vendor_patchlevel;
+ return KM_ERROR_OK;
+ }
+
+ keymaster_error_t SetBootPatchlevel(uint32_t boot_patchlevel) override {
+ if (boot_patchlevel_.has_value() &&
+ boot_patchlevel != boot_patchlevel_.value()) {
+ // Can't set patchlevel to a different value.
+ return KM_ERROR_INVALID_ARGUMENT;
+ }
+ boot_patchlevel_ = boot_patchlevel;
+ return KM_ERROR_OK;
+ }
+
+ std::optional<uint32_t> GetVendorPatchlevel() const override {
+ return vendor_patchlevel_;
+ }
+
+ std::optional<uint32_t> GetBootPatchlevel() const override {
+ return boot_patchlevel_;
+ }
+
private:
bool SeedRngIfNeeded() const;
bool ShouldReseedRng() const;
@@ -212,6 +240,8 @@
.device_locked = false};
UniquePtr<TrustyRemoteProvisioningContext>
trusty_remote_provisioning_context_;
+ std::optional<uint32_t> vendor_patchlevel_;
+ std::optional<uint32_t> boot_patchlevel_;
};
} // namespace keymaster