1 /*
2 * Copyright 2015 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 "trusty_gatekeeper.h"
18
19 #include <inttypes.h>
20 #include <trusty/time.h>
21 #include <uapi/err.h>
22
23 #include <lib/hwkey/hwkey.h>
24 #include <lib/keymaster/keymaster.h>
25 #include <lib/rng/trusty_rng.h>
26 #include <lib/storage/storage.h>
27
28 #include <openssl/hmac.h>
29
30 #define CALLS_BETWEEN_RNG_RESEEDS 32
31 #define RNG_RESEED_SIZE 64
32
33 #define HMAC_SHA_256_KEY_SIZE 32
34
35 #define GATEKEEPER_PREFIX "gatekeeper."
36
37 #define STORAGE_ID_LENGTH_MAX 64
38
39 #define MAX_FAILURE_RECORDS 10
40
41 namespace gatekeeper {
42
43 static const uint8_t DERIVATION_DATA[HMAC_SHA_256_KEY_SIZE] =
44 "TrustyGateKeeperDerivationData0";
45
TrustyGateKeeper()46 TrustyGateKeeper::TrustyGateKeeper() : GateKeeper(),
47 cached_auth_token_key_len_(0) {
48 rng_initialized_ = false;
49 calls_since_reseed_ = 0;
50 num_mem_records_ = 0;
51
52 SeedRngIfNeeded();
53 }
54
OpenSession()55 long TrustyGateKeeper::OpenSession() {
56 if (!SeedRngIfNeeded()) {
57 return ERR_NOT_READY;
58 }
59
60 return DerivePasswordKey();
61 }
62
CloseSession()63 void TrustyGateKeeper::CloseSession() {
64 ClearPasswordKey();
65 }
66
SeedRngIfNeeded()67 bool TrustyGateKeeper::SeedRngIfNeeded() {
68 if (ShouldReseedRng())
69 rng_initialized_ = ReseedRng();
70 return rng_initialized_;
71 }
72
ShouldReseedRng()73 bool TrustyGateKeeper::ShouldReseedRng() {
74 if (!rng_initialized_) {
75 return true;
76 }
77
78 if (++calls_since_reseed_ % CALLS_BETWEEN_RNG_RESEEDS == 0) {
79 return true;
80 }
81 return false;
82 }
83
ReseedRng()84 bool TrustyGateKeeper::ReseedRng() {
85 UniquePtr<uint8_t[]> rand_seed(new uint8_t[RNG_RESEED_SIZE]);
86 memset(rand_seed.get(), 0, RNG_RESEED_SIZE);
87 if (trusty_rng_secure_rand(rand_seed.get(), RNG_RESEED_SIZE) != NO_ERROR) {
88 return false;
89 }
90
91 trusty_rng_add_entropy(rand_seed.get(), RNG_RESEED_SIZE);
92 return true;
93 }
94
DerivePasswordKey()95 long TrustyGateKeeper::DerivePasswordKey() {
96 long rc = hwkey_open();
97 if (rc < 0) {
98 return rc;
99 }
100
101 hwkey_session_t session = (hwkey_session_t)rc;
102
103 password_key_.reset(new uint8_t[HMAC_SHA_256_KEY_SIZE]);
104
105 uint32_t kdf_version = HWKEY_KDF_VERSION_1;
106 rc = hwkey_derive(session, &kdf_version, DERIVATION_DATA,
107 password_key_.get(), HMAC_SHA_256_KEY_SIZE);
108
109 hwkey_close(session);
110 return rc;
111 }
112
ClearPasswordKey()113 void TrustyGateKeeper::ClearPasswordKey() {
114 memset_s(password_key_.get(), 0, HMAC_SHA_256_KEY_SIZE);
115 password_key_.reset();
116 }
117
118 /*
119 * While the GetAuthTokenKey header file says this value cannot be cached,
120 * after consulting with the GK/KM team this is incorrect - this is a per-boot
121 * key, and so in-memory caching is acceptable.
122 */
GetAuthTokenKey(const uint8_t ** auth_token_key,uint32_t * length) const123 bool TrustyGateKeeper::GetAuthTokenKey(const uint8_t** auth_token_key,
124 uint32_t* length) const {
125 *length = 0;
126 *auth_token_key = nullptr;
127
128 if (!cached_auth_token_key_) {
129 long rc = keymaster_open();
130 if (rc < 0) {
131 return false;
132 }
133
134 keymaster_session_t session = (keymaster_session_t)rc;
135
136 uint8_t* key = nullptr;
137 uint32_t local_length = 0;
138
139 rc = keymaster_get_auth_token_key(session, &key, &local_length);
140 keymaster_close(session);
141
142 if (rc == NO_ERROR) {
143 cached_auth_token_key_.reset(key);
144 cached_auth_token_key_len_ = local_length;
145 } else {
146 return false;
147 }
148 }
149
150 *auth_token_key = cached_auth_token_key_.get();
151 *length = cached_auth_token_key_len_;
152
153 return true;
154 }
155
GetPasswordKey(const uint8_t ** password_key,uint32_t * length)156 void TrustyGateKeeper::GetPasswordKey(const uint8_t** password_key,
157 uint32_t* length) {
158 *password_key = const_cast<const uint8_t*>(password_key_.get());
159 *length = HMAC_SHA_256_KEY_SIZE;
160 }
161
ComputePasswordSignature(uint8_t * signature,uint32_t signature_length,const uint8_t * key,uint32_t key_length,const uint8_t * password,uint32_t password_length,salt_t salt) const162 void TrustyGateKeeper::ComputePasswordSignature(uint8_t* signature,
163 uint32_t signature_length,
164 const uint8_t* key,
165 uint32_t key_length,
166 const uint8_t* password,
167 uint32_t password_length,
168 salt_t salt) const {
169 // todo: heap allocate
170 uint8_t salted_password[password_length + sizeof(salt)];
171 memcpy(salted_password, &salt, sizeof(salt));
172 memcpy(salted_password + sizeof(salt), password, password_length);
173 ComputeSignature(signature, signature_length, key, key_length,
174 salted_password, password_length + sizeof(salt));
175 }
176
GetRandom(void * random,uint32_t requested_size) const177 void TrustyGateKeeper::GetRandom(void* random, uint32_t requested_size) const {
178 if (random == NULL)
179 return;
180 trusty_rng_secure_rand(reinterpret_cast<uint8_t*>(random), requested_size);
181 }
182
ComputeSignature(uint8_t * signature,uint32_t signature_length,const uint8_t * key,uint32_t key_length,const uint8_t * message,const uint32_t length) const183 void TrustyGateKeeper::ComputeSignature(uint8_t* signature,
184 uint32_t signature_length,
185 const uint8_t* key,
186 uint32_t key_length,
187 const uint8_t* message,
188 const uint32_t length) const {
189 uint8_t buf[HMAC_SHA_256_KEY_SIZE];
190 unsigned int buf_len;
191
192 HMAC(EVP_sha256(), key, key_length, message, length, buf, &buf_len);
193 size_t to_write = buf_len;
194 if (buf_len > signature_length)
195 to_write = signature_length;
196 memset(signature, 0, signature_length);
197 memcpy(signature, buf, to_write);
198 }
199
GetMillisecondsSinceBoot() const200 uint64_t TrustyGateKeeper::GetMillisecondsSinceBoot() const {
201 int rc;
202 int64_t secure_time_ns = 0;
203 rc = trusty_gettime(0, &secure_time_ns);
204 if (rc != NO_ERROR) {
205 secure_time_ns = 0;
206 TLOGE("%s Error:[0x%x].\n", __func__, rc);
207 }
208 return secure_time_ns / 1000 / 1000;
209 }
210
GetSecureFailureRecord(uint32_t uid,secure_id_t user_id,failure_record_t * record)211 bool TrustyGateKeeper::GetSecureFailureRecord(uint32_t uid,
212 secure_id_t user_id,
213 failure_record_t* record) {
214 storage_session_t session;
215 int rc = storage_open_session(&session, GATEKEEPER_STORAGE_PORT);
216 if (rc < 0) {
217 TLOGE("Error: [%d] opening storage session\n", rc);
218 return false;
219 }
220
221 char id[STORAGE_ID_LENGTH_MAX];
222 memset(id, 0, sizeof(id));
223
224 file_handle_t handle;
225 snprintf(id, STORAGE_ID_LENGTH_MAX, GATEKEEPER_PREFIX "%u", uid);
226 rc = storage_open_file(session, &handle, id, 0, 0);
227 if (rc < 0) {
228 TLOGE("Error:[%d] opening storage object.\n", rc);
229 storage_close_session(session);
230 return false;
231 }
232
233 failure_record_t owner_record;
234 rc = storage_read(handle, 0, &owner_record, sizeof(owner_record));
235 storage_close_file(handle);
236 storage_close_session(session);
237
238 if (rc < 0) {
239 TLOGE("Error:[%d] reading storage object.\n", rc);
240 return false;
241 }
242
243 if ((size_t)rc < sizeof(owner_record)) {
244 TLOGE("Error: invalid object size [%d].\n", rc);
245 return false;
246 }
247
248 if (owner_record.secure_user_id != user_id) {
249 TLOGE("Error:[%" PRIu64 " != %" PRIu64 "] secure storage corrupt.\n",
250 owner_record.secure_user_id, user_id);
251 return false;
252 }
253
254 *record = owner_record;
255 return true;
256 }
257
GetFailureRecord(uint32_t uid,secure_id_t user_id,failure_record_t * record,bool secure)258 bool TrustyGateKeeper::GetFailureRecord(uint32_t uid,
259 secure_id_t user_id,
260 failure_record_t* record,
261 bool secure) {
262 if (secure) {
263 return GetSecureFailureRecord(uid, user_id, record);
264 } else {
265 return GetMemoryRecord(uid, user_id, record);
266 }
267 }
268
ClearFailureRecord(uint32_t uid,secure_id_t user_id,bool secure)269 bool TrustyGateKeeper::ClearFailureRecord(uint32_t uid,
270 secure_id_t user_id,
271 bool secure) {
272 failure_record_t record;
273 record.secure_user_id = user_id;
274 record.last_checked_timestamp = 0;
275 record.failure_counter = 0;
276 return WriteFailureRecord(uid, &record, secure);
277 }
278
WriteSecureFailureRecord(uint32_t uid,failure_record_t * record)279 bool TrustyGateKeeper::WriteSecureFailureRecord(uint32_t uid,
280 failure_record_t* record) {
281 storage_session_t session;
282 int rc = storage_open_session(&session, GATEKEEPER_STORAGE_PORT);
283 if (rc < 0) {
284 TLOGE("Error: [%d] failed to open storage session\n", rc);
285 return false;
286 }
287
288 char id[STORAGE_ID_LENGTH_MAX];
289 memset(id, 0, sizeof(id));
290 snprintf(id, STORAGE_ID_LENGTH_MAX, GATEKEEPER_PREFIX "%u", uid);
291
292 file_handle_t handle;
293 rc = storage_open_file(session, &handle, id, STORAGE_FILE_OPEN_CREATE, 0);
294 if (rc < 0) {
295 TLOGE("Error: [%d] failed to open storage object %s\n", rc, id);
296 storage_close_session(session);
297 return false;
298 }
299
300 rc = storage_write(handle, 0, record, sizeof(*record), STORAGE_OP_COMPLETE);
301 storage_close_file(handle);
302 storage_close_session(session);
303
304 if (rc < 0) {
305 TLOGE("Error:[%d] writing storage object.\n", rc);
306 return false;
307 }
308
309 if ((size_t)rc < sizeof(*record)) {
310 TLOGE("Error: invalid object size [%d].\n", rc);
311 return false;
312 }
313
314 return true;
315 }
316
WriteFailureRecord(uint32_t uid,failure_record_t * record,bool secure)317 bool TrustyGateKeeper::WriteFailureRecord(uint32_t uid,
318 failure_record_t* record,
319 bool secure) {
320 if (secure) {
321 return WriteSecureFailureRecord(uid, record);
322 } else {
323 return WriteMemoryRecord(uid, record);
324 }
325 }
326
IsHardwareBacked() const327 bool TrustyGateKeeper::IsHardwareBacked() const {
328 return true;
329 }
330
InitMemoryRecords()331 void TrustyGateKeeper::InitMemoryRecords() {
332 if (!mem_records_.get()) {
333 mem_failure_record_t* mem_recs = new mem_failure_record_t[MAX_FAILURE_RECORDS];
334 memset(mem_recs, 0, sizeof(*mem_recs));
335 mem_records_.reset(mem_recs);
336 num_mem_records_ = 0;
337 }
338 }
339
GetMemoryRecord(uint32_t uid,secure_id_t user_id,failure_record_t * record)340 bool TrustyGateKeeper::GetMemoryRecord(uint32_t uid, secure_id_t user_id,
341 failure_record_t* record) {
342 InitMemoryRecords();
343
344 for (int i = 0; i < num_mem_records_; i++) {
345 if (mem_records_[i].uid == uid) {
346 if (mem_records_[i].failure_record.secure_user_id == user_id) {
347 *record = mem_records_[i].failure_record;
348 return true;
349 }
350 TLOGE("Error:[%" PRIu64 " != %" PRIu64 "] mismatched SID for uid %u.\n",
351 mem_records_[i].failure_record.secure_user_id, user_id, uid);
352 return false;
353 }
354 }
355
356 return false;
357 }
358
WriteMemoryRecord(uint32_t uid,failure_record_t * record)359 bool TrustyGateKeeper::WriteMemoryRecord(uint32_t uid, failure_record_t* record) {
360 InitMemoryRecords();
361
362 int idx = 0;
363 int min_idx = 0;
364 uint64_t min_timestamp = ~0ULL;
365 for (idx = 0; idx < num_mem_records_; idx++) {
366 if (mem_records_[idx].uid == uid) {
367 break;
368 }
369
370 if (mem_records_[idx].failure_record.last_checked_timestamp <= min_timestamp) {
371 min_timestamp = mem_records_[idx].failure_record.last_checked_timestamp;
372 min_idx = idx;
373 }
374 }
375
376 if (idx >= MAX_FAILURE_RECORDS) {
377 // replace oldest element
378 idx = min_idx;
379 } else if (idx == num_mem_records_) {
380 num_mem_records_++;
381 }
382
383 mem_records_[idx].uid = uid;
384 mem_records_[idx].failure_record = *record;
385 return true;
386 }
387
RemoveUser(uint32_t uid)388 gatekeeper_error_t TrustyGateKeeper::RemoveUser(uint32_t uid) {
389 bool deleted = false;
390
391 // Remove from the in-memory record
392 if (mem_records_.get()) {
393 int idx = 0;
394 for (idx = 0; idx < num_mem_records_; idx++) {
395 if (mem_records_[idx].uid == uid) {
396 memset(&mem_records_[idx], 0, sizeof(mem_failure_record_t));
397 deleted = true;
398 }
399 }
400 }
401
402 storage_session_t session;
403 int rc = storage_open_session(&session, GATEKEEPER_STORAGE_PORT);
404 if (rc < 0) {
405 TLOGE("Error: [%d] opening storage session\n", rc);
406 return ERROR_UNKNOWN;
407 }
408
409 char id[STORAGE_ID_LENGTH_MAX];
410 memset(id, 0, sizeof(id));
411 snprintf(id, STORAGE_ID_LENGTH_MAX, GATEKEEPER_PREFIX "%u", uid);
412
413 rc = storage_delete_file(session, id, STORAGE_OP_COMPLETE);
414 if (rc < 0) {
415 // if the user's record was added to memory, there may not be a
416 // record in storage, so only report failures if we haven't already
417 // deleted a record from memory.
418 storage_close_session(session);
419 return deleted ? ERROR_NONE : ERROR_UNKNOWN;
420 }
421 storage_close_session(session);
422
423 return ERROR_NONE;
424 }
425
RemoveAllUsers()426 gatekeeper_error_t TrustyGateKeeper::RemoveAllUsers() {
427
428 storage_session_t session;
429 int rc = storage_open_session(&session, GATEKEEPER_STORAGE_PORT);
430 if (rc < 0) {
431 TLOGE("Error: [%d] opening storage session\n", rc);
432 return ERROR_UNKNOWN;
433 }
434
435 storage_open_dir_state *state;
436 rc = storage_open_dir(session, "", &state);
437 if (rc < 0) {
438 TLOGE("Error:[%d] opening storage dir.\n", rc);
439 storage_close_session(session);
440 return ERROR_UNKNOWN;
441 }
442 while (true) {
443 uint8_t dir_flags = 0;
444 char name[STORAGE_ID_LENGTH_MAX];
445 rc = storage_read_dir(session, state, &dir_flags, name, STORAGE_ID_LENGTH_MAX);
446 if (rc < 0) {
447 TLOGE("Error:[%d] reading storage dir.\n", rc);
448 storage_close_session(session);
449 return ERROR_UNKNOWN;
450 }
451 if ((dir_flags & STORAGE_FILE_LIST_STATE_MASK) == STORAGE_FILE_LIST_END) {
452 break;
453 }
454 if (!strncmp(name, GATEKEEPER_PREFIX, strlen(GATEKEEPER_PREFIX))) {
455 rc = storage_delete_file(session, name, 0);
456 if (rc < 0) {
457 TLOGE("Error:[%d] deleting storage object.\n", rc);
458 storage_close_session(session);
459 return ERROR_UNKNOWN;
460 }
461 }
462 }
463 storage_close_dir(session, state);
464 rc = storage_end_transaction(session, true);
465 if (rc < 0) {
466 TLOGE("Error:[%d] ending storage transaction.\n", rc);
467 storage_close_session(session);
468 return ERROR_UNKNOWN;
469 }
470 storage_close_session(session);
471
472 num_mem_records_ = 0;
473
474 return ERROR_NONE;
475 }
476
477 } // namespace gatekeeper
478