diff --git a/keymaster1_engine.cpp b/keymaster1_engine.cpp
new file mode 100644
index 0000000..866a255
--- /dev/null
+++ b/keymaster1_engine.cpp
@@ -0,0 +1,415 @@
+/*
+ * 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.
+ */
+
+#include "keymaster1_engine.h"
+
+#include <assert.h>
+
+#include <algorithm>
+#include <memory>
+
+#define LOG_TAG "Keymaster1Engine"
+#include <cutils/log.h>
+
+#include "keymaster/android_keymaster_utils.h"
+
+#include <openssl/bn.h>
+#include <openssl/ec_key.h>
+#include <openssl/ecdsa.h>
+
+#include "openssl_err.h"
+#include "openssl_utils.h"
+
+using std::shared_ptr;
+using std::unique_ptr;
+
+namespace keymaster {
+
+Keymaster1Engine* Keymaster1Engine::instance_ = nullptr;
+
+Keymaster1Engine::Keymaster1Engine(const keymaster1_device_t* keymaster1_device)
+    : keymaster1_device_(keymaster1_device), engine_(ENGINE_new()),
+      rsa_index_(RSA_get_ex_new_index(0 /* argl */, NULL /* argp */, NULL /* new_func */,
+                                      Keymaster1Engine::duplicate_key_data,
+                                      Keymaster1Engine::free_key_data)),
+      ec_key_index_(EC_KEY_get_ex_new_index(0 /* argl */, NULL /* argp */, NULL /* new_func */,
+                                            Keymaster1Engine::duplicate_key_data,
+                                            Keymaster1Engine::free_key_data)),
+      rsa_method_(BuildRsaMethod()), ecdsa_method_(BuildEcdsaMethod()) {
+    assert(rsa_index_ != -1);
+    assert(ec_key_index_ != -1);
+    assert(keymaster1_device);
+    assert(!instance_);
+
+    instance_ = this;
+
+    ENGINE_set_RSA_method(engine_.get(), &rsa_method_, sizeof(rsa_method_));
+    ENGINE_set_ECDSA_method(engine_.get(), &ecdsa_method_, sizeof(ecdsa_method_));
+}
+
+Keymaster1Engine::~Keymaster1Engine() {
+    keymaster1_device_->common.close(
+        reinterpret_cast<hw_device_t*>(const_cast<keymaster1_device_t*>(keymaster1_device_)));
+    instance_ = nullptr;
+}
+
+static void ConvertCharacteristics(keymaster_key_characteristics_t* characteristics,
+                                   AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) {
+    unique_ptr<keymaster_key_characteristics_t, Characteristics_Delete> characteristics_deleter(
+        characteristics);
+    if (hw_enforced)
+        hw_enforced->Reinitialize(characteristics->hw_enforced);
+    if (sw_enforced)
+        sw_enforced->Reinitialize(characteristics->sw_enforced);
+}
+
+keymaster_error_t Keymaster1Engine::GenerateKey(const AuthorizationSet& key_description,
+                                                KeymasterKeyBlob* key_blob,
+                                                AuthorizationSet* hw_enforced,
+                                                AuthorizationSet* sw_enforced) const {
+    assert(key_blob);
+
+    keymaster_key_characteristics_t* characteristics;
+    keymaster_key_blob_t blob;
+    keymaster_error_t error = keymaster1_device_->generate_key(keymaster1_device_, &key_description,
+                                                               &blob, &characteristics);
+    if (error != KM_ERROR_OK)
+        return error;
+    unique_ptr<uint8_t, Malloc_Delete> blob_deleter(const_cast<uint8_t*>(blob.key_material));
+    key_blob->key_material = dup_buffer(blob.key_material, blob.key_material_size);
+    key_blob->key_material_size = blob.key_material_size;
+
+    ConvertCharacteristics(characteristics, hw_enforced, sw_enforced);
+    return error;
+}
+
+keymaster_error_t Keymaster1Engine::ImportKey(const AuthorizationSet& key_description,
+                                              keymaster_key_format_t input_key_material_format,
+                                              const KeymasterKeyBlob& input_key_material,
+                                              KeymasterKeyBlob* output_key_blob,
+                                              AuthorizationSet* hw_enforced,
+                                              AuthorizationSet* sw_enforced) const {
+    assert(output_key_blob);
+
+    keymaster_key_characteristics_t* characteristics;
+    const keymaster_blob_t input_key = {input_key_material.key_material,
+                                        input_key_material.key_material_size};
+    keymaster_key_blob_t blob;
+    keymaster_error_t error = keymaster1_device_->import_key(keymaster1_device_, &key_description,
+                                                             input_key_material_format, &input_key,
+                                                             &blob, &characteristics);
+    if (error != KM_ERROR_OK)
+        return error;
+    unique_ptr<uint8_t, Malloc_Delete> blob_deleter(const_cast<uint8_t*>(blob.key_material));
+    output_key_blob->key_material = dup_buffer(blob.key_material, blob.key_material_size);
+    output_key_blob->key_material_size = blob.key_material_size;
+
+    ConvertCharacteristics(characteristics, hw_enforced, sw_enforced);
+    return error;
+}
+
+RSA* Keymaster1Engine::BuildRsaKey(const KeymasterKeyBlob& blob,
+                                   const AuthorizationSet& additional_params,
+                                   keymaster_error_t* error) const {
+    // Create new RSA key (with engine methods) and add metadata
+    unique_ptr<RSA, RSA_Delete> rsa(RSA_new_method(engine_.get()));
+    if (!rsa) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    KeyData* key_data = new KeyData(blob, additional_params);
+    if (!RSA_set_ex_data(rsa.get(), rsa_index_, key_data)) {
+        *error = TranslateLastOpenSslError();
+        delete key_data;
+        return nullptr;
+    }
+
+    // Copy public key into new RSA key
+    unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(
+        GetKeymaster1PublicKey(key_data->key_material, key_data->begin_params, error));
+    if (!pkey) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    unique_ptr<RSA, RSA_Delete> public_rsa(EVP_PKEY_get1_RSA(pkey.get()));
+    if (!public_rsa) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    rsa->n = BN_dup(public_rsa->n);
+    rsa->e = BN_dup(public_rsa->e);
+    if (!rsa->n || !rsa->e) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    *error = KM_ERROR_OK;
+    return rsa.release();
+}
+
+EC_KEY* Keymaster1Engine::BuildEcKey(const KeymasterKeyBlob& blob,
+                                     const AuthorizationSet& additional_params,
+                                     keymaster_error_t* error) const {
+    // Create new EC key (with engine methods) and insert blob
+    unique_ptr<EC_KEY, EC_Delete> ec_key(EC_KEY_new_method(engine_.get()));
+    if (!ec_key) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    KeyData* key_data = new KeyData(blob, additional_params);
+    if (!EC_KEY_set_ex_data(ec_key.get(), ec_key_index_, key_data)) {
+        *error = TranslateLastOpenSslError();
+        delete key_data;
+        return nullptr;
+    }
+
+    // Copy public key into new EC key
+    unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(
+        GetKeymaster1PublicKey(blob, additional_params, error));
+    if (!pkey) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    unique_ptr<EC_KEY, EC_Delete> public_ec_key(EVP_PKEY_get1_EC_KEY(pkey.get()));
+    if (!public_ec_key) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    if (!EC_KEY_set_group(ec_key.get(), EC_KEY_get0_group(public_ec_key.get())) ||
+        !EC_KEY_set_public_key(ec_key.get(), EC_KEY_get0_public_key(public_ec_key.get()))) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    *error = KM_ERROR_OK;
+    return ec_key.release();
+}
+
+Keymaster1Engine::KeyData* Keymaster1Engine::GetData(EVP_PKEY* key) const {
+    switch (EVP_PKEY_type(key->type)) {
+    case EVP_PKEY_RSA: {
+        unique_ptr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(key));
+        return GetData(rsa.get());
+    }
+
+    case EVP_PKEY_EC: {
+        unique_ptr<EC_KEY, EC_Delete> ec_key(EVP_PKEY_get1_EC_KEY(key));
+        return GetData(ec_key.get());
+    }
+
+    default:
+        return nullptr;
+    };
+}
+
+Keymaster1Engine::KeyData* Keymaster1Engine::GetData(const RSA* rsa) const {
+    if (!rsa)
+        return nullptr;
+    return reinterpret_cast<KeyData*>(RSA_get_ex_data(rsa, rsa_index_));
+}
+
+Keymaster1Engine::KeyData* Keymaster1Engine::GetData(const EC_KEY* ec_key) const {
+    if (!ec_key)
+        return nullptr;
+    return reinterpret_cast<KeyData*>(EC_KEY_get_ex_data(ec_key, ec_key_index_));
+}
+
+/* static */
+int Keymaster1Engine::duplicate_key_data(CRYPTO_EX_DATA* /* to */, const CRYPTO_EX_DATA* /* from */,
+                                         void** from_d, int /* index */, long /* argl */,
+                                         void* /* argp */) {
+    KeyData* data = reinterpret_cast<KeyData*>(*from_d);
+    if (!data)
+        return 1;
+
+    // Default copy ctor is good.
+    *from_d = new KeyData(*data);
+    if (*from_d)
+        return 1;
+    return 0;
+}
+
+/* static */
+void Keymaster1Engine::free_key_data(void* /* parent */, void* ptr, CRYPTO_EX_DATA* /* data */,
+                                     int /* index*/, long /* argl */, void* /* argp */) {
+    delete reinterpret_cast<KeyData*>(ptr);
+}
+
+keymaster_error_t Keymaster1Engine::Keymaster1Finish(const KeyData* key_data,
+                                                     const keymaster_blob_t& input,
+                                                     keymaster_blob_t* output) {
+    if (key_data->op_handle == 0)
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    size_t input_consumed;
+    // Note: devices are required to consume all input in a single update call for undigested
+    // signing operations and encryption operations.  No need to loop here.
+    keymaster_error_t error =
+        device()->update(device(), key_data->op_handle, &key_data->finish_params, &input,
+                         &input_consumed, nullptr /* out_params */, nullptr /* output */);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    return device()->finish(device(), key_data->op_handle, &key_data->finish_params,
+                            nullptr /* signature */, nullptr /* out_params */, output);
+}
+
+/* static */
+int Keymaster1Engine::rsa_sign_raw(RSA* rsa, size_t* out_len, uint8_t* out, size_t max_out,
+                                   const uint8_t* in, size_t in_len, int padding) {
+    KeyData* key_data = instance_->GetData(rsa);
+    if (!key_data)
+        return 0;
+
+    if (padding != key_data->expected_openssl_padding) {
+        LOG_E("Expected sign_raw with padding %d but got padding %d",
+              key_data->expected_openssl_padding, padding);
+        return KM_ERROR_UNKNOWN_ERROR;
+    }
+
+    keymaster_blob_t input = {in, in_len};
+    keymaster_blob_t output;
+    key_data->error = instance_->Keymaster1Finish(key_data, input, &output);
+    if (key_data->error != KM_ERROR_OK)
+        return 0;
+    unique_ptr<uint8_t, Malloc_Delete> output_deleter(const_cast<uint8_t*>(output.data));
+
+    *out_len = std::min(output.data_length, max_out);
+    memcpy(out, output.data, *out_len);
+    return 1;
+}
+
+/* static */
+int Keymaster1Engine::rsa_decrypt(RSA* rsa, size_t* out_len, uint8_t* out, size_t max_out,
+                                  const uint8_t* in, size_t in_len, int padding) {
+    KeyData* key_data = instance_->GetData(rsa);
+    if (!key_data)
+        return 0;
+
+    if (padding != key_data->expected_openssl_padding) {
+        LOG_E("Expected sign_raw with padding %d but got padding %d",
+              key_data->expected_openssl_padding, padding);
+        return KM_ERROR_UNKNOWN_ERROR;
+    }
+
+    keymaster_blob_t input = {in, in_len};
+    keymaster_blob_t output;
+    key_data->error = instance_->Keymaster1Finish(key_data, input, &output);
+    if (key_data->error != KM_ERROR_OK)
+        return 0;
+    unique_ptr<uint8_t, Malloc_Delete> output_deleter(const_cast<uint8_t*>(output.data));
+
+    *out_len = std::min(output.data_length, max_out);
+    memcpy(out, output.data, *out_len);
+    return 1;
+}
+
+/* static */
+int Keymaster1Engine::ecdsa_sign(const uint8_t* digest, size_t digest_len, uint8_t* sig,
+                                 unsigned int* sig_len, EC_KEY* ec_key) {
+    KeyData* key_data = instance_->GetData(ec_key);
+    if (!key_data)
+        return 0;
+
+    // Truncate digest if it's too long
+    size_t max_input_len = (ec_group_size_bits(ec_key) + 7) / 8;
+    if (digest_len > max_input_len)
+        digest_len = max_input_len;
+
+    keymaster_blob_t input = {digest, digest_len};
+    keymaster_blob_t output;
+    key_data->error = instance_->Keymaster1Finish(key_data, input, &output);
+    if (key_data->error != KM_ERROR_OK)
+        return 0;
+    unique_ptr<uint8_t, Malloc_Delete> output_deleter(const_cast<uint8_t*>(output.data));
+
+    *sig_len = std::min(output.data_length, ECDSA_size(ec_key));
+    memcpy(sig, output.data, *sig_len);
+    return 1;
+}
+
+EVP_PKEY* Keymaster1Engine::GetKeymaster1PublicKey(const KeymasterKeyBlob& blob,
+                                                   const AuthorizationSet& additional_params,
+                                                   keymaster_error_t* error) const {
+    keymaster_blob_t client_id = {nullptr, 0};
+    keymaster_blob_t app_data = {nullptr, 0};
+    keymaster_blob_t* client_id_ptr = nullptr;
+    keymaster_blob_t* app_data_ptr = nullptr;
+    if (additional_params.GetTagValue(TAG_APPLICATION_ID, &client_id))
+        client_id_ptr = &client_id;
+    if (additional_params.GetTagValue(TAG_APPLICATION_DATA, &app_data))
+        app_data_ptr = &app_data;
+
+    keymaster_blob_t export_data = {nullptr, 0};
+    *error = keymaster1_device_->export_key(keymaster1_device_, KM_KEY_FORMAT_X509, &blob,
+                                            client_id_ptr, app_data_ptr, &export_data);
+    if (*error != KM_ERROR_OK)
+        return nullptr;
+
+    unique_ptr<uint8_t, Malloc_Delete> pub_key(const_cast<uint8_t*>(export_data.data));
+
+    const uint8_t* p = export_data.data;
+    return d2i_PUBKEY(nullptr /* allocate new struct */, &p, export_data.data_length);
+}
+
+RSA_METHOD Keymaster1Engine::BuildRsaMethod() {
+    RSA_METHOD method;
+
+    method.common.references = 0;
+    method.common.is_static = 1;
+    method.app_data = nullptr;
+    method.init = nullptr;
+    method.finish = nullptr;
+    method.size = nullptr;
+    method.sign = nullptr;
+    method.verify = nullptr;
+    method.encrypt = nullptr;
+    method.sign_raw = Keymaster1Engine::rsa_sign_raw;
+    method.decrypt = Keymaster1Engine::rsa_decrypt;
+    method.verify_raw = nullptr;
+    method.private_transform = nullptr;
+    method.mod_exp = nullptr;
+    method.bn_mod_exp = BN_mod_exp_mont;
+    method.flags = RSA_FLAG_OPAQUE;
+    method.keygen = nullptr;
+    method.supports_digest = nullptr;
+
+    return method;
+}
+
+ECDSA_METHOD Keymaster1Engine::BuildEcdsaMethod() {
+    ECDSA_METHOD method;
+
+    method.common.references = 0;
+    method.common.is_static = 1;
+    method.app_data = nullptr;
+    method.init = nullptr;
+    method.finish = nullptr;
+    method.group_order_size = nullptr;
+    method.sign = Keymaster1Engine::ecdsa_sign;
+    method.verify = nullptr;
+    method.flags = ECDSA_FLAG_OPAQUE;
+
+    return method;
+}
+
+}  // namespace keymaster
