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