diff options
Diffstat (limited to 'gatekeeperd')
-rw-r--r-- | gatekeeperd/SoftGateKeeper.h | 47 | ||||
-rw-r--r-- | gatekeeperd/SoftGateKeeperDevice.h | 2 | ||||
-rw-r--r-- | gatekeeperd/gatekeeperd.cpp | 65 |
3 files changed, 106 insertions, 8 deletions
diff --git a/gatekeeperd/SoftGateKeeper.h b/gatekeeperd/SoftGateKeeper.h index e554411..75fe11d 100644 --- a/gatekeeperd/SoftGateKeeper.h +++ b/gatekeeperd/SoftGateKeeper.h @@ -20,6 +20,8 @@ extern "C" { #include <openssl/rand.h> +#include <openssl/sha.h> + #include <crypto_scrypt.h> } @@ -30,6 +32,10 @@ extern "C" { namespace gatekeeper { +struct fast_hash_t { + uint64_t salt; + uint8_t digest[SHA256_DIGEST_LENGTH]; +}; class SoftGateKeeper : public GateKeeper { public: @@ -125,9 +131,48 @@ public: return true; } + fast_hash_t ComputeFastHash(const SizedBuffer &password, uint64_t salt) { + fast_hash_t fast_hash; + size_t digest_size = password.length + sizeof(salt); + std::unique_ptr<uint8_t[]> digest(new uint8_t[digest_size]); + memcpy(digest.get(), &salt, sizeof(salt)); + memcpy(digest.get() + sizeof(salt), password.buffer.get(), password.length); + + SHA256(digest.get(), digest_size, (uint8_t *) &fast_hash.digest); + + fast_hash.salt = salt; + return fast_hash; + } + + bool VerifyFast(const fast_hash_t &fast_hash, const SizedBuffer &password) { + fast_hash_t computed = ComputeFastHash(password, fast_hash.salt); + return memcmp(computed.digest, fast_hash.digest, SHA256_DIGEST_LENGTH) == 0; + } + + bool DoVerify(const password_handle_t *expected_handle, const SizedBuffer &password) { + FastHashMap::const_iterator it = fast_hash_map_.find(expected_handle->user_id); + if (it != fast_hash_map_.end() && VerifyFast(it->second, password)) { + return true; + } else { + if (GateKeeper::DoVerify(expected_handle, password)) { + uint64_t salt; + GetRandom(&salt, sizeof(salt)); + fast_hash_map_[expected_handle->user_id] = ComputeFastHash(password, salt); + return true; + } + } + + return false; + } + private: + + typedef std::unordered_map<uint32_t, failure_record_t> FailureRecordMap; + typedef std::unordered_map<uint64_t, fast_hash_t> FastHashMap; + UniquePtr<uint8_t[]> key_; - std::unordered_map<uint32_t, failure_record_t> failure_map_; + FailureRecordMap failure_map_; + FastHashMap fast_hash_map_; }; } diff --git a/gatekeeperd/SoftGateKeeperDevice.h b/gatekeeperd/SoftGateKeeperDevice.h index 51a8511..3463c29 100644 --- a/gatekeeperd/SoftGateKeeperDevice.h +++ b/gatekeeperd/SoftGateKeeperDevice.h @@ -68,7 +68,7 @@ public: const uint8_t *provided_password, uint32_t provided_password_length, uint8_t **auth_token, uint32_t *auth_token_length, bool *request_reenroll); private: - UniquePtr<GateKeeper> impl_; + UniquePtr<SoftGateKeeper> impl_; }; } // namespace gatekeeper diff --git a/gatekeeperd/gatekeeperd.cpp b/gatekeeperd/gatekeeperd.cpp index c0f2279..f4f2cbf 100644 --- a/gatekeeperd/gatekeeperd.cpp +++ b/gatekeeperd/gatekeeperd.cpp @@ -31,6 +31,7 @@ #include <binder/IServiceManager.h> #include <binder/PermissionCache.h> #include <utils/String16.h> +#include <utils/Log.h> #include <keystore/IKeystoreService.h> #include <keystore/keystore.h> // For error code @@ -57,6 +58,13 @@ public: if (ret < 0) LOG_ALWAYS_FATAL_IF(ret < 0, "Unable to open GateKeeper HAL"); } + + if (mark_cold_boot()) { + ALOGI("cold boot: clearing state"); + if (device != NULL && device->delete_all_users != NULL) { + device->delete_all_users(device); + } + } } virtual ~GateKeeperProxy() { @@ -75,6 +83,20 @@ public: close(fd); } + bool mark_cold_boot() { + const char *filename = ".coldboot"; + if (access(filename, F_OK) == -1) { + int fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); + if (fd < 0) { + ALOGE("could not open file: %s : %s", filename, strerror(errno)); + return false; + } + close(fd); + return true; + } + return false; + } + void maybe_store_sid(uint32_t uid, uint64_t sid) { char filename[21]; sprintf(filename, "%u", uid); @@ -119,8 +141,19 @@ public: int ret; if (device) { - ret = device->enroll(device, uid, - current_password_handle, current_password_handle_length, + const gatekeeper::password_handle_t *handle = + reinterpret_cast<const gatekeeper::password_handle_t *>(current_password_handle); + + if (handle != NULL && !handle->hardware_backed) { + // handle is being re-enrolled from a software version. HAL probably won't accept + // the handle as valid, so we nullify it and enroll from scratch + current_password_handle = NULL; + current_password_handle_length = 0; + current_password = NULL; + current_password_length = 0; + } + + ret = device->enroll(device, uid, current_password_handle, current_password_handle_length, current_password, current_password_length, desired_password, desired_password_length, enrolled_password_handle, enrolled_password_handle_length); @@ -174,10 +207,26 @@ public: int ret; if (device) { - ret = device->verify(device, uid, challenge, - enrolled_password_handle, enrolled_password_handle_length, - provided_password, provided_password_length, auth_token, auth_token_length, - request_reenroll); + const gatekeeper::password_handle_t *handle = + reinterpret_cast<const gatekeeper::password_handle_t *>(enrolled_password_handle); + if (handle->hardware_backed) { + ret = device->verify(device, uid, challenge, + enrolled_password_handle, enrolled_password_handle_length, + provided_password, provided_password_length, auth_token, auth_token_length, + request_reenroll); + } else { + // upgrade scenario, a HAL has been added to this device where there was none before + SoftGateKeeperDevice soft_dev; + ret = soft_dev.verify(uid, challenge, + enrolled_password_handle, enrolled_password_handle_length, + provided_password, provided_password_length, auth_token, auth_token_length, + request_reenroll); + + if (ret == 0) { + // success! re-enroll with HAL + *request_reenroll = true; + } + } } else { ret = soft_device->verify(uid, challenge, enrolled_password_handle, enrolled_password_handle_length, @@ -221,6 +270,10 @@ public: return; } clear_sid(uid); + + if (device != NULL && device->delete_user != NULL) { + device->delete_user(device, uid); + } } virtual status_t dump(int fd, const Vector<String16> &) { |