1cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden/* 2cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden * Copyright (C) 2016 The Android Open Source Project 3cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden * 4cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden * Licensed under the Apache License, Version 2.0 (the "License"); 5cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden * you may not use this file except in compliance with the License. 6cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden * You may obtain a copy of the License at 7cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden * 8cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden * http://www.apache.org/licenses/LICENSE-2.0 9cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden * 10cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden * Unless required by applicable law or agreed to in writing, software 11cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden * distributed under the License is distributed on an "AS IS" BASIS, 12cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden * See the License for the specific language governing permissions and 14cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden * limitations under the License. 15cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden */ 16cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 17cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden#include <keymaster/keymaster_configuration.h> 18cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 19cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden#include <regex> 20cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden#include <string> 21cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 22cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden#include <regex.h> 23cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 24cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden#define LOG_TAG "keymaster" 25cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden#include <cutils/log.h> 26cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 27cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden#ifndef KEYMASTER_UNIT_TEST_BUILD 28cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden#include <cutils/properties.h> 29cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden#else 30cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden#define PROPERTY_VALUE_MAX 80 /* Value doesn't matter */ 31cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdenvoid property_get(const char* /* prop_name */, char* /* prop */, const char* /* default */) {} 32cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden#endif 33cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 34cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden#include <keymaster/authorization_set.h> 35cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 36cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdennamespace keymaster { 37cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 38cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdennamespace { 39cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 40cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdenconstexpr char kPlatformVersionProp[] = "ro.build.version.release"; 41cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdenconstexpr char kPlatformVersionRegex[] = "^([0-9]{1,2})(\\.([0-9]{1,2}))?(\\.([0-9]{1,2}))?"; 42cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdenconstexpr size_t kMajorVersionMatch = 1; 43cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdenconstexpr size_t kMinorVersionMatch = 3; 44cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdenconstexpr size_t kSubminorVersionMatch = 5; 45cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdenconstexpr size_t kPlatformVersionMatchCount = kSubminorVersionMatch + 1; 46cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 47cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdenconstexpr char kPlatformPatchlevelProp[] = "ro.build.version.security_patch"; 48cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdenconstexpr char kPlatformPatchlevelRegex[] = "^([0-9]{4})-([0-9]{2})-[0-9]{2}$"; 49cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdenconstexpr size_t kYearMatch = 1; 50cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdenconstexpr size_t kMonthMatch = 2; 51cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdenconstexpr size_t kPlatformPatchlevelMatchCount = kMonthMatch + 1; 52cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 53cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdenuint32_t match_to_uint32(const char* expression, const regmatch_t& match) { 54cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden if (match.rm_so == -1) 55cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden return 0; 56cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 57cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden size_t len = match.rm_eo - match.rm_so; 58cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden std::string s(expression + match.rm_so, len); 59cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden return std::stoul(s); 60cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden} 61cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 62cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden} // anonymous namespace 63cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 64cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdenkeymaster_error_t ConfigureDevice(keymaster2_device_t* dev, uint32_t os_version, 65cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden uint32_t os_patchlevel) { 66cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden AuthorizationSet config_params(AuthorizationSetBuilder() 67cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden .Authorization(keymaster::TAG_OS_VERSION, os_version) 68cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden .Authorization(keymaster::TAG_OS_PATCHLEVEL, os_patchlevel)); 69cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden return dev->configure(dev, &config_params); 70cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden} 71cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 72cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdenkeymaster_error_t ConfigureDevice(keymaster2_device_t* dev) { 7323fe27baf78f53a44281f6f0f4169413e8770a72Shawn Willden return ConfigureDevice(dev, GetOsVersion(), GetOsPatchlevel()); 74cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden} 75cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 76cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdenuint32_t GetOsVersion(const char* version_str) { 77cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden regex_t regex; 78cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden if (regcomp(®ex, kPlatformVersionRegex, REG_EXTENDED)) { 79cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden ALOGE("Failed to compile version regex! (%s)", kPlatformVersionRegex); 80cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden return 0; 81cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden } 82cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 83cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden regmatch_t matches[kPlatformVersionMatchCount]; 8423fe27baf78f53a44281f6f0f4169413e8770a72Shawn Willden int not_match = 8523fe27baf78f53a44281f6f0f4169413e8770a72Shawn Willden regexec(®ex, version_str, kPlatformVersionMatchCount, matches, 0 /* flags */); 8638837e9dbf0be3f0f6014e66c6d92a75205b964eThurston Hou Yeen Dang regfree(®ex); 8738837e9dbf0be3f0f6014e66c6d92a75205b964eThurston Hou Yeen Dang if (not_match) { 88cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden ALOGI("Platform version string does not match expected format. Using version 0."); 89cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden return 0; 90cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden } 91cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 92cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden uint32_t major = match_to_uint32(version_str, matches[kMajorVersionMatch]); 93cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden uint32_t minor = match_to_uint32(version_str, matches[kMinorVersionMatch]); 94cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden uint32_t subminor = match_to_uint32(version_str, matches[kSubminorVersionMatch]); 95cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 96cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden return (major * 100 + minor) * 100 + subminor; 97cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden} 98cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 9923fe27baf78f53a44281f6f0f4169413e8770a72Shawn Willdenuint32_t GetOsVersion() { 10023fe27baf78f53a44281f6f0f4169413e8770a72Shawn Willden char version_str[PROPERTY_VALUE_MAX]; 10123fe27baf78f53a44281f6f0f4169413e8770a72Shawn Willden property_get(kPlatformVersionProp, version_str, "" /* default */); 10223fe27baf78f53a44281f6f0f4169413e8770a72Shawn Willden return GetOsVersion(version_str); 10323fe27baf78f53a44281f6f0f4169413e8770a72Shawn Willden} 10423fe27baf78f53a44281f6f0f4169413e8770a72Shawn Willden 105cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willdenuint32_t GetOsPatchlevel(const char* patchlevel_str) { 106cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden regex_t regex; 107cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden if (regcomp(®ex, kPlatformPatchlevelRegex, REG_EXTENDED) != 0) { 108cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden ALOGE("Failed to compile platform patchlevel regex! (%s)", kPlatformPatchlevelRegex); 109cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden return 0; 110cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden } 111cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 112cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden regmatch_t matches[kPlatformPatchlevelMatchCount]; 11323fe27baf78f53a44281f6f0f4169413e8770a72Shawn Willden int not_match = 11423fe27baf78f53a44281f6f0f4169413e8770a72Shawn Willden regexec(®ex, patchlevel_str, kPlatformPatchlevelMatchCount, matches, 0 /* flags */); 11538837e9dbf0be3f0f6014e66c6d92a75205b964eThurston Hou Yeen Dang regfree(®ex); 11638837e9dbf0be3f0f6014e66c6d92a75205b964eThurston Hou Yeen Dang if (not_match) { 117cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden ALOGI("Platform patchlevel string does not match expected format. Using patchlevel 0"); 118cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden return 0; 119cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden } 120cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 121cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden uint32_t year = match_to_uint32(patchlevel_str, matches[kYearMatch]); 122cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden uint32_t month = match_to_uint32(patchlevel_str, matches[kMonthMatch]); 123cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 124cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden if (month < 1 || month > 12) { 125cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden ALOGE("Invalid patch month %d", month); 126cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden return 0; 127cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden } 128cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden return year * 100 + month; 129cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden} 130cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden 13123fe27baf78f53a44281f6f0f4169413e8770a72Shawn Willdenuint32_t GetOsPatchlevel() { 13223fe27baf78f53a44281f6f0f4169413e8770a72Shawn Willden char patchlevel_str[PROPERTY_VALUE_MAX]; 13323fe27baf78f53a44281f6f0f4169413e8770a72Shawn Willden property_get(kPlatformPatchlevelProp, patchlevel_str, "" /* default */); 13423fe27baf78f53a44281f6f0f4169413e8770a72Shawn Willden return GetOsPatchlevel(patchlevel_str); 13523fe27baf78f53a44281f6f0f4169413e8770a72Shawn Willden} 13623fe27baf78f53a44281f6f0f4169413e8770a72Shawn Willden 137cddf3a443abf64f3d77c48886693179c0b8a35bbShawn Willden} // namespace keymaster 138