summaryrefslogtreecommitdiff
authorTellen Yu <tellen.yu@amlogic.com>2017-09-06 07:29:57 (GMT)
committer Tellen Yu <tellen.yu@amlogic.com>2017-09-06 07:38:30 (GMT)
commit125f7bb3eef36d9d9c96f8048e70f84c4a764d21 (patch)
treed573bf504e6a71961da71a803aad5c8167870d83
parentc029e9fb2ea8d2bf8d5bf3db9c3a2fc4ae8c5eaf (diff)
downloadgatekeeper-125f7bb3eef36d9d9c96f8048e70f84c4a764d21.zip
gatekeeper-125f7bb3eef36d9d9c96f8048e70f84c4a764d21.tar.gz
gatekeeper-125f7bb3eef36d9d9c96f8048e70f84c4a764d21.tar.bz2
VTS: use software gatekeeper instead of trusty [1/1]
PD# NONE use software gatekeeper simulate hardware gatekeeper, because, our platform don't use it Change-Id: Idbe7f7aac2b2606bae8e5d5d5e949d7b0eeb96f1
Diffstat
-rw-r--r--Android.mk20
-rw-r--r--GKPModule.cpp (renamed from module.cpp)26
-rw-r--r--soft/SoftGateKeeper.h182
-rw-r--r--soft/SoftGateKeeperDevice.cpp (copied from trusty_gatekeeper.cpp)147
-rw-r--r--soft/SoftGateKeeperDevice.h93
-rw-r--r--trusty/gatekeeper_ipc.h (renamed from gatekeeper_ipc.h)0
-rw-r--r--trusty/trusty_gatekeeper.cpp (renamed from trusty_gatekeeper.cpp)0
-rw-r--r--trusty/trusty_gatekeeper.h (renamed from trusty_gatekeeper.h)0
-rw-r--r--trusty/trusty_gatekeeper_ipc.c (renamed from trusty_gatekeeper_ipc.c)0
-rw-r--r--trusty/trusty_gatekeeper_ipc.h (renamed from trusty_gatekeeper_ipc.h)0
10 files changed, 354 insertions, 114 deletions
diff --git a/Android.mk b/Android.mk
index ad5ca02..dc0165b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -29,9 +29,16 @@ LOCAL_MODULE := gatekeeper.amlogic
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_SRC_FILES := \
- module.cpp \
- trusty_gatekeeper_ipc.c \
- trusty_gatekeeper.cpp
+ GKPModule.cpp \
+ trusty/trusty_gatekeeper_ipc.c \
+ trusty/trusty_gatekeeper.cpp \
+ soft/SoftGateKeeperDevice.cpp
+
+LOCAL_STATIC_LIBRARIES := libscrypt_static
+LOCAL_C_INCLUDES := \
+ external/boringssl/src/include/ \
+ external/scrypt/lib/crypto \
+ system/core/base/include
LOCAL_CLFAGS = -fvisibility=hidden -Wall -Werror
@@ -39,8 +46,13 @@ LOCAL_SHARED_LIBRARIES := \
libgatekeeper \
liblog \
libcutils \
- libtrusty
+ libtrusty \
+ libcrypto
LOCAL_MODULE_TAGS := optional
+ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK)
+LOCAL_PROPRIETARY_MODULE := true
+endif
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/module.cpp b/GKPModule.cpp
index 0ee3c2f..15ed4d8 100644
--- a/module.cpp
+++ b/GKPModule.cpp
@@ -20,26 +20,36 @@
#include <errno.h>
#include <stdlib.h>
-#include "trusty_gatekeeper.h"
+#include "trusty/trusty_gatekeeper.h"
+#include "soft/SoftGateKeeperDevice.h"
using gatekeeper::TrustyGateKeeperDevice;
+using android::SoftGateKeeperDevice;
-static int trusty_gatekeeper_open(const hw_module_t *module, const char *name,
+static int gatekeeper_open(const hw_module_t *module, const char *name,
hw_device_t **device) {
if (strcmp(name, HARDWARE_GATEKEEPER) != 0) {
return -EINVAL;
}
- TrustyGateKeeperDevice *gatekeeper = new TrustyGateKeeperDevice(module);
- if (gatekeeper == NULL) return -ENOMEM;
- *device = gatekeeper->hw_device();
+ //trusty gatekeeper don't implement, so use software instead of
+ if (true) {
+ SoftGateKeeperDevice *gatekeeper = new SoftGateKeeperDevice(module);
+ if (gatekeeper == NULL) return -ENOMEM;
+ *device = gatekeeper->sw_device();
+ }
+ else {
+ TrustyGateKeeperDevice *gatekeeper = new TrustyGateKeeperDevice(module);
+ if (gatekeeper == NULL) return -ENOMEM;
+ *device = gatekeeper->hw_device();
+ }
return 0;
}
static struct hw_module_methods_t gatekeeper_module_methods = {
- .open = trusty_gatekeeper_open,
+ .open = gatekeeper_open,
};
struct gatekeeper_module HAL_MODULE_INFO_SYM __attribute__((visibility("default"))) = {
@@ -48,8 +58,8 @@ struct gatekeeper_module HAL_MODULE_INFO_SYM __attribute__((visibility("default"
.module_api_version = GATEKEEPER_MODULE_API_VERSION_0_1,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = GATEKEEPER_HARDWARE_MODULE_ID,
- .name = "Trusty GateKeeper HAL",
- .author = "The Android Open Source Project",
+ .name = "AML GateKeeper HAL",
+ .author = "aml",
.methods = &gatekeeper_module_methods,
.dso = 0,
.reserved = {}
diff --git a/soft/SoftGateKeeper.h b/soft/SoftGateKeeper.h
new file mode 100644
index 0000000..cb02a6f
--- a/dev/null
+++ b/soft/SoftGateKeeper.h
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef SOFT_GATEKEEPER_H_
+#define SOFT_GATEKEEPER_H_
+
+extern "C" {
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+#include <crypto_scrypt.h>
+}
+
+#include <android-base/memory.h>
+#include <UniquePtr.h>
+#include <gatekeeper/gatekeeper.h>
+
+#include <iostream>
+#include <unordered_map>
+
+namespace gatekeeper {
+
+struct fast_hash_t {
+ uint64_t salt;
+ uint8_t digest[SHA256_DIGEST_LENGTH];
+};
+
+class SoftGateKeeper : public GateKeeper {
+public:
+ static const uint32_t SIGNATURE_LENGTH_BYTES = 32;
+
+ // scrypt params
+ static const uint64_t N = 16384;
+ static const uint32_t r = 8;
+ static const uint32_t p = 1;
+
+ static const int MAX_UINT_32_CHARS = 11;
+
+ SoftGateKeeper() {
+ key_.reset(new uint8_t[SIGNATURE_LENGTH_BYTES]);
+ memset(key_.get(), 0, SIGNATURE_LENGTH_BYTES);
+ }
+
+ virtual ~SoftGateKeeper() {
+ }
+
+ virtual bool GetAuthTokenKey(const uint8_t **auth_token_key,
+ uint32_t *length) const {
+ if (auth_token_key == NULL || length == NULL) return false;
+ uint8_t *auth_token_key_copy = new uint8_t[SIGNATURE_LENGTH_BYTES];
+ memcpy(auth_token_key_copy, key_.get(), SIGNATURE_LENGTH_BYTES);
+
+ *auth_token_key = auth_token_key_copy;
+ *length = SIGNATURE_LENGTH_BYTES;
+ return true;
+ }
+
+ virtual void GetPasswordKey(const uint8_t **password_key, uint32_t *length) {
+ if (password_key == NULL || length == NULL) return;
+ uint8_t *password_key_copy = new uint8_t[SIGNATURE_LENGTH_BYTES];
+ memcpy(password_key_copy, key_.get(), SIGNATURE_LENGTH_BYTES);
+
+ *password_key = password_key_copy;
+ *length = SIGNATURE_LENGTH_BYTES;
+ }
+
+ virtual void ComputePasswordSignature(uint8_t *signature, uint32_t signature_length,
+ const uint8_t *, uint32_t, const uint8_t *password,
+ uint32_t password_length, salt_t salt) const {
+ if (signature == NULL) return;
+ crypto_scrypt(password, password_length, reinterpret_cast<uint8_t *>(&salt),
+ sizeof(salt), N, r, p, signature, signature_length);
+ }
+
+ virtual void GetRandom(void *random, uint32_t requested_length) const {
+ if (random == NULL) return;
+ RAND_pseudo_bytes((uint8_t *) random, requested_length);
+ }
+
+ virtual void ComputeSignature(uint8_t *signature, uint32_t signature_length,
+ const uint8_t *, uint32_t, const uint8_t *, const uint32_t) const {
+ if (signature == NULL) return;
+ memset(signature, 0, signature_length);
+ }
+
+ virtual uint64_t GetMillisecondsSinceBoot() const {
+ struct timespec time;
+ int res = clock_gettime(CLOCK_BOOTTIME, &time);
+ if (res < 0) return 0;
+ return (time.tv_sec * 1000) + (time.tv_nsec / 1000 / 1000);
+ }
+
+ virtual bool IsHardwareBacked() const {
+ return false;
+ }
+
+ virtual bool GetFailureRecord(uint32_t uid, secure_id_t user_id, failure_record_t *record,
+ bool /* secure */) {
+ failure_record_t *stored = &failure_map_[uid];
+ if (user_id != stored->secure_user_id) {
+ stored->secure_user_id = user_id;
+ stored->last_checked_timestamp = 0;
+ stored->failure_counter = 0;
+ }
+ memcpy(record, stored, sizeof(*record));
+ return true;
+ }
+
+ virtual bool ClearFailureRecord(uint32_t uid, secure_id_t user_id, bool /* secure */) {
+ failure_record_t *stored = &failure_map_[uid];
+ stored->secure_user_id = user_id;
+ stored->last_checked_timestamp = 0;
+ stored->failure_counter = 0;
+ return true;
+ }
+
+ virtual bool WriteFailureRecord(uint32_t uid, failure_record_t *record, bool /* secure */) {
+ failure_map_[uid] = *record;
+ 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) {
+ uint64_t user_id = android::base::get_unaligned<secure_id_t>(&expected_handle->user_id);
+ FastHashMap::const_iterator it = fast_hash_map_.find(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_[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_;
+ FailureRecordMap failure_map_;
+ FastHashMap fast_hash_map_;
+};
+}
+
+#endif // SOFT_GATEKEEPER_H_
diff --git a/trusty_gatekeeper.cpp b/soft/SoftGateKeeperDevice.cpp
index b3fbfa9..ea52688 100644
--- a/trusty_gatekeeper.cpp
+++ b/soft/SoftGateKeeperDevice.cpp
@@ -14,80 +14,50 @@
* limitations under the License.
*/
-#define LOG_TAG "TrustyGateKeeper"
-
#include <assert.h>
#include <errno.h>
#include <stdio.h>
+#include "SoftGateKeeper.h"
+#include "SoftGateKeeperDevice.h"
-#include <type_traits>
-
-#include <log/log.h>
-
-#include "trusty_gatekeeper.h"
-#include "trusty_gatekeeper_ipc.h"
-#include "gatekeeper_ipc.h"
-
-namespace gatekeeper {
-
-const uint32_t SEND_BUF_SIZE = 8192;
-const uint32_t RECV_BUF_SIZE = 8192;
-
-TrustyGateKeeperDevice::TrustyGateKeeperDevice(const hw_module_t *module) {
-#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
- static_assert(std::is_standard_layout<TrustyGateKeeperDevice>::value,
- "TrustyGateKeeperDevice must be standard layout");
- static_assert(offsetof(TrustyGateKeeperDevice, device_) == 0,
- "device_ must be the first member of TrustyGateKeeperDevice");
- static_assert(offsetof(TrustyGateKeeperDevice, device_.common) == 0,
- "common must be the first member of gatekeeper_device");
-#else
- assert(reinterpret_cast<gatekeeper_device_t *>(this) == &device_);
- assert(reinterpret_cast<hw_device_t *>(this) == &(device_.common));
-#endif
-
- memset(&device_, 0, sizeof(device_));
- device_.common.tag = HARDWARE_DEVICE_TAG;
- device_.common.version = 1;
- device_.common.module = const_cast<hw_module_t *>(module);
- device_.common.close = close_device;
-
- device_.enroll = enroll;
- device_.verify = verify;
- device_.delete_user = nullptr;
- device_.delete_all_users = nullptr;
-
- int rc = trusty_gatekeeper_connect();
- if (rc < 0) {
- ALOGE("Error initializing trusty session: %d", rc);
- }
+namespace android {
- error_ = rc;
+SoftGateKeeperDevice::SoftGateKeeperDevice(const hw_module_t *module) {
+ assert(reinterpret_cast<gatekeeper_device_t *>(this) == &deviceSoft);
+ assert(reinterpret_cast<hw_device_t *>(this) == &(deviceSoft.common));
-}
+ memset(&deviceSoft, 0, sizeof(deviceSoft));
+ deviceSoft.common.tag = HARDWARE_DEVICE_TAG;
+ deviceSoft.common.version = 1;
+ deviceSoft.common.module = const_cast<hw_module_t *>(module);
+ deviceSoft.common.close = close_device;
-hw_device_t* TrustyGateKeeperDevice::hw_device() {
- return &device_.common;
+ deviceSoft.enroll = enroll;
+ deviceSoft.verify = verify;
+ deviceSoft.delete_user = nullptr;
+ deviceSoft.delete_all_users = nullptr;
+
+ implSoft.reset(new SoftGateKeeper());
}
-int TrustyGateKeeperDevice::close_device(hw_device_t* dev) {
- delete reinterpret_cast<TrustyGateKeeperDevice *>(dev);
+int SoftGateKeeperDevice::close_device(hw_device_t* dev) {
+ delete reinterpret_cast<SoftGateKeeperDevice *>(dev);
return 0;
}
-TrustyGateKeeperDevice::~TrustyGateKeeperDevice() {
- trusty_gatekeeper_disconnect();
+SoftGateKeeperDevice::~SoftGateKeeperDevice() {
+
}
-int TrustyGateKeeperDevice::Enroll(uint32_t uid, const uint8_t *current_password_handle,
- uint32_t current_password_handle_length, const uint8_t *current_password,
- uint32_t current_password_length, const uint8_t *desired_password,
- uint32_t desired_password_length, uint8_t **enrolled_password_handle,
- uint32_t *enrolled_password_handle_length) {
+hw_device_t* SoftGateKeeperDevice::sw_device() {
+ return &deviceSoft.common;
+}
- if (error_ != 0) {
- return error_;
- }
+int SoftGateKeeperDevice::Enroll(uint32_t uid,
+ const uint8_t *current_password_handle, uint32_t current_password_handle_length,
+ const uint8_t *current_password, uint32_t current_password_length,
+ const uint8_t *desired_password, uint32_t desired_password_length,
+ uint8_t **enrolled_password_handle, uint32_t *enrolled_password_handle_length) {
SizedBuffer desired_password_buffer(desired_password_length);
memcpy(desired_password_buffer.buffer.get(), desired_password, desired_password_length);
@@ -107,28 +77,24 @@ int TrustyGateKeeperDevice::Enroll(uint32_t uid, const uint8_t *current_password
&current_password_buffer);
EnrollResponse response;
- gatekeeper_error_t error = Send(request, &response);
+ implSoft->Enroll(request, &response);
- if (error == ERROR_RETRY) {
+ if (response.error == ERROR_RETRY) {
return response.retry_timeout;
- } else if (error != ERROR_NONE) {
+ } else if (response.error != ERROR_NONE) {
return -EINVAL;
}
*enrolled_password_handle = response.enrolled_password_handle.buffer.release();
*enrolled_password_handle_length = response.enrolled_password_handle.length;
-
-
return 0;
}
-int TrustyGateKeeperDevice::Verify(uint32_t uid, uint64_t challenge,
- const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length,
- const uint8_t *provided_password, uint32_t provided_password_length,
- uint8_t **auth_token, uint32_t *auth_token_length, bool *request_reenroll) {
- if (error_ != 0) {
- return error_;
- }
+int SoftGateKeeperDevice::Verify(uint32_t uid,
+ uint64_t challenge, const uint8_t *enrolled_password_handle,
+ uint32_t enrolled_password_handle_length, const uint8_t *provided_password,
+ uint32_t provided_password_length, uint8_t **auth_token, uint32_t *auth_token_length,
+ bool *request_reenroll) {
SizedBuffer password_handle_buffer(enrolled_password_handle_length);
memcpy(password_handle_buffer.buffer.get(), enrolled_password_handle,
@@ -139,11 +105,11 @@ int TrustyGateKeeperDevice::Verify(uint32_t uid, uint64_t challenge,
VerifyRequest request(uid, challenge, &password_handle_buffer, &provided_password_buffer);
VerifyResponse response;
- gatekeeper_error_t error = Send(request, &response);
+ implSoft->Verify(request, &response);
- if (error == ERROR_RETRY) {
+ if (response.error == ERROR_RETRY) {
return response.retry_timeout;
- } else if (error != ERROR_NONE) {
+ } else if (response.error != ERROR_NONE) {
return -EINVAL;
}
@@ -159,35 +125,12 @@ int TrustyGateKeeperDevice::Verify(uint32_t uid, uint64_t challenge,
return 0;
}
-gatekeeper_error_t TrustyGateKeeperDevice::Send(uint32_t command, const GateKeeperMessage& request,
- GateKeeperMessage *response) {
- uint32_t request_size = request.GetSerializedSize();
- if (request_size > SEND_BUF_SIZE)
- return ERROR_INVALID;
- uint8_t send_buf[SEND_BUF_SIZE];
- request.Serialize(send_buf, send_buf + request_size);
-
- // Send it
- uint8_t recv_buf[RECV_BUF_SIZE];
- uint32_t response_size = RECV_BUF_SIZE;
- int rc = trusty_gatekeeper_call(command, send_buf, request_size, recv_buf, &response_size);
- if (rc < 0) {
- ALOGE("error (%d) calling gatekeeper TA", rc);
- return ERROR_INVALID;
- }
-
- const gatekeeper_message *msg = reinterpret_cast<gatekeeper_message *>(recv_buf);
- const uint8_t *payload = msg->payload;
-
- return response->Deserialize(payload, payload + response_size);
-}
-
-static inline TrustyGateKeeperDevice *convert_device(const gatekeeper_device *dev) {
- return reinterpret_cast<TrustyGateKeeperDevice *>(const_cast<gatekeeper_device *>(dev));
+static inline SoftGateKeeperDevice *convert_device(const gatekeeper_device *dev) {
+ return reinterpret_cast<SoftGateKeeperDevice *>(const_cast<gatekeeper_device *>(dev));
}
/* static */
-int TrustyGateKeeperDevice::enroll(const struct gatekeeper_device *dev, uint32_t uid,
+int SoftGateKeeperDevice::enroll(const struct gatekeeper_device *dev, uint32_t uid,
const uint8_t *current_password_handle, uint32_t current_password_handle_length,
const uint8_t *current_password, uint32_t current_password_length,
const uint8_t *desired_password, uint32_t desired_password_length,
@@ -214,7 +157,7 @@ int TrustyGateKeeperDevice::enroll(const struct gatekeeper_device *dev, uint32_t
}
/* static */
-int TrustyGateKeeperDevice::verify(const struct gatekeeper_device *dev, uint32_t uid,
+int SoftGateKeeperDevice::verify(const struct gatekeeper_device *dev, uint32_t uid,
uint64_t challenge, const uint8_t *enrolled_password_handle,
uint32_t enrolled_password_handle_length, const uint8_t *provided_password,
uint32_t provided_password_length, uint8_t **auth_token, uint32_t *auth_token_length,
@@ -229,4 +172,4 @@ int TrustyGateKeeperDevice::verify(const struct gatekeeper_device *dev, uint32_t
enrolled_password_handle_length, provided_password, provided_password_length,
auth_token, auth_token_length, request_reenroll);
}
-};
+} // namespace android
diff --git a/soft/SoftGateKeeperDevice.h b/soft/SoftGateKeeperDevice.h
new file mode 100644
index 0000000..ae71b8c
--- a/dev/null
+++ b/soft/SoftGateKeeperDevice.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SOFT_GATEKEEPER_DEVICE_H_
+#define SOFT_GATEKEEPER_DEVICE_H_
+
+#include <hardware/gatekeeper.h>
+#include "SoftGateKeeper.h"
+
+#include <UniquePtr.h>
+
+using namespace gatekeeper;
+
+namespace android {
+
+/**
+ * Software based GateKeeper implementation
+ */
+class SoftGateKeeperDevice {
+public:
+ SoftGateKeeperDevice(const hw_module_t *module);
+ ~SoftGateKeeperDevice();
+
+ hw_device_t* sw_device();
+
+ // Wrappers to translate the gatekeeper HAL API to the Kegyuard Messages API.
+
+ /**
+ * Enrolls password_payload, which should be derived from a user selected pin or password,
+ * with the authentication factor private key used only for enrolling authentication
+ * factor data.
+ *
+ * Returns: 0 on success or an error code less than 0 on error.
+ * On error, enrolled_password_handle will not be allocated.
+ */
+ int Enroll(uint32_t uid,
+ const uint8_t *current_password_handle, uint32_t current_password_handle_length,
+ const uint8_t *current_password, uint32_t current_password_length,
+ const uint8_t *desired_password, uint32_t desired_password_length,
+ uint8_t **enrolled_password_handle, uint32_t *enrolled_password_handle_length);
+
+ /**
+ * Verifies provided_password matches enrolled_password_handle.
+ *
+ * Implementations of this module may retain the result of this call
+ * to attest to the recency of authentication.
+ *
+ * On success, writes the address of a verification token to auth_token,
+ * usable to attest password verification to other trusted services. Clients
+ * may pass NULL for this value.
+ *
+ * Returns: 0 on success or an error code less than 0 on error
+ * On error, verification token will not be allocated
+ */
+ int Verify(uint32_t uid, uint64_t challenge,
+ const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length,
+ const uint8_t *provided_password, uint32_t provided_password_length,
+ uint8_t **auth_token, uint32_t *auth_token_length, bool *request_reenroll);
+
+ static int enroll(const struct gatekeeper_device *dev, uint32_t uid,
+ const uint8_t *current_password_handle, uint32_t current_password_handle_length,
+ const uint8_t *current_password, uint32_t current_password_length,
+ const uint8_t *desired_password, uint32_t desired_password_length,
+ uint8_t **enrolled_password_handle, uint32_t *enrolled_password_handle_length);
+
+ static int verify(const struct gatekeeper_device *dev, uint32_t uid, uint64_t challenge,
+ const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length,
+ const uint8_t *provided_password, uint32_t provided_password_length,
+ uint8_t **auth_token, uint32_t *auth_token_length, bool *request_reenroll);
+
+ static int close_device(hw_device_t* dev);
+
+ gatekeeper_device deviceSoft;
+private:
+ UniquePtr<SoftGateKeeper> implSoft;
+};
+
+} // namespace gatekeeper
+
+#endif //SOFT_GATEKEEPER_DEVICE_H_
diff --git a/gatekeeper_ipc.h b/trusty/gatekeeper_ipc.h
index b05dcd8..b05dcd8 100644
--- a/gatekeeper_ipc.h
+++ b/trusty/gatekeeper_ipc.h
diff --git a/trusty_gatekeeper.cpp b/trusty/trusty_gatekeeper.cpp
index b3fbfa9..b3fbfa9 100644
--- a/trusty_gatekeeper.cpp
+++ b/trusty/trusty_gatekeeper.cpp
diff --git a/trusty_gatekeeper.h b/trusty/trusty_gatekeeper.h
index 2becc49..2becc49 100644
--- a/trusty_gatekeeper.h
+++ b/trusty/trusty_gatekeeper.h
diff --git a/trusty_gatekeeper_ipc.c b/trusty/trusty_gatekeeper_ipc.c
index f67944b..f67944b 100644
--- a/trusty_gatekeeper_ipc.c
+++ b/trusty/trusty_gatekeeper_ipc.c
diff --git a/trusty_gatekeeper_ipc.h b/trusty/trusty_gatekeeper_ipc.h
index f8de7f8..f8de7f8 100644
--- a/trusty_gatekeeper_ipc.h
+++ b/trusty/trusty_gatekeeper_ipc.h