diff --git a/microdroid/keymint/MicrodroidKeyMintDevice.cpp b/microdroid/keymint/MicrodroidKeyMintDevice.cpp
new file mode 100644
index 0000000..62d6942
--- /dev/null
+++ b/microdroid/keymint/MicrodroidKeyMintDevice.cpp
@@ -0,0 +1,472 @@
+/*
+ * Copyright 2021, 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.
+ */
+
+#define LOG_TAG "android.hardware.security.keymint-impl"
+#include "MicrodroidKeyMintDevice.h"
+
+#include <aidl/android/hardware/security/keymint/ErrorCode.h>
+#include <android-base/logging.h>
+#include <keymaster/android_keymaster.h>
+#include <keymaster/contexts/pure_soft_keymaster_context.h>
+#include <keymaster/keymaster_configuration.h>
+
+#include "AndroidKeyMintOperation.h"
+#include "KeyMintUtils.h"
+
+namespace aidl::android::hardware::security::keymint {
+
+using namespace keymaster; // NOLINT(google-build-using-namespace)
+
+using km_utils::authToken2AidlVec;
+using km_utils::kmBlob2vector;
+using km_utils::kmError2ScopedAStatus;
+using km_utils::kmParam2Aidl;
+using km_utils::KmParamSet;
+using km_utils::kmParamSet2Aidl;
+using km_utils::legacy_enum_conversion;
+using secureclock::TimeStampToken;
+
+namespace {
+
+vector<KeyCharacteristics> convertKeyCharacteristics(SecurityLevel keyMintSecurityLevel,
+                                                     const AuthorizationSet& requestParams,
+                                                     const AuthorizationSet& sw_enforced,
+                                                     const AuthorizationSet& hw_enforced,
+                                                     bool include_keystore_enforced = true) {
+    KeyCharacteristics keyMintEnforced{keyMintSecurityLevel, {}};
+
+    if (keyMintSecurityLevel != SecurityLevel::SOFTWARE) {
+        // We're pretending to be TRUSTED_ENVIRONMENT or STRONGBOX.
+        keyMintEnforced.authorizations = kmParamSet2Aidl(hw_enforced);
+        if (include_keystore_enforced) {
+            // Put all the software authorizations in the keystore list.
+            KeyCharacteristics keystoreEnforced{SecurityLevel::KEYSTORE,
+                                                kmParamSet2Aidl(sw_enforced)};
+            return {std::move(keyMintEnforced), std::move(keystoreEnforced)};
+        } else {
+            return {std::move(keyMintEnforced)};
+        }
+    }
+
+    KeyCharacteristics keystoreEnforced{SecurityLevel::KEYSTORE, {}};
+    CHECK(hw_enforced.empty()) << "Hardware-enforced list is non-empty for pure SW KeyMint";
+
+    // This is a pure software implementation, so all tags are in sw_enforced.
+    // We need to walk through the SW-enforced list and figure out which tags to
+    // return in the software list and which in the keystore list.
+
+    for (auto& entry : sw_enforced) {
+        switch (entry.tag) {
+            /* Invalid and unused */
+            case KM_TAG_ECIES_SINGLE_HASH_MODE:
+            case KM_TAG_INVALID:
+            case KM_TAG_KDF:
+            case KM_TAG_ROLLBACK_RESISTANCE:
+                CHECK(false) << "We shouldn't see tag " << entry.tag;
+                break;
+
+            /* Unimplemented */
+            case KM_TAG_ALLOW_WHILE_ON_BODY:
+            case KM_TAG_BOOTLOADER_ONLY:
+            case KM_TAG_EARLY_BOOT_ONLY:
+            case KM_TAG_ROLLBACK_RESISTANT:
+            case KM_TAG_STORAGE_KEY:
+            case KM_TAG_TRUSTED_CONFIRMATION_REQUIRED:
+            case KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED:
+                break;
+
+            /* Keystore-enforced if not locally generated. */
+            case KM_TAG_CREATION_DATETIME:
+                // A KeyMaster implementation is required to add this tag to generated/imported
+                // keys. A KeyMint implementation is not required to create this tag, only to echo
+                // it back if it was included in the key generation/import request.
+                if (requestParams.Contains(KM_TAG_CREATION_DATETIME)) {
+                    keystoreEnforced.authorizations.push_back(kmParam2Aidl(entry));
+                }
+                break;
+
+            /* Disallowed in KeyCharacteristics */
+            case KM_TAG_APPLICATION_DATA:
+            case KM_TAG_ATTESTATION_APPLICATION_ID:
+                break;
+
+            /* Not key characteristics */
+            case KM_TAG_ASSOCIATED_DATA:
+            case KM_TAG_ATTESTATION_CHALLENGE:
+            case KM_TAG_ATTESTATION_ID_BRAND:
+            case KM_TAG_ATTESTATION_ID_DEVICE:
+            case KM_TAG_ATTESTATION_ID_IMEI:
+            case KM_TAG_ATTESTATION_ID_MANUFACTURER:
+            case KM_TAG_ATTESTATION_ID_MEID:
+            case KM_TAG_ATTESTATION_ID_MODEL:
+            case KM_TAG_ATTESTATION_ID_PRODUCT:
+            case KM_TAG_ATTESTATION_ID_SERIAL:
+            case KM_TAG_AUTH_TOKEN:
+            case KM_TAG_CERTIFICATE_SERIAL:
+            case KM_TAG_CERTIFICATE_SUBJECT:
+            case KM_TAG_CERTIFICATE_NOT_AFTER:
+            case KM_TAG_CERTIFICATE_NOT_BEFORE:
+            case KM_TAG_CONFIRMATION_TOKEN:
+            case KM_TAG_DEVICE_UNIQUE_ATTESTATION:
+            case KM_TAG_IDENTITY_CREDENTIAL_KEY:
+            case KM_TAG_MAC_LENGTH:
+            case KM_TAG_NONCE:
+            case KM_TAG_RESET_SINCE_ID_ROTATION:
+            case KM_TAG_ROOT_OF_TRUST:
+            case KM_TAG_UNIQUE_ID:
+                break;
+
+            /* KeyMint-enforced */
+            case KM_TAG_ALGORITHM:
+            case KM_TAG_APPLICATION_ID:
+            case KM_TAG_AUTH_TIMEOUT:
+            case KM_TAG_BLOB_USAGE_REQUIREMENTS:
+            case KM_TAG_BLOCK_MODE:
+            case KM_TAG_BOOT_PATCHLEVEL:
+            case KM_TAG_CALLER_NONCE:
+            case KM_TAG_DIGEST:
+            case KM_TAG_EC_CURVE:
+            case KM_TAG_EXPORTABLE:
+            case KM_TAG_INCLUDE_UNIQUE_ID:
+            case KM_TAG_KEY_SIZE:
+            case KM_TAG_MAX_USES_PER_BOOT:
+            case KM_TAG_MIN_MAC_LENGTH:
+            case KM_TAG_MIN_SECONDS_BETWEEN_OPS:
+            case KM_TAG_NO_AUTH_REQUIRED:
+            case KM_TAG_ORIGIN:
+            case KM_TAG_OS_PATCHLEVEL:
+            case KM_TAG_OS_VERSION:
+            case KM_TAG_PADDING:
+            case KM_TAG_PURPOSE:
+            case KM_TAG_RSA_OAEP_MGF_DIGEST:
+            case KM_TAG_RSA_PUBLIC_EXPONENT:
+            case KM_TAG_UNLOCKED_DEVICE_REQUIRED:
+            case KM_TAG_USER_AUTH_TYPE:
+            case KM_TAG_USER_SECURE_ID:
+            case KM_TAG_VENDOR_PATCHLEVEL:
+                keyMintEnforced.authorizations.push_back(kmParam2Aidl(entry));
+                break;
+
+            /* Keystore-enforced */
+            case KM_TAG_ACTIVE_DATETIME:
+            case KM_TAG_ALL_APPLICATIONS:
+            case KM_TAG_ALL_USERS:
+            case KM_TAG_MAX_BOOT_LEVEL:
+            case KM_TAG_ORIGINATION_EXPIRE_DATETIME:
+            case KM_TAG_USAGE_EXPIRE_DATETIME:
+            case KM_TAG_USER_ID:
+            case KM_TAG_USAGE_COUNT_LIMIT:
+                keystoreEnforced.authorizations.push_back(kmParam2Aidl(entry));
+                break;
+        }
+    }
+
+    vector<KeyCharacteristics> retval;
+    retval.reserve(2);
+    if (!keyMintEnforced.authorizations.empty()) retval.push_back(std::move(keyMintEnforced));
+    if (include_keystore_enforced && !keystoreEnforced.authorizations.empty()) {
+        retval.push_back(std::move(keystoreEnforced));
+    }
+
+    return retval;
+}
+
+Certificate convertCertificate(const keymaster_blob_t& cert) {
+    return {std::vector<uint8_t>(cert.data, cert.data + cert.data_length)};
+}
+
+vector<Certificate> convertCertificateChain(const CertificateChain& chain) {
+    vector<Certificate> retval;
+    retval.reserve(chain.entry_count);
+    std::transform(chain.begin(), chain.end(), std::back_inserter(retval), convertCertificate);
+    return retval;
+}
+
+void addClientAndAppData(const std::vector<uint8_t>& appId, const std::vector<uint8_t>& appData,
+                         ::keymaster::AuthorizationSet* params) {
+    params->Clear();
+    if (appId.size()) {
+        params->push_back(::keymaster::TAG_APPLICATION_ID, appId.data(), appId.size());
+    }
+    if (appData.size()) {
+        params->push_back(::keymaster::TAG_APPLICATION_DATA, appData.data(), appData.size());
+    }
+}
+
+} // namespace
+
+constexpr size_t kOperationTableSize = 16;
+
+MicrodroidKeyMintDevice::MicrodroidKeyMintDevice(SecurityLevel securityLevel)
+      : impl_(new ::keymaster::AndroidKeymaster(
+                [&]() -> auto {
+                    auto context =
+                            new PureSoftKeymasterContext(KmVersion::KEYMINT_1,
+                                                         static_cast<keymaster_security_level_t>(
+                                                                 securityLevel));
+                    context->SetSystemVersion(::keymaster::GetOsVersion(),
+                                              ::keymaster::GetOsPatchlevel());
+                    return context;
+                }(),
+                kOperationTableSize)),
+        securityLevel_(securityLevel) {}
+
+MicrodroidKeyMintDevice::~MicrodroidKeyMintDevice() {}
+
+ScopedAStatus MicrodroidKeyMintDevice::getHardwareInfo(KeyMintHardwareInfo* info) {
+    info->versionNumber = 1;
+    info->securityLevel = securityLevel_;
+    info->keyMintName = "FakeKeyMintDevice";
+    info->keyMintAuthorName = "Google";
+    info->timestampTokenRequired = false;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus MicrodroidKeyMintDevice::addRngEntropy(const vector<uint8_t>& data) {
+    if (data.size() == 0) {
+        return ScopedAStatus::ok();
+    }
+
+    AddEntropyRequest request(impl_->message_version());
+    request.random_data.Reinitialize(data.data(), data.size());
+
+    AddEntropyResponse response(impl_->message_version());
+    impl_->AddRngEntropy(request, &response);
+
+    return kmError2ScopedAStatus(response.error);
+}
+
+ScopedAStatus MicrodroidKeyMintDevice::generateKey(const vector<KeyParameter>& keyParams,
+                                                   const optional<AttestationKey>& attestationKey,
+                                                   KeyCreationResult* creationResult) {
+    GenerateKeyRequest request(impl_->message_version());
+    request.key_description.Reinitialize(KmParamSet(keyParams));
+    if (attestationKey) {
+        request.attestation_signing_key_blob =
+                KeymasterKeyBlob(attestationKey->keyBlob.data(), attestationKey->keyBlob.size());
+        request.attest_key_params.Reinitialize(KmParamSet(attestationKey->attestKeyParams));
+        request.issuer_subject = KeymasterBlob(attestationKey->issuerSubjectName.data(),
+                                               attestationKey->issuerSubjectName.size());
+    }
+
+    GenerateKeyResponse response(impl_->message_version());
+    impl_->GenerateKey(request, &response);
+
+    if (response.error != KM_ERROR_OK) {
+        // Note a key difference between this current aidl and previous hal, is
+        // that hal returns void where as aidl returns the error status.  If
+        // aidl returns error, then aidl will not return any change you may make
+        // to the out parameters.  This is quite different from hal where all
+        // output variable can be modified due to hal returning void.
+        //
+        // So the caller need to be aware not to expect aidl functions to clear
+        // the output variables for you in case of error.  If you left some
+        // wrong data set in the out parameters, they will stay there.
+        return kmError2ScopedAStatus(response.error);
+    }
+
+    creationResult->keyBlob = kmBlob2vector(response.key_blob);
+    creationResult->keyCharacteristics =
+            convertKeyCharacteristics(securityLevel_, request.key_description, response.unenforced,
+                                      response.enforced);
+    creationResult->certificateChain = convertCertificateChain(response.certificate_chain);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus MicrodroidKeyMintDevice::importKey(const vector<KeyParameter>& keyParams,
+                                                 KeyFormat keyFormat,
+                                                 const vector<uint8_t>& keyData,
+                                                 const optional<AttestationKey>& attestationKey,
+                                                 KeyCreationResult* creationResult) {
+    ImportKeyRequest request(impl_->message_version());
+    request.key_description.Reinitialize(KmParamSet(keyParams));
+    request.key_format = legacy_enum_conversion(keyFormat);
+    request.key_data = KeymasterKeyBlob(keyData.data(), keyData.size());
+    if (attestationKey) {
+        request.attestation_signing_key_blob =
+                KeymasterKeyBlob(attestationKey->keyBlob.data(), attestationKey->keyBlob.size());
+        request.attest_key_params.Reinitialize(KmParamSet(attestationKey->attestKeyParams));
+        request.issuer_subject = KeymasterBlob(attestationKey->issuerSubjectName.data(),
+                                               attestationKey->issuerSubjectName.size());
+    }
+
+    ImportKeyResponse response(impl_->message_version());
+    impl_->ImportKey(request, &response);
+
+    if (response.error != KM_ERROR_OK) {
+        return kmError2ScopedAStatus(response.error);
+    }
+
+    creationResult->keyBlob = kmBlob2vector(response.key_blob);
+    creationResult->keyCharacteristics =
+            convertKeyCharacteristics(securityLevel_, request.key_description, response.unenforced,
+                                      response.enforced);
+    creationResult->certificateChain = convertCertificateChain(response.certificate_chain);
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus MicrodroidKeyMintDevice::importWrappedKey(
+        const vector<uint8_t>& wrappedKeyData,        //
+        const vector<uint8_t>& wrappingKeyBlob,       //
+        const vector<uint8_t>& maskingKey,            //
+        const vector<KeyParameter>& unwrappingParams, //
+        int64_t passwordSid, int64_t biometricSid,    //
+        KeyCreationResult* creationResult) {
+    ImportWrappedKeyRequest request(impl_->message_version());
+    request.SetWrappedMaterial(wrappedKeyData.data(), wrappedKeyData.size());
+    request.SetWrappingMaterial(wrappingKeyBlob.data(), wrappingKeyBlob.size());
+    request.SetMaskingKeyMaterial(maskingKey.data(), maskingKey.size());
+    request.additional_params.Reinitialize(KmParamSet(unwrappingParams));
+    request.password_sid = static_cast<uint64_t>(passwordSid);
+    request.biometric_sid = static_cast<uint64_t>(biometricSid);
+
+    ImportWrappedKeyResponse response(impl_->message_version());
+    impl_->ImportWrappedKey(request, &response);
+
+    if (response.error != KM_ERROR_OK) {
+        return kmError2ScopedAStatus(response.error);
+    }
+
+    creationResult->keyBlob = kmBlob2vector(response.key_blob);
+    creationResult->keyCharacteristics =
+            convertKeyCharacteristics(securityLevel_, request.additional_params,
+                                      response.unenforced, response.enforced);
+    creationResult->certificateChain = convertCertificateChain(response.certificate_chain);
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus MicrodroidKeyMintDevice::upgradeKey(const vector<uint8_t>& keyBlobToUpgrade,
+                                                  const vector<KeyParameter>& upgradeParams,
+                                                  vector<uint8_t>* keyBlob) {
+    UpgradeKeyRequest request(impl_->message_version());
+    request.SetKeyMaterial(keyBlobToUpgrade.data(), keyBlobToUpgrade.size());
+    request.upgrade_params.Reinitialize(KmParamSet(upgradeParams));
+
+    UpgradeKeyResponse response(impl_->message_version());
+    impl_->UpgradeKey(request, &response);
+
+    if (response.error != KM_ERROR_OK) {
+        return kmError2ScopedAStatus(response.error);
+    }
+
+    *keyBlob = kmBlob2vector(response.upgraded_key);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus MicrodroidKeyMintDevice::deleteKey(const vector<uint8_t>& keyBlob) {
+    DeleteKeyRequest request(impl_->message_version());
+    request.SetKeyMaterial(keyBlob.data(), keyBlob.size());
+
+    DeleteKeyResponse response(impl_->message_version());
+    impl_->DeleteKey(request, &response);
+
+    return kmError2ScopedAStatus(response.error);
+}
+
+ScopedAStatus MicrodroidKeyMintDevice::deleteAllKeys() {
+    // There's nothing to be done to delete software key blobs.
+    DeleteAllKeysRequest request(impl_->message_version());
+    DeleteAllKeysResponse response(impl_->message_version());
+    impl_->DeleteAllKeys(request, &response);
+
+    return kmError2ScopedAStatus(response.error);
+}
+
+ScopedAStatus MicrodroidKeyMintDevice::destroyAttestationIds() {
+    return kmError2ScopedAStatus(KM_ERROR_UNIMPLEMENTED);
+}
+
+ScopedAStatus MicrodroidKeyMintDevice::begin(KeyPurpose purpose, const vector<uint8_t>& keyBlob,
+                                             const vector<KeyParameter>& params,
+                                             const optional<HardwareAuthToken>& authToken,
+                                             BeginResult* result) {
+    BeginOperationRequest request(impl_->message_version());
+    request.purpose = legacy_enum_conversion(purpose);
+    request.SetKeyMaterial(keyBlob.data(), keyBlob.size());
+    request.additional_params.Reinitialize(KmParamSet(params));
+
+    vector<uint8_t> vector_token = authToken2AidlVec(authToken);
+    request.additional_params.push_back(TAG_AUTH_TOKEN,
+                                        reinterpret_cast<uint8_t*>(vector_token.data()),
+                                        vector_token.size());
+
+    BeginOperationResponse response(impl_->message_version());
+    impl_->BeginOperation(request, &response);
+
+    if (response.error != KM_ERROR_OK) {
+        return kmError2ScopedAStatus(response.error);
+    }
+
+    result->params = kmParamSet2Aidl(response.output_params);
+    result->challenge = response.op_handle;
+    result->operation =
+            ndk::SharedRefBase::make<AndroidKeyMintOperation>(impl_, response.op_handle);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus MicrodroidKeyMintDevice::deviceLocked(
+        bool passwordOnly, const std::optional<secureclock::TimeStampToken>& timestampToken) {
+    DeviceLockedRequest request(impl_->message_version());
+    request.passwordOnly = passwordOnly;
+    if (timestampToken.has_value()) {
+        request.token.challenge = timestampToken->challenge;
+        request.token.mac = {timestampToken->mac.data(), timestampToken->mac.size()};
+        request.token.timestamp = timestampToken->timestamp.milliSeconds;
+    }
+    DeviceLockedResponse response = impl_->DeviceLocked(request);
+    return kmError2ScopedAStatus(response.error);
+}
+
+ScopedAStatus MicrodroidKeyMintDevice::earlyBootEnded() {
+    EarlyBootEndedResponse response = impl_->EarlyBootEnded();
+    return kmError2ScopedAStatus(response.error);
+}
+
+ScopedAStatus MicrodroidKeyMintDevice::convertStorageKeyToEphemeral(
+        const std::vector<uint8_t>& /* storageKeyBlob */,
+        std::vector<uint8_t>* /* ephemeralKeyBlob */) {
+    return kmError2ScopedAStatus(KM_ERROR_UNIMPLEMENTED);
+}
+
+ScopedAStatus MicrodroidKeyMintDevice::getKeyCharacteristics(
+        const std::vector<uint8_t>& keyBlob, const std::vector<uint8_t>& appId,
+        const std::vector<uint8_t>& appData, std::vector<KeyCharacteristics>* keyCharacteristics) {
+    GetKeyCharacteristicsRequest request(impl_->message_version());
+    request.SetKeyMaterial(keyBlob.data(), keyBlob.size());
+    addClientAndAppData(appId, appData, &request.additional_params);
+
+    GetKeyCharacteristicsResponse response(impl_->message_version());
+    impl_->GetKeyCharacteristics(request, &response);
+
+    if (response.error != KM_ERROR_OK) {
+        return kmError2ScopedAStatus(response.error);
+    }
+
+    AuthorizationSet emptySet;
+    *keyCharacteristics = convertKeyCharacteristics(securityLevel_, emptySet, response.unenforced,
+                                                    response.enforced,
+                                                    /* include_keystore_enforced = */ false);
+
+    return ScopedAStatus::ok();
+}
+
+IKeyMintDevice* CreateKeyMintDevice(SecurityLevel securityLevel) {
+    return ::new MicrodroidKeyMintDevice(securityLevel);
+}
+
+} // namespace aidl::android::hardware::security::keymint
