1 /*
2 * Copyright (C) 2018 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 <regex.h>
18
19 #include <android-base/logging.h>
20 #include <android-base/properties.h>
21 #include <hardware/hw_auth_token.h>
22 #include <keymasterV4_0/keymaster_utils.h>
23
24 namespace android::hardware {
25
operator <(const hidl_vec<uint8_t> & a,const hidl_vec<uint8_t> & b)26 inline static bool operator<(const hidl_vec<uint8_t>& a, const hidl_vec<uint8_t>& b) {
27 auto result = memcmp(a.data(), b.data(), std::min(a.size(), b.size()));
28 if (!result) return a.size() < b.size();
29 return result < 0;
30 }
31
32 template <size_t SIZE>
operator <(const hidl_array<uint8_t,SIZE> & a,const hidl_array<uint8_t,SIZE> & b)33 inline static bool operator<(const hidl_array<uint8_t, SIZE>& a,
34 const hidl_array<uint8_t, SIZE>& b) {
35 return memcmp(a.data(), b.data(), SIZE) == -1;
36 }
37
38 namespace keymaster::V4_0 {
39
operator <(const HmacSharingParameters & a,const HmacSharingParameters & b)40 bool operator<(const HmacSharingParameters& a, const HmacSharingParameters& b) {
41 return std::tie(a.seed, a.nonce) < std::tie(b.seed, b.nonce);
42 }
43
44 namespace support {
45
46 template <typename T, typename InIter>
copy_bytes_from_iterator(T * value,InIter src)47 inline static InIter copy_bytes_from_iterator(T* value, InIter src) {
48 uint8_t* value_ptr = reinterpret_cast<uint8_t*>(value);
49 std::copy(src, src + sizeof(T), value_ptr);
50 return src + sizeof(T);
51 }
52
53 template <typename T, typename OutIter>
copy_bytes_to_iterator(const T & value,OutIter dest)54 inline static OutIter copy_bytes_to_iterator(const T& value, OutIter dest) {
55 const uint8_t* value_ptr = reinterpret_cast<const uint8_t*>(&value);
56 return std::copy(value_ptr, value_ptr + sizeof(value), dest);
57 }
58
59 constexpr size_t kHmacSize = 32;
60
authToken2HidlVec(const HardwareAuthToken & token)61 hidl_vec<uint8_t> authToken2HidlVec(const HardwareAuthToken& token) {
62 static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) +
63 sizeof(token.authenticatorId) + sizeof(token.authenticatorType) +
64 sizeof(token.timestamp) + kHmacSize ==
65 sizeof(hw_auth_token_t),
66 "HardwareAuthToken content size does not match hw_auth_token_t size");
67
68 hidl_vec<uint8_t> result;
69 result.resize(sizeof(hw_auth_token_t));
70 auto pos = result.begin();
71 *pos++ = 0; // Version byte
72 pos = copy_bytes_to_iterator(token.challenge, pos);
73 pos = copy_bytes_to_iterator(token.userId, pos);
74 pos = copy_bytes_to_iterator(token.authenticatorId, pos);
75 auto auth_type = htonl(static_cast<uint32_t>(token.authenticatorType));
76 pos = copy_bytes_to_iterator(auth_type, pos);
77 auto timestamp = htonq(token.timestamp);
78 pos = copy_bytes_to_iterator(timestamp, pos);
79 if (token.mac.size() != kHmacSize) {
80 std::fill(pos, pos + kHmacSize, 0);
81 } else {
82 std::copy(token.mac.begin(), token.mac.end(), pos);
83 }
84
85 return result;
86 }
87
hidlVec2AuthToken(const hidl_vec<uint8_t> & buffer)88 HardwareAuthToken hidlVec2AuthToken(const hidl_vec<uint8_t>& buffer) {
89 HardwareAuthToken token;
90 static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) +
91 sizeof(token.authenticatorId) + sizeof(token.authenticatorType) +
92 sizeof(token.timestamp) + kHmacSize ==
93 sizeof(hw_auth_token_t),
94 "HardwareAuthToken content size does not match hw_auth_token_t size");
95
96 if (buffer.size() != sizeof(hw_auth_token_t)) return {};
97
98 auto pos = buffer.begin();
99 ++pos; // skip first byte
100 pos = copy_bytes_from_iterator(&token.challenge, pos);
101 pos = copy_bytes_from_iterator(&token.userId, pos);
102 pos = copy_bytes_from_iterator(&token.authenticatorId, pos);
103 pos = copy_bytes_from_iterator(&token.authenticatorType, pos);
104 token.authenticatorType = static_cast<HardwareAuthenticatorType>(
105 ntohl(static_cast<uint32_t>(token.authenticatorType)));
106 pos = copy_bytes_from_iterator(&token.timestamp, pos);
107 token.timestamp = ntohq(token.timestamp);
108 token.mac.resize(kHmacSize);
109 std::copy(pos, pos + kHmacSize, token.mac.data());
110
111 return token;
112 }
113
appendUint64(std::vector<uint8_t> & vec,uint64_t value)114 void appendUint64(std::vector<uint8_t>& vec, uint64_t value) {
115 for (size_t n = 0; n < sizeof(uint64_t); n++) {
116 uint8_t byte = (value >> (n * 8)) & 0xff;
117 vec.push_back(byte);
118 }
119 }
120
extractUint64(const std::vector<uint8_t> & data,size_t offset)121 uint64_t extractUint64(const std::vector<uint8_t>& data, size_t offset) {
122 uint64_t value = 0;
123 for (size_t n = 0; n < sizeof(uint64_t); n++) {
124 uint64_t tmp = data[offset + n];
125 value |= (tmp << (n * 8));
126 }
127 return value;
128 }
129
appendUint32(std::vector<uint8_t> & vec,uint32_t value)130 void appendUint32(std::vector<uint8_t>& vec, uint32_t value) {
131 for (size_t n = 0; n < sizeof(uint32_t); n++) {
132 uint8_t byte = (value >> (n * 8)) & 0xff;
133 vec.push_back(byte);
134 }
135 }
136
extractUint32(const std::vector<uint8_t> & data,size_t offset)137 uint32_t extractUint32(const std::vector<uint8_t>& data, size_t offset) {
138 uint32_t value = 0;
139 for (size_t n = 0; n < sizeof(uint32_t); n++) {
140 uint32_t tmp = data[offset + n];
141 value |= (tmp << (n * 8));
142 }
143 return value;
144 }
145
serializeVerificationToken(const VerificationToken & token)146 std::optional<std::vector<uint8_t>> serializeVerificationToken(const VerificationToken& token) {
147 if (token.parametersVerified.size() > 0) {
148 LOG(ERROR) << "Serializing verification tokens with parametersVerified is not supported";
149 return {};
150 }
151 if (!(token.mac.size() == 0 || token.mac.size() == 32)) {
152 LOG(ERROR) << "Unexpected MAC size " << token.mac.size() << ", expected 0 or 32";
153 return {};
154 }
155 std::vector<uint8_t> serializedToken;
156 appendUint64(serializedToken, token.challenge);
157 appendUint64(serializedToken, token.timestamp);
158 appendUint32(serializedToken, uint32_t(token.securityLevel));
159 appendUint32(serializedToken, token.mac.size());
160 serializedToken.insert(serializedToken.end(), token.mac.begin(), token.mac.end());
161 return serializedToken;
162 }
163
deserializeVerificationToken(const std::vector<uint8_t> & serializedToken)164 std::optional<VerificationToken> deserializeVerificationToken(
165 const std::vector<uint8_t>& serializedToken) {
166 if (serializedToken.size() < 24) {
167 LOG(ERROR) << "Unexpected serialized VerificationToken size " << serializedToken.size()
168 << ", expected at least 24 bytes";
169 return {};
170 }
171 VerificationToken token;
172 token.challenge = extractUint64(serializedToken, 0);
173 token.timestamp = extractUint64(serializedToken, 8);
174 token.securityLevel = SecurityLevel(extractUint32(serializedToken, 16));
175 size_t macSize = extractUint32(serializedToken, 20);
176 size_t expectedSerializedSize = 24 + macSize;
177 if (serializedToken.size() != expectedSerializedSize) {
178 LOG(ERROR) << "Unexpected serialized VerificationToken size " << serializedToken.size()
179 << ", expected " << expectedSerializedSize;
180 return {};
181 }
182 if (macSize > 0) {
183 token.mac = std::vector<uint8_t>(serializedToken.begin() + 24, serializedToken.end());
184 }
185 return token;
186 }
187
188 namespace {
189
190 constexpr char kPlatformVersionProp[] = "ro.build.version.release";
191 constexpr char kPlatformVersionRegex[] = "^([0-9]{1,2})(\\.([0-9]{1,2}))?(\\.([0-9]{1,2}))?";
192 constexpr size_t kMajorVersionMatch = 1;
193 constexpr size_t kMinorVersionMatch = 3;
194 constexpr size_t kSubminorVersionMatch = 5;
195 constexpr size_t kPlatformVersionMatchCount = kSubminorVersionMatch + 1;
196
197 constexpr char kPlatformPatchlevelProp[] = "ro.build.version.security_patch";
198 constexpr char kPlatformPatchlevelRegex[] = "^([0-9]{4})-([0-9]{2})-[0-9]{2}$";
199 constexpr size_t kYearMatch = 1;
200 constexpr size_t kMonthMatch = 2;
201 constexpr size_t kPlatformPatchlevelMatchCount = kMonthMatch + 1;
202
match_to_uint32(const char * expression,const regmatch_t & match)203 uint32_t match_to_uint32(const char* expression, const regmatch_t& match) {
204 if (match.rm_so == -1) return 0;
205
206 size_t len = match.rm_eo - match.rm_so;
207 std::string s(expression + match.rm_so, len);
208 return std::stoul(s);
209 }
210
wait_and_get_property(const char * prop)211 std::string wait_and_get_property(const char* prop) {
212 std::string prop_value;
213 while (!android::base::WaitForPropertyCreation(prop))
214 ;
215 prop_value = android::base::GetProperty(prop, "" /* default */);
216 return prop_value;
217 }
218
219 } // anonymous namespace
220
getOsVersion(const char * version_str)221 uint32_t getOsVersion(const char* version_str) {
222 regex_t regex;
223 if (regcomp(®ex, kPlatformVersionRegex, REG_EXTENDED)) {
224 return 0;
225 }
226
227 regmatch_t matches[kPlatformVersionMatchCount];
228 int not_match =
229 regexec(®ex, version_str, kPlatformVersionMatchCount, matches, 0 /* flags */);
230 regfree(®ex);
231 if (not_match) {
232 return 0;
233 }
234
235 uint32_t major = match_to_uint32(version_str, matches[kMajorVersionMatch]);
236 uint32_t minor = match_to_uint32(version_str, matches[kMinorVersionMatch]);
237 uint32_t subminor = match_to_uint32(version_str, matches[kSubminorVersionMatch]);
238
239 return (major * 100 + minor) * 100 + subminor;
240 }
241
getOsVersion()242 uint32_t getOsVersion() {
243 std::string version = wait_and_get_property(kPlatformVersionProp);
244 return getOsVersion(version.c_str());
245 }
246
getOsPatchlevel(const char * patchlevel_str)247 uint32_t getOsPatchlevel(const char* patchlevel_str) {
248 regex_t regex;
249 if (regcomp(®ex, kPlatformPatchlevelRegex, REG_EXTENDED) != 0) {
250 return 0;
251 }
252
253 regmatch_t matches[kPlatformPatchlevelMatchCount];
254 int not_match =
255 regexec(®ex, patchlevel_str, kPlatformPatchlevelMatchCount, matches, 0 /* flags */);
256 regfree(®ex);
257 if (not_match) {
258 return 0;
259 }
260
261 uint32_t year = match_to_uint32(patchlevel_str, matches[kYearMatch]);
262 uint32_t month = match_to_uint32(patchlevel_str, matches[kMonthMatch]);
263
264 if (month < 1 || month > 12) {
265 return 0;
266 }
267 return year * 100 + month;
268 }
269
getOsPatchlevel()270 uint32_t getOsPatchlevel() {
271 std::string patchlevel = wait_and_get_property(kPlatformPatchlevelProp);
272 return getOsPatchlevel(patchlevel.c_str());
273 }
274
275 } // namespace support
276 } // namespace keymaster::V4_0
277 } // namespace android::hardware
278