1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <keymaster/keymaster_configuration.h>
18
19 #include <regex>
20 #include <string>
21
22 #include <regex.h>
23
24 #define LOG_TAG "keymaster"
25
26 #include <android-base/logging.h>
27 #include <android-base/properties.h>
28 #include <log/log.h>
29
30 #include <keymaster/authorization_set.h>
31
32 namespace keymaster {
33
34 namespace {
35
36 constexpr char kPlatformVersionProp[] = "ro.build.version.release";
37 constexpr char kPlatformVersionRegex[] = "^([0-9]{1,2})(\\.([0-9]{1,2}))?(\\.([0-9]{1,2}))?";
38 constexpr size_t kMajorVersionMatch = 1;
39 constexpr size_t kMinorVersionMatch = 3;
40 constexpr size_t kSubminorVersionMatch = 5;
41 constexpr size_t kPlatformVersionMatchCount = kSubminorVersionMatch + 1;
42
43 constexpr char kPlatformPatchlevelProp[] = "ro.build.version.security_patch";
44 constexpr char kVendorPatchlevelProp[] = "ro.vendor.build.security_patch";
45 constexpr char kPatchlevelRegex[] = "^([0-9]{4})-([0-9]{2})-([0-9]{2})$";
46 constexpr char kVerifiedBootStateProp[] = "ro.boot.verifiedbootstate";
47 constexpr char kVbmetaDeviceStateProp[] = "ro.boot.vbmeta.device_state";
48 constexpr char kVbmetaDigestProp[] = "ro.boot.vbmeta.digest";
49 constexpr size_t kYearMatch = 1;
50 constexpr size_t kMonthMatch = 2;
51 constexpr size_t kDayMatch = 3;
52 constexpr size_t kPatchlevelMatchCount = kDayMatch + 1;
53
match_to_uint32(const char * expression,const regmatch_t & match)54 uint32_t match_to_uint32(const char* expression, const regmatch_t& match) {
55 if (match.rm_so == -1) return 0;
56
57 size_t len = match.rm_eo - match.rm_so;
58 std::string s(expression + match.rm_so, len);
59 return std::stoul(s);
60 }
61
wait_and_get_property(const char * prop)62 std::string wait_and_get_property(const char* prop) {
63 std::string prop_value;
64 #ifndef KEYMASTER_UNIT_TEST_BUILD
65 while (!android::base::WaitForPropertyCreation(prop)) {
66 SLOGE("waited 15s for %s, still waiting...", prop);
67 }
68 prop_value = android::base::GetProperty(prop, "" /* default */);
69 #endif
70 return prop_value;
71 }
72
73 enum class PatchlevelOutput { kYearMonthDay, kYearMonth };
74
GetPatchlevel(const char * patchlevel_str,PatchlevelOutput detail)75 uint32_t GetPatchlevel(const char* patchlevel_str, PatchlevelOutput detail) {
76 regex_t regex;
77 if (regcomp(®ex, kPatchlevelRegex, REG_EXTENDED) != 0) {
78 ALOGE("Failed to compile platform patchlevel regex! (%s)", kPatchlevelRegex);
79 return 0;
80 }
81
82 regmatch_t matches[kPatchlevelMatchCount];
83 int not_match = regexec(®ex, patchlevel_str, kPatchlevelMatchCount, matches, 0 /* flags */);
84 regfree(®ex);
85 if (not_match) {
86 ALOGI(" patchlevel string does not match expected format. Using patchlevel 0");
87 return 0;
88 }
89
90 uint32_t year = match_to_uint32(patchlevel_str, matches[kYearMatch]);
91 uint32_t month = match_to_uint32(patchlevel_str, matches[kMonthMatch]);
92
93 if (month < 1 || month > 12) {
94 ALOGE("Invalid patch month %d", month);
95 return 0;
96 }
97
98 switch (detail) {
99 case PatchlevelOutput::kYearMonthDay: {
100 uint32_t day = match_to_uint32(patchlevel_str, matches[kDayMatch]);
101 if (day < 1 || day > 31) {
102 ALOGE("Invalid patch day %d", day);
103 return 0;
104 }
105 return year * 10000 + month * 100 + day;
106 }
107 case PatchlevelOutput::kYearMonth:
108 return year * 100 + month;
109 }
110 return 0;
111 }
112
113 } // anonymous namespace
114
ConfigureDevice(keymaster2_device_t * dev,uint32_t os_version,uint32_t os_patchlevel)115 keymaster_error_t ConfigureDevice(keymaster2_device_t* dev, uint32_t os_version,
116 uint32_t os_patchlevel) {
117 AuthorizationSet config_params(AuthorizationSetBuilder()
118 .Authorization(keymaster::TAG_OS_VERSION, os_version)
119 .Authorization(keymaster::TAG_OS_PATCHLEVEL, os_patchlevel));
120 return dev->configure(dev, &config_params);
121 }
122
ConfigureDevice(keymaster2_device_t * dev)123 keymaster_error_t ConfigureDevice(keymaster2_device_t* dev) {
124 return ConfigureDevice(dev, GetOsVersion(), GetOsPatchlevel());
125 }
126
GetOsVersion(const char * version_str)127 uint32_t GetOsVersion(const char* version_str) {
128 regex_t regex;
129 if (regcomp(®ex, kPlatformVersionRegex, REG_EXTENDED)) {
130 ALOGE("Failed to compile version regex! (%s)", kPlatformVersionRegex);
131 return 0;
132 }
133
134 regmatch_t matches[kPlatformVersionMatchCount];
135 int not_match =
136 regexec(®ex, version_str, kPlatformVersionMatchCount, matches, 0 /* flags */);
137 regfree(®ex);
138 if (not_match) {
139 ALOGI("Platform version string \"%s\" does not match expected format. Using version 0.",
140 version_str);
141 return 0;
142 }
143
144 uint32_t major = match_to_uint32(version_str, matches[kMajorVersionMatch]);
145 uint32_t minor = match_to_uint32(version_str, matches[kMinorVersionMatch]);
146 uint32_t subminor = match_to_uint32(version_str, matches[kSubminorVersionMatch]);
147
148 return (major * 100 + minor) * 100 + subminor;
149 }
150
GetOsVersion()151 uint32_t GetOsVersion() {
152 std::string version = wait_and_get_property(kPlatformVersionProp);
153 return GetOsVersion(version.c_str());
154 }
155
GetOsPatchlevel(const char * patchlevel_str)156 uint32_t GetOsPatchlevel(const char* patchlevel_str) {
157 return GetPatchlevel(patchlevel_str, PatchlevelOutput::kYearMonth);
158 }
159
GetOsPatchlevel()160 uint32_t GetOsPatchlevel() {
161 std::string patchlevel = wait_and_get_property(kPlatformPatchlevelProp);
162 return GetOsPatchlevel(patchlevel.c_str());
163 }
164
GetVendorPatchlevel()165 uint32_t GetVendorPatchlevel() {
166 std::string patchlevel = wait_and_get_property(kVendorPatchlevelProp);
167 return GetPatchlevel(patchlevel.c_str(), PatchlevelOutput::kYearMonthDay);
168 }
169
GetVerifiedBootState()170 std::string GetVerifiedBootState() {
171 // Do not wait for bootloader-set properties. They are passed to the kernel
172 // on the command line, and should always be available. If not available at
173 // this point, it will never be available.
174 return android::base::GetProperty(kVerifiedBootStateProp, /*default_value=*/"red");
175 }
176
GetBootloaderState()177 std::string GetBootloaderState() {
178 // Do not wait for bootloader-set properties. They are passed to the kernel
179 // on the command line, and should always be available. If not available at
180 // this point, it will never be available.
181 return android::base::GetProperty(kVbmetaDeviceStateProp, /*default_value=*/"unlocked");
182 }
183
HexCharToInt(char c)184 std::optional<uint8_t> HexCharToInt(char c) {
185 switch (c) {
186 case '0':
187 return 0x0;
188 case '1':
189 return 0x1;
190 case '2':
191 return 0x2;
192 case '3':
193 return 0x3;
194 case '4':
195 return 0x4;
196 case '5':
197 return 0x5;
198 case '6':
199 return 0x6;
200 case '7':
201 return 0x7;
202 case '8':
203 return 0x8;
204 case '9':
205 return 0x9;
206 case 'a':
207 return 0xa;
208 case 'A':
209 return 0xa;
210 case 'b':
211 return 0xb;
212 case 'B':
213 return 0xb;
214 case 'c':
215 return 0xc;
216 case 'C':
217 return 0xc;
218 case 'd':
219 return 0xd;
220 case 'D':
221 return 0xd;
222 case 'e':
223 return 0xe;
224 case 'E':
225 return 0xe;
226 case 'f':
227 return 0xf;
228 case 'F':
229 return 0xf;
230 default:
231 return std::nullopt;
232 }
233 }
234
GetVbmetaDigest(std::string_view vbmeta_string)235 std::optional<std::vector<uint8_t>> GetVbmetaDigest(std::string_view vbmeta_string) {
236 if (vbmeta_string.size() % 2 == 1) {
237 LOG(ERROR) << "hex string has an odd length (" << vbmeta_string.size() << ")";
238 return std::nullopt;
239 }
240
241 std::vector<uint8_t> out;
242 out.reserve(vbmeta_string.size() / 2);
243 for (auto next = vbmeta_string.begin(); next != vbmeta_string.end(); next += 2) {
244 auto high_nibble = HexCharToInt(*next);
245 auto low_nibble = HexCharToInt(*(next + 1));
246 if (!high_nibble || !low_nibble) {
247 LOG(ERROR) << "invalid input: '" << *next << "' or '" << *(next + 1) << "'";
248 return std::nullopt;
249 }
250 out.push_back((*high_nibble << 4) | *low_nibble);
251 }
252
253 return out;
254 }
255
GetVbmetaDigest()256 std::optional<std::vector<uint8_t>> GetVbmetaDigest() {
257 // Do not wait for bootloader-set properties. They are passed to the kernel
258 // on the command line, and should always be available. If not available at
259 // this point, it will never be available.
260 auto vbmeta_string = android::base::GetProperty(
261 kVbmetaDigestProp,
262 /*default_value=*/"0000000000000000000000000000000000000000000000000000000000000000");
263 return GetVbmetaDigest(vbmeta_string);
264 }
265
266 } // namespace keymaster
267