diff --git a/keymaster/4.0/support/include/keymasterV4_0/keymaster_utils.h b/keymaster/4.0/support/include/keymasterV4_0/keymaster_utils.h index 5e5ae8d0ed..61645f853e 100644 --- a/keymaster/4.0/support/include/keymasterV4_0/keymaster_utils.h +++ b/keymaster/4.0/support/include/keymasterV4_0/keymaster_utils.h @@ -52,6 +52,9 @@ inline static hidl_vec blob2hidlVec(const std::vector& blob) { HardwareAuthToken hidlVec2AuthToken(const hidl_vec& buffer); hidl_vec authToken2HidlVec(const HardwareAuthToken& token); +uint32_t getOsVersion(); +uint32_t getOsPatchlevel(); + } // namespace support } // namespace V4_0 } // namespace keymaster diff --git a/keymaster/4.0/support/keymaster_utils.cpp b/keymaster/4.0/support/keymaster_utils.cpp index e35fdd36d5..850a7767bf 100644 --- a/keymaster/4.0/support/keymaster_utils.cpp +++ b/keymaster/4.0/support/keymaster_utils.cpp @@ -14,11 +14,13 @@ * limitations under the License. */ +#include + +#include #include #include -namespace android { -namespace hardware { +namespace android::hardware { inline static bool operator<(const hidl_vec& a, const hidl_vec& b) { auto result = memcmp(a.data(), b.data(), std::min(a.size(), b.size())); @@ -32,8 +34,7 @@ inline static bool operator<(const hidl_array& a, return memcmp(a.data(), b.data(), SIZE) == -1; } -namespace keymaster { -namespace V4_0 { +namespace keymaster::V4_0 { bool operator<(const HmacSharingParameters& a, const HmacSharingParameters& b) { return std::tie(a.seed, a.nonce) < std::tie(b.seed, b.nonce); @@ -58,9 +59,9 @@ constexpr size_t kHmacSize = 32; hidl_vec authToken2HidlVec(const HardwareAuthToken& token) { static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) + - sizeof(token.authenticatorId) + sizeof(token.authenticatorType) + - sizeof(token.timestamp) + kHmacSize == - sizeof(hw_auth_token_t), + sizeof(token.authenticatorId) + sizeof(token.authenticatorType) + + sizeof(token.timestamp) + kHmacSize == + sizeof(hw_auth_token_t), "HardwareAuthToken content size does not match hw_auth_token_t size"); hidl_vec result; @@ -86,9 +87,9 @@ hidl_vec authToken2HidlVec(const HardwareAuthToken& token) { HardwareAuthToken hidlVec2AuthToken(const hidl_vec& buffer) { HardwareAuthToken token; static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) + - sizeof(token.authenticatorId) + sizeof(token.authenticatorType) + - sizeof(token.timestamp) + kHmacSize == - sizeof(hw_auth_token_t), + sizeof(token.authenticatorId) + sizeof(token.authenticatorType) + + sizeof(token.timestamp) + kHmacSize == + sizeof(hw_auth_token_t), "HardwareAuthToken content size does not match hw_auth_token_t size"); if (buffer.size() != sizeof(hw_auth_token_t)) return {}; @@ -100,7 +101,7 @@ HardwareAuthToken hidlVec2AuthToken(const hidl_vec& buffer) { pos = copy_bytes_from_iterator(&token.authenticatorId, pos); pos = copy_bytes_from_iterator(&token.authenticatorType, pos); token.authenticatorType = static_cast( - ntohl(static_cast(token.authenticatorType))); + ntohl(static_cast(token.authenticatorType))); pos = copy_bytes_from_iterator(&token.timestamp, pos); token.timestamp = ntohq(token.timestamp); token.mac.resize(kHmacSize); @@ -109,8 +110,93 @@ HardwareAuthToken hidlVec2AuthToken(const hidl_vec& buffer) { return token; } +namespace { + +constexpr char kPlatformVersionProp[] = "ro.build.version.release"; +constexpr char kPlatformVersionRegex[] = "^([0-9]{1,2})(\\.([0-9]{1,2}))?(\\.([0-9]{1,2}))?"; +constexpr size_t kMajorVersionMatch = 1; +constexpr size_t kMinorVersionMatch = 3; +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 size_t kYearMatch = 1; +constexpr size_t kMonthMatch = 2; +constexpr size_t kPlatformPatchlevelMatchCount = kMonthMatch + 1; + +uint32_t match_to_uint32(const char* expression, const regmatch_t& match) { + if (match.rm_so == -1) return 0; + + size_t len = match.rm_eo - match.rm_so; + std::string s(expression + match.rm_so, len); + return std::stoul(s); +} + +std::string wait_and_get_property(const char* prop) { + std::string prop_value; + while (!android::base::WaitForPropertyCreation(prop)) + ; + prop_value = android::base::GetProperty(prop, "" /* default */); + return prop_value; +} + +} // anonymous namespace + +uint32_t getOsVersion(const char* version_str) { + regex_t regex; + if (regcomp(®ex, kPlatformVersionRegex, REG_EXTENDED)) { + return 0; + } + + regmatch_t matches[kPlatformVersionMatchCount]; + int not_match = + regexec(®ex, version_str, kPlatformVersionMatchCount, matches, 0 /* flags */); + regfree(®ex); + if (not_match) { + return 0; + } + + uint32_t major = match_to_uint32(version_str, matches[kMajorVersionMatch]); + uint32_t minor = match_to_uint32(version_str, matches[kMinorVersionMatch]); + uint32_t subminor = match_to_uint32(version_str, matches[kSubminorVersionMatch]); + + return (major * 100 + minor) * 100 + subminor; +} + +uint32_t getOsVersion() { + std::string version = wait_and_get_property(kPlatformVersionProp); + return getOsVersion(version.c_str()); +} + +uint32_t getOsPatchlevel(const char* patchlevel_str) { + regex_t regex; + if (regcomp(®ex, kPlatformPatchlevelRegex, REG_EXTENDED) != 0) { + return 0; + } + + regmatch_t matches[kPlatformPatchlevelMatchCount]; + int not_match = + regexec(®ex, patchlevel_str, kPlatformPatchlevelMatchCount, matches, 0 /* flags */); + regfree(®ex); + if (not_match) { + 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) { + return 0; + } + return year * 100 + month; +} + +uint32_t getOsPatchlevel() { + std::string patchlevel = wait_and_get_property(kPlatformPatchlevelProp); + return getOsPatchlevel(patchlevel.c_str()); +} + } // namespace support -} // namespace V4_0 -} // namespace keymaster -} // namespace hardware -} // namespace android +} // namespace keymaster::V4_0 +} // namespace android::hardware diff --git a/keymaster/4.0/vts/functional/Android.bp b/keymaster/4.0/vts/functional/Android.bp index 5649f20f86..7244ae3c96 100644 --- a/keymaster/4.0/vts/functional/Android.bp +++ b/keymaster/4.0/vts/functional/Android.bp @@ -27,7 +27,9 @@ cc_test { "android.hardware.keymaster@4.0", "libcrypto_static", "libkeymaster4support", - "libsoftkeymasterdevice", ], - test_suites: ["general-tests", "vts-core"], + test_suites: [ + "general-tests", + "vts-core", + ], } diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp index 7241984694..1fbd721e24 100644 --- a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp +++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp @@ -23,6 +23,7 @@ #include #include +#include namespace android { namespace hardware { @@ -56,11 +57,11 @@ void KeymasterHidlTest::InitializeKeymaster() { .isOk()); } -void KeymasterHidlTest::SetUp() { +void KeymasterHidlTest::SetUpTestCase() { InitializeKeymaster(); - os_version_ = ::keymaster::GetOsVersion(); - os_patch_level_ = ::keymaster::GetOsPatchlevel(); + os_version_ = support::getOsVersion(); + os_patch_level_ = support::getOsPatchlevel(); auto service_manager = android::hidl::manager::V1_0::IServiceManager::getService(); ASSERT_NE(nullptr, service_manager.get()); diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.h b/keymaster/4.0/vts/functional/KeymasterHidlTest.h index 4bd8b26db9..f7d6da2ca0 100644 --- a/keymaster/4.0/vts/functional/KeymasterHidlTest.h +++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.h @@ -18,10 +18,8 @@ #include #include -#include -#include -#include -#include + +#include #include