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