diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-08-18 04:04:48 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-08-18 04:04:48 +0000 |
commit | 598155a2371f2cd4cb7a6fcfeb12d38e17e45a18 (patch) | |
tree | 8536a59c8818cf5eb9ca12d5e56af3783f865469 | |
parent | 0a8d77c2f86043ff4b6c9d80017d576e8acce40b (diff) | |
parent | cabcb5764a7cbabed295d7b66fb0758831f77f67 (diff) | |
download | keymaster-598155a2371f2cd4cb7a6fcfeb12d38e17e45a18.tar.gz |
Snap for 7652338 from cabcb5764a7cbabed295d7b66fb0758831f77f67 to mainline-cellbroadcast-releaseandroid-mainline-12.0.0_r86android-mainline-12.0.0_r71android-mainline-12.0.0_r7android-mainline-12.0.0_r60android-mainline-12.0.0_r43android-mainline-12.0.0_r24android-mainline-12.0.0_r116android-mainline-12.0.0_r101android12-mainline-cellbroadcast-release
Change-Id: I66ad70931e1216ff94f80cdf12e9c764bec2b7c8
-rw-r--r-- | android_keymaster/android_keymaster.cpp | 53 | ||||
-rw-r--r-- | android_keymaster/keymaster_configuration.cpp | 75 | ||||
-rw-r--r-- | contexts/pure_soft_keymaster_context.cpp | 6 | ||||
-rw-r--r-- | include/keymaster/android_keymaster.h | 4 | ||||
-rw-r--r-- | include/keymaster/android_keymaster_messages.h | 38 | ||||
-rw-r--r-- | include/keymaster/contexts/pure_soft_keymaster_context.h | 25 | ||||
-rw-r--r-- | include/keymaster/key_blob_utils/software_keyblobs.h | 15 | ||||
-rw-r--r-- | include/keymaster/keymaster_configuration.h | 11 | ||||
-rw-r--r-- | include/keymaster/keymaster_context.h | 32 | ||||
-rw-r--r-- | key_blob_utils/software_keyblobs.cpp | 39 | ||||
-rw-r--r-- | ng/AndroidKeymaster4Device.cpp | 13 | ||||
-rw-r--r-- | tests/android_keymaster_messages_test.cpp | 41 |
12 files changed, 311 insertions, 41 deletions
diff --git a/android_keymaster/android_keymaster.cpp b/android_keymaster/android_keymaster.cpp index 3850481..00fa837 100644 --- a/android_keymaster/android_keymaster.cpp +++ b/android_keymaster/android_keymaster.cpp @@ -56,6 +56,22 @@ using cppcose::kAesGcmNonceLength; using cppcose::P256; using cppcose::x25519_HKDF_DeriveKey; +template <keymaster_tag_t T> +keymaster_error_t CheckPatchLevel(const AuthorizationSet& tee_enforced, + const AuthorizationSet& sw_enforced, TypedTag<KM_UINT, T> tag, + uint32_t current_patchlevel) { + uint32_t key_patchlevel; + if (tee_enforced.GetTagValue(tag, &key_patchlevel) || + sw_enforced.GetTagValue(tag, &key_patchlevel)) { + if (key_patchlevel < current_patchlevel) { + return KM_ERROR_KEY_REQUIRES_UPGRADE; + } else if (key_patchlevel > current_patchlevel) { + return KM_ERROR_INVALID_KEY_BLOB; + } + } + return KM_ERROR_OK; +} + keymaster_error_t CheckVersionInfo(const AuthorizationSet& tee_enforced, const AuthorizationSet& sw_enforced, const KeymasterContext& context) { @@ -63,13 +79,22 @@ keymaster_error_t CheckVersionInfo(const AuthorizationSet& tee_enforced, uint32_t os_patchlevel; context.GetSystemVersion(&os_version, &os_patchlevel); - uint32_t key_os_patchlevel; - if (tee_enforced.GetTagValue(TAG_OS_PATCHLEVEL, &key_os_patchlevel) || - sw_enforced.GetTagValue(TAG_OS_PATCHLEVEL, &key_os_patchlevel)) { - if (key_os_patchlevel < os_patchlevel) - return KM_ERROR_KEY_REQUIRES_UPGRADE; - else if (key_os_patchlevel > os_patchlevel) - return KM_ERROR_INVALID_KEY_BLOB; + keymaster_error_t err = + CheckPatchLevel(tee_enforced, sw_enforced, TAG_OS_PATCHLEVEL, os_patchlevel); + if (err != KM_ERROR_OK) return err; + + // Also check the vendor and boot patchlevels if available. + auto vendor_patchlevel = context.GetVendorPatchlevel(); + if (vendor_patchlevel.has_value()) { + err = CheckPatchLevel(tee_enforced, sw_enforced, TAG_VENDOR_PATCHLEVEL, + vendor_patchlevel.value()); + if (err != KM_ERROR_OK) return err; + } + auto boot_patchlevel = context.GetBootPatchlevel(); + if (boot_patchlevel.has_value()) { + err = CheckPatchLevel(tee_enforced, sw_enforced, TAG_BOOT_PATCHLEVEL, + boot_patchlevel.value()); + if (err != KM_ERROR_OK) return err; } return KM_ERROR_OK; @@ -782,6 +807,20 @@ void AndroidKeymaster::Configure(const ConfigureRequest& request, ConfigureRespo response->error = context_->SetSystemVersion(request.os_version, request.os_patchlevel); } +ConfigureVendorPatchlevelResponse +AndroidKeymaster::ConfigureVendorPatchlevel(const ConfigureVendorPatchlevelRequest& request) { + ConfigureVendorPatchlevelResponse rsp(message_version()); + rsp.error = context_->SetVendorPatchlevel(request.vendor_patchlevel); + return rsp; +} + +ConfigureBootPatchlevelResponse +AndroidKeymaster::ConfigureBootPatchlevel(const ConfigureBootPatchlevelRequest& request) { + ConfigureBootPatchlevelResponse rsp(message_version()); + rsp.error = context_->SetBootPatchlevel(request.boot_patchlevel); + return rsp; +} + bool AndroidKeymaster::has_operation(keymaster_operation_handle_t op_handle) const { return operation_table_->Find(op_handle) != nullptr; } diff --git a/android_keymaster/keymaster_configuration.cpp b/android_keymaster/keymaster_configuration.cpp index 7bf51c4..ca78863 100644 --- a/android_keymaster/keymaster_configuration.cpp +++ b/android_keymaster/keymaster_configuration.cpp @@ -40,10 +40,12 @@ constexpr size_t kSubminorVersionMatch = 5; constexpr size_t kPlatformVersionMatchCount = kSubminorVersionMatch + 1; constexpr char kPlatformPatchlevelProp[] = "ro.build.version.security_patch"; -constexpr char kPlatformPatchlevelRegex[] = "^([0-9]{4})-([0-9]{2})-[0-9]{2}$"; +constexpr char kVendorPatchlevelProp[] = "ro.vendor.build.security_patch"; +constexpr char kPatchlevelRegex[] = "^([0-9]{4})-([0-9]{2})-([0-9]{2})$"; constexpr size_t kYearMatch = 1; constexpr size_t kMonthMatch = 2; -constexpr size_t kPlatformPatchlevelMatchCount = kMonthMatch + 1; +constexpr size_t kDayMatch = 3; +constexpr size_t kPatchlevelMatchCount = kDayMatch + 1; uint32_t match_to_uint32(const char* expression, const regmatch_t& match) { if (match.rm_so == -1) return 0; @@ -64,6 +66,46 @@ std::string wait_and_get_property(const char* prop) { return prop_value; } +enum class PatchlevelOutput { kYearMonthDay, kYearMonth }; + +uint32_t GetPatchlevel(const char* patchlevel_str, PatchlevelOutput detail) { + regex_t regex; + if (regcomp(®ex, kPatchlevelRegex, REG_EXTENDED) != 0) { + ALOGE("Failed to compile platform patchlevel regex! (%s)", kPatchlevelRegex); + return 0; + } + + regmatch_t matches[kPatchlevelMatchCount]; + int not_match = regexec(®ex, patchlevel_str, kPatchlevelMatchCount, matches, 0 /* flags */); + regfree(®ex); + if (not_match) { + ALOGI(" patchlevel string does not match expected format. Using patchlevel 0"); + return 0; + } + + uint32_t year = match_to_uint32(patchlevel_str, matches[kYearMatch]); + uint32_t month = match_to_uint32(patchlevel_str, matches[kMonthMatch]); + + if (month < 1 || month > 12) { + ALOGE("Invalid patch month %d", month); + return 0; + } + + switch (detail) { + case PatchlevelOutput::kYearMonthDay: { + uint32_t day = match_to_uint32(patchlevel_str, matches[kDayMatch]); + if (day < 1 || day > 31) { + ALOGE("Invalid patch day %d", day); + return 0; + } + return year * 10000 + month * 100 + day; + } + case PatchlevelOutput::kYearMonth: + return year * 100 + month; + } + return 0; +} + } // anonymous namespace keymaster_error_t ConfigureDevice(keymaster2_device_t* dev, uint32_t os_version, @@ -108,29 +150,7 @@ uint32_t GetOsVersion() { } uint32_t GetOsPatchlevel(const char* patchlevel_str) { - regex_t regex; - if (regcomp(®ex, kPlatformPatchlevelRegex, REG_EXTENDED) != 0) { - ALOGE("Failed to compile platform patchlevel regex! (%s)", kPlatformPatchlevelRegex); - return 0; - } - - regmatch_t matches[kPlatformPatchlevelMatchCount]; - int not_match = - regexec(®ex, patchlevel_str, kPlatformPatchlevelMatchCount, matches, 0 /* flags */); - regfree(®ex); - if (not_match) { - ALOGI("Platform patchlevel string does not match expected format. Using patchlevel 0"); - return 0; - } - - uint32_t year = match_to_uint32(patchlevel_str, matches[kYearMatch]); - uint32_t month = match_to_uint32(patchlevel_str, matches[kMonthMatch]); - - if (month < 1 || month > 12) { - ALOGE("Invalid patch month %d", month); - return 0; - } - return year * 100 + month; + return GetPatchlevel(patchlevel_str, PatchlevelOutput::kYearMonth); } uint32_t GetOsPatchlevel() { @@ -138,4 +158,9 @@ uint32_t GetOsPatchlevel() { return GetOsPatchlevel(patchlevel.c_str()); } +uint32_t GetVendorPatchlevel() { + std::string patchlevel = wait_and_get_property(kVendorPatchlevelProp); + return GetPatchlevel(patchlevel.c_str(), PatchlevelOutput::kYearMonthDay); +} + } // namespace keymaster diff --git a/contexts/pure_soft_keymaster_context.cpp b/contexts/pure_soft_keymaster_context.cpp index c04475e..bfa92a4 100644 --- a/contexts/pure_soft_keymaster_context.cpp +++ b/contexts/pure_soft_keymaster_context.cpp @@ -187,6 +187,9 @@ keymaster_error_t PureSoftKeymasterContext::CreateKeyBlob(const AuthorizationSet keymaster_error_t error = SetKeyBlobAuthorizations(key_description, origin, os_version_, os_patchlevel_, hw_enforced, sw_enforced); if (error != KM_ERROR_OK) return error; + error = + ExtendKeyBlobAuthorizations(hw_enforced, sw_enforced, vendor_patchlevel_, boot_patchlevel_); + if (error != KM_ERROR_OK) return error; AuthorizationSet hidden; error = BuildHiddenAuthorizations(key_description, &hidden, softwareRootOfTrust); @@ -210,7 +213,8 @@ keymaster_error_t PureSoftKeymasterContext::UpgradeKeyBlob(const KeymasterKeyBlo keymaster_error_t error = ParseKeyBlob(key_to_upgrade, upgrade_params, &key); if (error != KM_ERROR_OK) return error; - return UpgradeSoftKeyBlob(key, os_version_, os_patchlevel_, upgrade_params, upgraded_key); + return FullUpgradeSoftKeyBlob(key, os_version_, os_patchlevel_, vendor_patchlevel_, + boot_patchlevel_, upgrade_params, upgraded_key); } keymaster_error_t PureSoftKeymasterContext::ParseKeyBlob(const KeymasterKeyBlob& blob, diff --git a/include/keymaster/android_keymaster.h b/include/keymaster/android_keymaster.h index e1f4eee..bbeb81a 100644 --- a/include/keymaster/android_keymaster.h +++ b/include/keymaster/android_keymaster.h @@ -93,6 +93,10 @@ class AndroidKeymaster { EarlyBootEndedResponse EarlyBootEnded(); DeviceLockedResponse DeviceLocked(const DeviceLockedRequest& request); GetVersion2Response GetVersion2(const GetVersion2Request& request); + ConfigureVendorPatchlevelResponse + ConfigureVendorPatchlevel(const ConfigureVendorPatchlevelRequest& request); + ConfigureBootPatchlevelResponse + ConfigureBootPatchlevel(const ConfigureBootPatchlevelRequest& request); bool has_operation(keymaster_operation_handle_t op_handle) const; diff --git a/include/keymaster/android_keymaster_messages.h b/include/keymaster/android_keymaster_messages.h index 610a139..2ec473f 100644 --- a/include/keymaster/android_keymaster_messages.h +++ b/include/keymaster/android_keymaster_messages.h @@ -61,6 +61,8 @@ enum AndroidKeymasterCommand : uint32_t { GENERATE_RKP_KEY = 29, GENERATE_CSR = 30, GENERATE_TIMESTAMP_TOKEN = 31, + CONFIGURE_VENDOR_PATCHLEVEL = 32, + CONFIGURE_BOOT_PATCHLEVEL = 33, }; /** @@ -401,7 +403,7 @@ struct GenerateCsrRequest : public KeymasterMessage { bool test_mode = false; size_t num_keys = 0; - KeymasterBlob* keys_to_sign_array; + KeymasterBlob* keys_to_sign_array = nullptr; KeymasterBlob endpoint_enc_cert_chain; KeymasterBlob challenge; }; @@ -751,7 +753,7 @@ struct ConfigureRequest : public KeymasterMessage { } uint32_t os_version; - uint32_t os_patchlevel; + uint32_t os_patchlevel; // YYYYMM }; using ConfigureResponse = EmptyKeymasterResponse; @@ -1143,4 +1145,36 @@ struct SetAttestationIdsRequest : public KeymasterMessage { using SetAttestationIdsResponse = EmptyKeymasterResponse; +struct ConfigureVendorPatchlevelRequest : public KeymasterMessage { + explicit ConfigureVendorPatchlevelRequest(int32_t ver) : KeymasterMessage(ver) {} + + size_t SerializedSize() const override { return sizeof(vendor_patchlevel); } + uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override { + return append_uint32_to_buf(buf, end, vendor_patchlevel); + } + bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override { + return copy_uint32_from_buf(buf_ptr, end, &vendor_patchlevel); + } + + uint32_t vendor_patchlevel{}; // YYYYMMDD +}; + +using ConfigureVendorPatchlevelResponse = EmptyKeymasterResponse; + +struct ConfigureBootPatchlevelRequest : public KeymasterMessage { + explicit ConfigureBootPatchlevelRequest(int32_t ver) : KeymasterMessage(ver) {} + + size_t SerializedSize() const override { return sizeof(boot_patchlevel); } + uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override { + return append_uint32_to_buf(buf, end, boot_patchlevel); + } + bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override { + return copy_uint32_from_buf(buf_ptr, end, &boot_patchlevel); + } + + uint32_t boot_patchlevel{}; // YYYYMMDD +}; + +using ConfigureBootPatchlevelResponse = EmptyKeymasterResponse; + } // namespace keymaster diff --git a/include/keymaster/contexts/pure_soft_keymaster_context.h b/include/keymaster/contexts/pure_soft_keymaster_context.h index 892af5d..2f7f098 100644 --- a/include/keymaster/contexts/pure_soft_keymaster_context.h +++ b/include/keymaster/contexts/pure_soft_keymaster_context.h @@ -89,6 +89,29 @@ class PureSoftKeymasterContext : public KeymasterContext, RemoteProvisioningContext* GetRemoteProvisioningContext() const override { return pure_soft_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_; } + /********************************************************************************************* * Implement SoftwareKeyBlobMaker */ @@ -119,6 +142,8 @@ class PureSoftKeymasterContext : public KeymasterContext, std::unique_ptr<KeyFactory> hmac_factory_; uint32_t os_version_; uint32_t os_patchlevel_; + std::optional<uint32_t> vendor_patchlevel_; + std::optional<uint32_t> boot_patchlevel_; SoftKeymasterEnforcement soft_keymaster_enforcement_; const keymaster_security_level_t security_level_; std::unique_ptr<SecureKeyStorage> pure_soft_secure_key_storage_; diff --git a/include/keymaster/key_blob_utils/software_keyblobs.h b/include/keymaster/key_blob_utils/software_keyblobs.h index 65e7ff5..962ed5a 100644 --- a/include/keymaster/key_blob_utils/software_keyblobs.h +++ b/include/keymaster/key_blob_utils/software_keyblobs.h @@ -17,6 +17,8 @@ #pragma once +#include <optional> + #include <hardware/keymaster_defs.h> #include <keymaster/android_keymaster_utils.h> #include <openssl/base.h> @@ -52,8 +54,21 @@ keymaster_error_t SetKeyBlobAuthorizations(const AuthorizationSet& key_descripti keymaster_key_origin_t origin, uint32_t os_version, uint32_t os_patchlevel, AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced); + +keymaster_error_t ExtendKeyBlobAuthorizations(AuthorizationSet* hw_enforced, + AuthorizationSet* sw_enforced, + std::optional<uint32_t> vendor_patchlevel, + std::optional<uint32_t> boot_patchlevel); + keymaster_error_t UpgradeSoftKeyBlob(const UniquePtr<Key>& key, const uint32_t os_version, const uint32_t os_patchlevel, const AuthorizationSet& upgrade_params, KeymasterKeyBlob* upgraded_key); + +keymaster_error_t FullUpgradeSoftKeyBlob(const UniquePtr<Key>& key, const uint32_t os_version, + uint32_t os_patchlevel, + std::optional<uint32_t> vendor_patchlevel, + std::optional<uint32_t> boot_patchlevel, + const AuthorizationSet& upgrade_params, + KeymasterKeyBlob* upgraded_key); } // namespace keymaster diff --git a/include/keymaster/keymaster_configuration.h b/include/keymaster/keymaster_configuration.h index 69738fd..32da101 100644 --- a/include/keymaster/keymaster_configuration.h +++ b/include/keymaster/keymaster_configuration.h @@ -48,16 +48,23 @@ uint32_t GetOsVersion(); /** * Parses OS patch level string, returning year and month in integer form. For example, "2016-03-25" * will be returned as 201603. Returns 0 if the string doesn't contain a date in the form - * YYYY-MM-DD. + * YYYY-MM-DD; returns YYYMM on success. */ uint32_t GetOsPatchlevel(const char* patchlevel_string); /** * Retrieves and parses OS patch level from build properties. Returns 0 if the string doesn't - * contain a date in the form YYYY-MM-DD. + * contain a date in the form YYYY-MM-DD; returns YYYYMM on success. */ uint32_t GetOsPatchlevel(); +/** + * Retrieves and parses vendor patch level from build properties (which may require SELinux + * permission). Returns 0 if the string doesn't contain a date in the form YYYY-MM-DD; returns + * YYYYMMDD on success. + */ +uint32_t GetVendorPatchlevel(); + } // namespace keymaster #endif // SYSTEM_KEYMASTER_KEYMASTER_CONFIGURATION_H_ diff --git a/include/keymaster/keymaster_context.h b/include/keymaster/keymaster_context.h index 3eebfc5..65c1b73 100644 --- a/include/keymaster/keymaster_context.h +++ b/include/keymaster/keymaster_context.h @@ -17,6 +17,8 @@ #ifndef SYSTEM_KEYMASTER_KEYMASTER_CONTEXT_H_ #define SYSTEM_KEYMASTER_KEYMASTER_CONTEXT_H_ +#include <optional> + #include <assert.h> #include <hardware/keymaster_defs.h> @@ -213,6 +215,36 @@ class KeymasterContext { */ virtual RemoteProvisioningContext* GetRemoteProvisioningContext() const { return nullptr; } + /** + * Sets the vendor patchlevel (format YYYYMMDD) for the implementation. This value should + * be set by the HAL service at start of day. A subsequent attempt to set a different + * value will return KM_ERROR_INVALID_ARGUMENT. + */ + virtual keymaster_error_t SetVendorPatchlevel(uint32_t /* vendor_patchlevel */) { + return KM_ERROR_UNIMPLEMENTED; + } + + /** + * Sets the boot patchlevel (format YYYYMMDD) for the implementation. This value should be set + * by the bootloader. A subsequent to set a different value will return + * KM_ERROR_INVALID_ARGUMENT; + */ + virtual keymaster_error_t SetBootPatchlevel(uint32_t /* boot_patchlevel */) { + return KM_ERROR_UNIMPLEMENTED; + } + + /** + * Returns the vendor patchlevel, as set by the HAL service using SetVendorPatchlevel. + */ + virtual std::optional<uint32_t> GetVendorPatchlevel() const { return std::nullopt; } + + /** + * Returns the boot patchlevel. For hardware-based implementations this will be the value set by + * the bootloader. For software implementations this will be the information set by + * SetBootPatchLevel. + */ + virtual std::optional<uint32_t> GetBootPatchlevel() const { return std::nullopt; } + private: // Uncopyable. KeymasterContext(const KeymasterContext&); diff --git a/key_blob_utils/software_keyblobs.cpp b/key_blob_utils/software_keyblobs.cpp index de038f0..764ebcb 100644 --- a/key_blob_utils/software_keyblobs.cpp +++ b/key_blob_utils/software_keyblobs.cpp @@ -381,10 +381,37 @@ keymaster_error_t SetKeyBlobAuthorizations(const AuthorizationSet& key_descripti return TranslateAuthorizationSetError(sw_enforced->is_valid()); } +keymaster_error_t ExtendKeyBlobAuthorizations(AuthorizationSet* hw_enforced, + AuthorizationSet* sw_enforced, + std::optional<uint32_t> vendor_patchlevel, + std::optional<uint32_t> boot_patchlevel) { + // If hw_enforced is non-empty, we're pretending to be some sort of secure hardware. + AuthorizationSet* pseudo_hw_enforced = (hw_enforced->empty()) ? sw_enforced : hw_enforced; + if (vendor_patchlevel.has_value()) { + pseudo_hw_enforced->push_back(TAG_VENDOR_PATCHLEVEL, vendor_patchlevel.value()); + } + if (boot_patchlevel.has_value()) { + pseudo_hw_enforced->push_back(TAG_BOOT_PATCHLEVEL, boot_patchlevel.value()); + } + return TranslateAuthorizationSetError(sw_enforced->is_valid()); +} + keymaster_error_t UpgradeSoftKeyBlob(const UniquePtr<Key>& key, const uint32_t os_version, const uint32_t os_patchlevel, const AuthorizationSet& upgrade_params, KeymasterKeyBlob* upgraded_key) { + return FullUpgradeSoftKeyBlob(key, os_version, os_patchlevel, + /* vendor_patchlevel= */ std::nullopt, + /* boot_patchlevel= */ std::nullopt, // + upgrade_params, upgraded_key); +} + +keymaster_error_t FullUpgradeSoftKeyBlob(const UniquePtr<Key>& key, const uint32_t os_version, + uint32_t os_patchlevel, + std::optional<uint32_t> vendor_patchlevel, + std::optional<uint32_t> boot_patchlevel, + const AuthorizationSet& upgrade_params, + KeymasterKeyBlob* upgraded_key) { bool set_changed = false; if (os_version == 0) { @@ -402,13 +429,21 @@ keymaster_error_t UpgradeSoftKeyBlob(const UniquePtr<Key>& key, const uint32_t o } if (!UpgradeIntegerTag(TAG_OS_VERSION, os_version, &key->sw_enforced(), &set_changed) || - !UpgradeIntegerTag(TAG_OS_PATCHLEVEL, os_patchlevel, &key->sw_enforced(), &set_changed)) + !UpgradeIntegerTag(TAG_OS_PATCHLEVEL, os_patchlevel, &key->sw_enforced(), &set_changed) || + (vendor_patchlevel.has_value() && + !UpgradeIntegerTag(TAG_VENDOR_PATCHLEVEL, vendor_patchlevel.value(), &key->sw_enforced(), + &set_changed)) || + (boot_patchlevel.has_value() && + !UpgradeIntegerTag(TAG_BOOT_PATCHLEVEL, boot_patchlevel.value(), &key->sw_enforced(), + &set_changed))) { // One of the version fields would have been a downgrade. Not allowed. return KM_ERROR_INVALID_ARGUMENT; + } - if (!set_changed) + if (!set_changed) { // Dont' need an upgrade. return KM_ERROR_OK; + } AuthorizationSet hidden; auto error = BuildHiddenAuthorizations(upgrade_params, &hidden, softwareRootOfTrust); diff --git a/ng/AndroidKeymaster4Device.cpp b/ng/AndroidKeymaster4Device.cpp index a71948e..18d7fb4 100644 --- a/ng/AndroidKeymaster4Device.cpp +++ b/ng/AndroidKeymaster4Device.cpp @@ -511,7 +511,7 @@ Return<void> AndroidKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec<u Return<void> AndroidKeymaster4Device::update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams, const hidl_vec<uint8_t>& input, - const HardwareAuthToken& /* authToken */, + const HardwareAuthToken& authToken , const VerificationToken& /* verificationToken */, update_cb _hidl_cb) { UpdateOperationRequest request(impl_->message_version()); @@ -519,6 +519,10 @@ Return<void> AndroidKeymaster4Device::update(uint64_t operationHandle, request.input.Reinitialize(input.data(), input.size()); request.additional_params.Reinitialize(KmParamSet(inParams)); + hidl_vec<uint8_t> hidl_vec_token = authToken2HidlVec(authToken); + request.additional_params.push_back( + TAG_AUTH_TOKEN, reinterpret_cast<uint8_t*>(hidl_vec_token.data()), hidl_vec_token.size()); + UpdateOperationResponse response(impl_->message_version()); impl_->UpdateOperation(request, &response); @@ -538,7 +542,7 @@ Return<void> AndroidKeymaster4Device::finish(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams, const hidl_vec<uint8_t>& input, const hidl_vec<uint8_t>& signature, - const HardwareAuthToken& /* authToken */, + const HardwareAuthToken& authToken , const VerificationToken& /* verificationToken */, finish_cb _hidl_cb) { FinishOperationRequest request(impl_->message_version()); @@ -547,6 +551,11 @@ Return<void> AndroidKeymaster4Device::finish(uint64_t operationHandle, request.signature.Reinitialize(signature.data(), signature.size()); request.additional_params.Reinitialize(KmParamSet(inParams)); + hidl_vec<uint8_t> hidl_vec_token = authToken2HidlVec(authToken); + request.additional_params.push_back( + TAG_AUTH_TOKEN, reinterpret_cast<uint8_t*>(hidl_vec_token.data()), hidl_vec_token.size()); + + FinishOperationResponse response(impl_->message_version()); impl_->FinishOperation(request, &response); diff --git a/tests/android_keymaster_messages_test.cpp b/tests/android_keymaster_messages_test.cpp index 2c4ea0b..7b523a8 100644 --- a/tests/android_keymaster_messages_test.cpp +++ b/tests/android_keymaster_messages_test.cpp @@ -675,6 +675,47 @@ TEST(RoundTrip, ConfigureRequest) { } } +TEST(RoundTrip, ConfigureResponse) { + for (int ver = 0; ver <= kMaxMessageVersion; ++ver) { + ConfigureResponse rsp(ver); + UniquePtr<ConfigureResponse> deserialized(round_trip(ver, rsp, 4)); + } +} + +TEST(RoundTrip, ConfigureVendorPatchlevelRequest) { + for (int ver = 0; ver <= kMaxMessageVersion; ++ver) { + ConfigureVendorPatchlevelRequest req(ver); + req.vendor_patchlevel = 2; + + UniquePtr<ConfigureVendorPatchlevelRequest> deserialized(round_trip(ver, req, 4)); + EXPECT_EQ(deserialized->vendor_patchlevel, req.vendor_patchlevel); + } +} + +TEST(RoundTrip, ConfigureVendorPatchlevelResponse) { + for (int ver = 0; ver <= kMaxMessageVersion; ++ver) { + ConfigureVendorPatchlevelResponse rsp(ver); + UniquePtr<ConfigureVendorPatchlevelResponse> deserialized(round_trip(ver, rsp, 4)); + } +} + +TEST(RoundTrip, ConfigureBootPatchlevelRequest) { + for (int ver = 0; ver <= kMaxMessageVersion; ++ver) { + ConfigureBootPatchlevelRequest req(ver); + req.boot_patchlevel = 2; + + UniquePtr<ConfigureBootPatchlevelRequest> deserialized(round_trip(ver, req, 4)); + EXPECT_EQ(deserialized->boot_patchlevel, req.boot_patchlevel); + } +} + +TEST(RoundTrip, ConfigureBootPatchlevelResponse) { + for (int ver = 0; ver <= kMaxMessageVersion; ++ver) { + ConfigureBootPatchlevelResponse rsp(ver); + UniquePtr<ConfigureBootPatchlevelResponse> deserialized(round_trip(ver, rsp, 4)); + } +} + TEST(RoundTrip, AddEntropyRequest) { for (int ver = 0; ver <= kMaxMessageVersion; ++ver) { AddEntropyRequest msg(ver); |