Another refactor, deleting AbstractFactoryRegistry.

I should have known better than to make these singletons to begin
with.  Globals create problems.  This undoes that mistake.

Change-Id: Idf61d5f72e3c34b5c4ddb27cc94b05f506561743
diff --git a/Android.mk b/Android.mk
index de43d86..a7995f4 100644
--- a/Android.mk
+++ b/Android.mk
@@ -108,7 +108,6 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := keymaster_tests
 LOCAL_SRC_FILES := \
-	abstract_factory_registry_test.cpp \
 	android_keymaster_messages_test.cpp \
 	android_keymaster_test.cpp \
 	android_keymaster_test_utils.cpp \
diff --git a/Makefile b/Makefile
index c0b6500..02793fe 100644
--- a/Makefile
+++ b/Makefile
@@ -55,7 +55,6 @@
 LDLIBS=-L$(BASE)/../boringssl/build/crypto -lcrypto -lpthread -lstdc++ -lgcov
 
 CPPSRCS=\
-	abstract_factory_registry_test.cpp \
 	aead_mode_operation.cpp \
 	aes_key.cpp \
 	aes_operation.cpp \
@@ -104,7 +103,7 @@
 OBJS=$(CPPSRCS:.cpp=.o) $(CCSRCS:.cc=.o) $(CSRCS:.c=.o)
 DEPS=$(CPPSRCS:.cpp=.d) $(CCSRCS:.cc=.d) $(CSRCS:.c=.d)
 
-BINARIES = abstract_factory_registry_test \
+BINARIES = \
 	android_keymaster_messages_test \
 	android_keymaster_test \
 	authorization_set_test \
@@ -241,11 +240,6 @@
 	$(BASE)/system/security/keystore/keyblob_utils.o \
 	$(GTEST_OBJS)
 
-abstract_factory_registry_test: abstract_factory_registry_test.o \
-	android_keymaster_utils.o \
-	logger.o \
-	$(GTEST_OBJS)
-
 keymaster_enforcement_test: keymaster_enforcement_test.o \
 	android_keymaster_messages.o \
 	android_keymaster_test_utils.o \
diff --git a/abstract_factory_registry.h b/abstract_factory_registry.h
deleted file mode 100644
index 61dfae1..0000000
--- a/abstract_factory_registry.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright 2014 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 SYSTEM_KEYMASTER_REGISTRY_H_
-#define SYSTEM_KEYMASTER_REGISTRY_H_
-
-#include <assert.h>
-#include <string.h>
-
-#include <UniquePtr.h>
-
-#include <keymaster/android_keymaster_utils.h>
-#include <keymaster/logger.h>
-
-namespace keymaster {
-
-template <typename AbstractFactoryType, typename ConcreteFactoryType> class FactoryRegistration;
-static const size_t DEFAULT_REGISTRY_CAPACITY = 8;
-
-/**
- * A registry of abstract factories that maps keys to concrete subtypes of the specified abstract
- * factory type.  Specific concrete types can be looked up by key using Get(), or all can be
- * retrived with GetAll().  Note that the registry is not designed to handle large numbers of
- * factories (they're stored in an array, which is searched linearly), and it is not recommended to
- * add and remove entries dynamically.
- *
- * To use this registry:
- *
- * 1.  Create an AbstractFactory class.  It must contain:
- *     a.  A typedef "KeyType" that defines the registry key type.
- *     b.  A pure virtual method "registry_key()" that returns KeyType.
- *     c.  A virtual destructor.
- *     d.  Factory methods (likely all pure virtual).
- *
- * 2.  Create one or more concrete subclasses of AbstractFactory.  The concrete factories must have
- *     failure-proof, no-argument constructors.  Note that by design it is impossible to register
- *     two factories which return the same value from registry_key().  Attempting to do so will
- *     cause both to be removed.
- *
- * 3.  Define the registry instance pointer using the DEFINE_ABSTRACT_FACTORY_REGISTRY_INSTANCE
- *     macro.
- *
- * 4.  Register each of the concrete factories by creating an instance of
- *     AbstractFactoryRegistry<AbstractFactory>::Registration<ConcreteFactory> for each concrete
- *     factory.
- *
- * 5.  At run-time call Get() or GetAll() to retrieve AbstractFactory-typed pointers to the concrete
- *     factories, then use the factories.
- *
- * 6.  (Optional, but recommended) Shortly after startup, use GetAll() and validate that all of the
- *     entries appear to be valid.  In the absence of exceptions, failures will be silent.  In the
- *     presence of exceptions, failures that throw would cause a crash on startup.
- */
-template <typename AbstractFactoryType> class AbstractFactoryRegistry {
-  public:
-    typedef typename AbstractFactoryType::KeyType KeyType;
-
-    /**
-     * Get a concrete factory for the specified key type.
-     */
-    static AbstractFactoryType* Get(const KeyType key) { return instance()->GetFactory(key); }
-
-    /**
-     * Get all concrete factories.  The caller does NOT take ownership of the returned array, and
-     * must not modify anything in it.
-     */
-    static const AbstractFactoryType** GetAll(size_t* factory_count) {
-        return const_cast<const AbstractFactoryType**>(instance()->GetAllFactories(factory_count));
-    }
-
-    /**
-     * Return a the number of registered factories.
-     */
-    static size_t size() { return instance()->num_factories(); }
-
-    /**
-     * Registration objects are responsible for creating, registering, de-registering and deleting
-     * concrete factory instances.  Operator new is private and unimplemented to prevent dynamic
-     * allocation; Registrations must be either stack- or statically-allocated.
-     */
-    template <typename ConcreteFactoryType> class Registration {
-      public:
-        template <typename... Args>
-        Registration(Args... args)
-            : factory_(new ConcreteFactoryType(args...)) {
-            AbstractFactoryRegistry::instance()->Register(factory_.get());
-        }
-
-        ~Registration() {
-            if (instance_ptr)
-                instance_ptr->Deregister(factory_.get());
-        }
-
-      private:
-        UniquePtr<ConcreteFactoryType> factory_;
-    };
-
-  private:
-    template <typename A, typename C> friend class FactoryRegistration;
-
-    static AbstractFactoryRegistry* instance() {
-        if (!instance_ptr)
-            instance_ptr = new AbstractFactoryRegistry;
-        return instance_ptr;
-    }
-
-    void Register(AbstractFactoryType* entry);
-    void Deregister(AbstractFactoryType* entry);
-
-    AbstractFactoryType* GetFactory(const KeyType key) const;
-    AbstractFactoryType** GetAllFactories(size_t* factory_count) const;
-    size_t num_factories() const { return size_; }
-
-    AbstractFactoryRegistry()
-        : capacity_(DEFAULT_REGISTRY_CAPACITY), size_(0),
-          entries_(new AbstractFactoryType*[capacity_]) {}
-    ~AbstractFactoryRegistry() {
-        assert(this == instance_ptr);
-        instance_ptr = 0;
-    }
-
-    void DeregisterAll() { delete instance_ptr; }
-
-    size_t capacity_;
-    size_t size_;
-    UniquePtr<AbstractFactoryType* []> entries_;
-
-#ifdef TESTING_REGISTRY
-  public:
-#endif  // TESTING_REGISTRY
-    static AbstractFactoryRegistry* instance_ptr;
-};
-
-/**
- * Helper macro for defining a registry instance.
- */
-#define DEFINE_ABSTRACT_FACTORY_REGISTRY_INSTANCE(AbstractFactoryType)                             \
-    template <>                                                                                    \
-    AbstractFactoryRegistry<AbstractFactoryType>*                                                  \
-        AbstractFactoryRegistry<AbstractFactoryType>::instance_ptr = 0
-
-template <typename AbstractFactoryType>
-AbstractFactoryType* AbstractFactoryRegistry<AbstractFactoryType>::GetFactory(
-    const typename AbstractFactoryType::KeyType key) const {
-    for (auto& entry : ArrayWrapper<AbstractFactoryType*>(entries_.get(), size_))
-        if (entry->registry_key() == key)
-            return entry;
-    return NULL;
-}
-
-template <typename AbstractFactoryType>
-AbstractFactoryType**
-AbstractFactoryRegistry<AbstractFactoryType>::GetAllFactories(size_t* factory_count) const {
-    *factory_count = size_;
-    return entries_.get();
-}
-
-template <typename AbstractFactoryType>
-void AbstractFactoryRegistry<AbstractFactoryType>::Register(AbstractFactoryType* entry) {
-    AbstractFactoryType* tmp = GetFactory(entry->registry_key());
-    if (tmp) {
-        // Already have one.  Don't add this one and remove the one we have.
-        Deregister(tmp);
-        return;
-    }
-
-    if (size_ == capacity_) {
-        size_t new_capacity = capacity_ * 2;
-        UniquePtr<AbstractFactoryType* []> new_entries(new AbstractFactoryType*[new_capacity]);
-        if (!new_entries.get()) {
-            LOG_S("Tried to register multiple abstract factories for the same type", 0);
-            return;
-        }
-        memcpy(new_entries.get(), entries_.get(), sizeof(AbstractFactoryType*) * size_);
-        entries_.reset(new_entries.release());
-        capacity_ = new_capacity;
-    }
-    entries_[size_++] = entry;
-}
-
-template <typename AbstractFactoryType>
-void AbstractFactoryRegistry<AbstractFactoryType>::Deregister(AbstractFactoryType* entry) {
-    // Since registration should always occur in reverse order from registration (due to
-    // FactoryRegistration not being new'able), entry should be the last in the registry.  We handle
-    // the more general case of out-of-order deregistrations in the code, but these assertions will
-    // tell us if something is wrong.
-    assert(size_ > 0);
-
-    for (int i = size_ - 1; i >= 0; --i) {
-        if (entries_[i]->registry_key() == entry->registry_key()) {
-            for (int j = i + 1; j < (int)size_; ++j)
-                entries_[j - 1] = entries_[j];
-            if (--size_ == 0)
-                delete instance_ptr;
-            return;
-        }
-    }
-}
-
-}  // namespace keymaster
-
-#endif  // SYSTEM_KEYMASTER_REGISTRY_H_
diff --git a/abstract_factory_registry_test.cpp b/abstract_factory_registry_test.cpp
deleted file mode 100644
index 605a79b..0000000
--- a/abstract_factory_registry_test.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright 2014 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 TESTING_REGISTRY
-#include "abstract_factory_registry.h"
-
-#include <algorithm>
-
-#include <gtest/gtest.h>
-
-namespace keymaster {
-
-class TestAbstractFactory {
-  public:
-    virtual ~TestAbstractFactory() {}
-    typedef int KeyType;
-    virtual KeyType registry_key() const = 0;
-};
-
-// For actual applications, the concrete factories will be different types, but for convenience we
-// use this template to create a whole family of concrete subtypes.
-template <int key> class TestFactory : public TestAbstractFactory {
-  public:
-    TestAbstractFactory::KeyType registry_key() const { return key; }
-};
-
-typedef AbstractFactoryRegistry<TestAbstractFactory> TestRegistry;
-
-DEFINE_ABSTRACT_FACTORY_REGISTRY_INSTANCE(TestAbstractFactory);
-
-#define REGISTER_FACTORY(n) TestRegistry::Registration<TestFactory<n>> registration##n
-
-TEST(RegistryTest, RegisterAndDeregister) {
-    // Registry instance hasn't been created.
-    EXPECT_TRUE(TestRegistry::instance_ptr == NULL);
-
-    {
-        REGISTER_FACTORY(1);
-
-        // Registry instance should have been created.
-        EXPECT_FALSE(TestRegistry::instance_ptr == NULL);
-
-        // Registry should contain instance.
-        EXPECT_EQ(1U, TestRegistry::size());
-        ASSERT_TRUE(TestRegistry::Get(1) != NULL);
-        EXPECT_EQ(1, TestRegistry::Get(1)->registry_key());
-
-        // Registration goes out of scope here.
-    }
-
-    // Registry should have been deleted, and pointer zeroed
-    EXPECT_TRUE(TestRegistry::instance_ptr == NULL);
-}
-
-TEST(RegistryTest, RegisterAndDeregisterTwo) {
-    // Registry instance hasn't been created.
-    EXPECT_TRUE(TestRegistry::instance_ptr == NULL);
-
-    {
-        REGISTER_FACTORY(1);
-
-        // Registry instance should have been created.
-        EXPECT_FALSE(TestRegistry::instance_ptr == NULL);
-
-        // Registry should contain instance.
-        EXPECT_EQ(1U, TestRegistry::size());
-        ASSERT_TRUE(TestRegistry::Get(1) != NULL);
-        EXPECT_EQ(1, TestRegistry::Get(1)->registry_key());
-
-        {
-            REGISTER_FACTORY(2);
-
-            // Registry should contain both.
-            EXPECT_EQ(2U, TestRegistry::size());
-            ASSERT_TRUE(TestRegistry::Get(1) != NULL);
-            ASSERT_TRUE(TestRegistry::Get(2) != NULL);
-            EXPECT_EQ(1, TestRegistry::Get(1)->registry_key());
-            EXPECT_EQ(2, TestRegistry::Get(2)->registry_key());
-
-            // First registration goes out of scope here.
-        }
-
-        // Registry should contain first still.
-        EXPECT_EQ(1U, TestRegistry::size());
-        ASSERT_TRUE(TestRegistry::Get(2) == NULL);
-        ASSERT_TRUE(TestRegistry::Get(1) != NULL);
-        EXPECT_EQ(1, TestRegistry::Get(1)->registry_key());
-
-        // Second registration goes out of scope here.
-    }
-
-    // Registry should have been deleted, and pointer zeroed
-    EXPECT_TRUE(TestRegistry::instance_ptr == NULL);
-}
-
-TEST(RegistryTest, RegisterAndDeregisterTen) {
-    // Registry instance hasn't been created.
-    EXPECT_TRUE(TestRegistry::instance_ptr == NULL);
-
-    {
-        // Register 10 factories.
-        REGISTER_FACTORY(1);
-        REGISTER_FACTORY(2);
-        REGISTER_FACTORY(3);
-        REGISTER_FACTORY(4);
-        REGISTER_FACTORY(5);
-        REGISTER_FACTORY(6);
-        REGISTER_FACTORY(7);
-        REGISTER_FACTORY(8);
-        REGISTER_FACTORY(9);
-        REGISTER_FACTORY(10);
-
-        // Registry instance should have been created.
-        EXPECT_FALSE(TestRegistry::instance_ptr == NULL);
-
-        // Registry should contain all 10.
-        EXPECT_EQ(10U, TestRegistry::size());
-        for (int i = 1; i <= 10; ++i) {
-            ASSERT_TRUE(TestRegistry::Get(i) != NULL);
-            EXPECT_EQ(i, TestRegistry::Get(i)->registry_key());
-        }
-
-        // Registrations go out of scope here.
-    }
-
-    // Registry should have been deleted, and pointer zeroed
-    EXPECT_TRUE(TestRegistry::instance_ptr == NULL);
-}
-
-template <typename Registry> void register_and_deregister_factory() {
-    TestRegistry::Registration<Registry> registration;
-}
-
-TEST(RegistryTest, DoubleRegister) {
-    // Registry instance hasn't been created.
-    EXPECT_TRUE(TestRegistry::instance_ptr == NULL);
-
-    // Register a factory;
-    TestRegistry::Registration<TestFactory<1>> registration1;
-    // Registry instance should have been created.
-    EXPECT_FALSE(TestRegistry::instance_ptr == NULL);
-
-    // Registry should contain instance.
-    EXPECT_EQ(1U, TestRegistry::size());
-    ASSERT_TRUE(TestRegistry::Get(1) != NULL);
-    EXPECT_EQ(1, TestRegistry::Get(1)->registry_key());
-
-    // Register another with the same key.
-    TestRegistry::Registration<TestFactory<1>> registration2;
-    // Registry should have been deleted, and pointer zeroed
-    EXPECT_TRUE(TestRegistry::instance_ptr == NULL);
-}
-
-}  // namespace keymaster
diff --git a/aes_key.cpp b/aes_key.cpp
index e1a890f..1d59010 100644
--- a/aes_key.cpp
+++ b/aes_key.cpp
@@ -25,9 +25,24 @@
 
 namespace keymaster {
 
+AesEncryptionOperationFactory encrypt_factory;
+AesDecryptionOperationFactory decrypt_factory;
+
+OperationFactory* AesKeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const {
+    switch (purpose) {
+    case KM_PURPOSE_ENCRYPT:
+        return &encrypt_factory;
+    case KM_PURPOSE_DECRYPT:
+        return &decrypt_factory;
+    default:
+        return nullptr;
+    }
+}
+
 keymaster_error_t AesKeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
                                          const AuthorizationSet& hw_enforced,
-                                         const AuthorizationSet& sw_enforced, UniquePtr<Key>* key) {
+                                         const AuthorizationSet& sw_enforced,
+                                         UniquePtr<Key>* key) const {
     if (!key)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
diff --git a/aes_key.h b/aes_key.h
index 28efc39..dfc9578 100644
--- a/aes_key.h
+++ b/aes_key.h
@@ -31,7 +31,10 @@
 
     keymaster_error_t LoadKey(const KeymasterKeyBlob& key_material,
                               const AuthorizationSet& hw_enforced,
-                              const AuthorizationSet& sw_enforced, UniquePtr<Key>* key) override;
+                              const AuthorizationSet& sw_enforced,
+                              UniquePtr<Key>* key) const override;
+
+    OperationFactory* GetOperationFactory(keymaster_purpose_t purpose) const override;
 
   private:
     bool key_size_supported(size_t key_size_bits) const override {
diff --git a/aes_operation.cpp b/aes_operation.cpp
index 22fbd0e..3e33e12 100644
--- a/aes_operation.cpp
+++ b/aes_operation.cpp
@@ -16,6 +16,8 @@
 
 #include <stdio.h>
 
+#include <UniquePtr.h>
+
 #include <openssl/aes.h>
 #include <openssl/err.h>
 #include <openssl/rand.h>
@@ -28,28 +30,6 @@
 
 namespace keymaster {
 
-/**
- * Abstract base for AES operation factories.  This class does all of the work to create
- * AES operations.
- */
-class AesOperationFactory : public OperationFactory {
-  public:
-    virtual KeyType registry_key() const { return KeyType(KM_ALGORITHM_AES, purpose()); }
-
-    virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
-                                       keymaster_error_t* error);
-    virtual const keymaster_block_mode_t* SupportedBlockModes(size_t* block_mode_count) const;
-    virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_count) const;
-
-    virtual keymaster_purpose_t purpose() const = 0;
-
-  private:
-    virtual Operation* CreateEvpOperation(const SymmetricKey& key,
-                                          keymaster_block_mode_t block_mode,
-                                          keymaster_padding_t padding, bool caller_iv,
-                                          keymaster_error_t* error);
-};
-
 Operation* AesOperationFactory::CreateOperation(const Key& key,
                                                 const AuthorizationSet& begin_params,
                                                 keymaster_error_t* error) {
@@ -157,22 +137,6 @@
     return supported_padding_modes;
 }
 
-/**
- * Concrete factory for AES encryption operations.
- */
-class AesEncryptionOperationFactory : public AesOperationFactory {
-    keymaster_purpose_t purpose() const { return KM_PURPOSE_ENCRYPT; }
-};
-static OperationFactoryRegistry::Registration<AesEncryptionOperationFactory> encrypt_registration;
-
-/**
- * Concrete factory for AES decryption operations.
- */
-class AesDecryptionOperationFactory : public AesOperationFactory {
-    keymaster_purpose_t purpose() const { return KM_PURPOSE_DECRYPT; }
-};
-static OperationFactoryRegistry::Registration<AesDecryptionOperationFactory> decrypt_registration;
-
 AesEvpOperation::AesEvpOperation(keymaster_purpose_t purpose, keymaster_block_mode_t block_mode,
                                  keymaster_padding_t padding, bool caller_iv, const uint8_t* key,
                                  size_t key_size)
diff --git a/aes_operation.h b/aes_operation.h
index 2172e2d..0420eb4 100644
--- a/aes_operation.h
+++ b/aes_operation.h
@@ -77,6 +77,42 @@
     int evp_encrypt_mode() { return 0; }
 };
 
+/**
+ * Abstract base for AES operation factories.  This class does all of the work to create
+ * AES operations.
+ */
+class AesOperationFactory : public OperationFactory {
+  public:
+    virtual KeyType registry_key() const { return KeyType(KM_ALGORITHM_AES, purpose()); }
+
+    virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
+                                       keymaster_error_t* error);
+    virtual const keymaster_block_mode_t* SupportedBlockModes(size_t* block_mode_count) const;
+    virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_count) const;
+
+    virtual keymaster_purpose_t purpose() const = 0;
+
+  private:
+    virtual Operation* CreateEvpOperation(const SymmetricKey& key,
+                                          keymaster_block_mode_t block_mode,
+                                          keymaster_padding_t padding, bool caller_iv,
+                                          keymaster_error_t* error);
+};
+
+/**
+ * Concrete factory for AES encryption operations.
+ */
+class AesEncryptionOperationFactory : public AesOperationFactory {
+    keymaster_purpose_t purpose() const { return KM_PURPOSE_ENCRYPT; }
+};
+
+/**
+ * Concrete factory for AES decryption operations.
+ */
+class AesDecryptionOperationFactory : public AesOperationFactory {
+    keymaster_purpose_t purpose() const { return KM_PURPOSE_DECRYPT; }
+};
+
 }  // namespace keymaster
 
 #endif  // SYSTEM_KEYMASTER_AES_OPERATION_H_
diff --git a/android_keymaster.cpp b/android_keymaster.cpp
index 0524ed4..09b83c0 100644
--- a/android_keymaster.cpp
+++ b/android_keymaster.cpp
@@ -60,8 +60,9 @@
 // information.
 
 template <typename T>
-bool check_supported(keymaster_algorithm_t algorithm, SupportedResponse<T>* response) {
-    if (KeyFactoryRegistry::Get(algorithm) == NULL) {
+bool check_supported(const KeymasterContext& context, keymaster_algorithm_t algorithm,
+                     SupportedResponse<T>* response) {
+    if (context.GetKeyFactory(algorithm) == NULL) {
         response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
         return false;
     }
@@ -83,48 +84,27 @@
     if (response == NULL)
         return;
 
-    size_t factory_count = 0;
-    const KeyFactory** factories = KeyFactoryRegistry::GetAll(&factory_count);
-    assert(factories != NULL);
-    assert(factory_count > 0);
-
-    UniquePtr<keymaster_algorithm_t[]> algorithms(new keymaster_algorithm_t[factory_count]);
-    if (!algorithms.get()) {
-        response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
-        return;
-    }
-
-    for (size_t i = 0; i < factory_count; ++i)
-        algorithms[i] = factories[i]->registry_key();
-
-    response->results = algorithms.release();
-    response->results_length = factory_count;
     response->error = KM_ERROR_OK;
-}
 
-static OperationFactory* GetOperationFactory(keymaster_algorithm_t algorithm,
-                                             keymaster_purpose_t purpose,
-                                             keymaster_error_t* error) {
-    assert(error);
-    if (error)
-        *error = KM_ERROR_OK;
-
-    OperationFactory* factory =
-        OperationFactoryRegistry::Get(OperationFactory::KeyType(algorithm, purpose));
-    if (factory == NULL && error)
-        *error = KM_ERROR_UNSUPPORTED_PURPOSE;
-
-    return factory;
+    size_t algorithm_count = 0;
+    const keymaster_algorithm_t* algorithms = context_->GetSupportedAlgorithms(&algorithm_count);
+    if (algorithm_count == 0)
+        return;
+    response->results_length = algorithm_count;
+    response->results = dup_array(algorithms, algorithm_count);
+    if (!response->results)
+        response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
 }
 
 template <typename T>
-void GetSupported(keymaster_algorithm_t algorithm, keymaster_purpose_t purpose,
+void GetSupported(const KeymasterContext& context, keymaster_algorithm_t algorithm,
+                  keymaster_purpose_t purpose,
                   const T* (OperationFactory::*get_supported_method)(size_t* count) const,
                   SupportedResponse<T>* response) {
-    if (response == NULL || !check_supported(algorithm, response))
+    if (response == NULL || !check_supported(context, algorithm, response))
         return;
 
-    OperationFactory* factory = GetOperationFactory(algorithm, purpose, &response->error);
+    const OperationFactory* factory = context.GetOperationFactory(algorithm, purpose);
     if (!factory) {
         response->error = KM_ERROR_UNSUPPORTED_PURPOSE;
         return;
@@ -138,40 +118,40 @@
 void AndroidKeymaster::SupportedBlockModes(
     keymaster_algorithm_t algorithm, keymaster_purpose_t purpose,
     SupportedResponse<keymaster_block_mode_t>* response) const {
-    GetSupported(algorithm, purpose, &OperationFactory::SupportedBlockModes, response);
+    GetSupported(*context_, algorithm, purpose, &OperationFactory::SupportedBlockModes, response);
 }
 
 void AndroidKeymaster::SupportedPaddingModes(
     keymaster_algorithm_t algorithm, keymaster_purpose_t purpose,
     SupportedResponse<keymaster_padding_t>* response) const {
-    GetSupported(algorithm, purpose, &OperationFactory::SupportedPaddingModes, response);
+    GetSupported(*context_, algorithm, purpose, &OperationFactory::SupportedPaddingModes, response);
 }
 
 void AndroidKeymaster::SupportedDigests(keymaster_algorithm_t algorithm,
                                         keymaster_purpose_t purpose,
                                         SupportedResponse<keymaster_digest_t>* response) const {
-    GetSupported(algorithm, purpose, &OperationFactory::SupportedDigests, response);
+    GetSupported(*context_, algorithm, purpose, &OperationFactory::SupportedDigests, response);
 }
 
 void AndroidKeymaster::SupportedImportFormats(
     keymaster_algorithm_t algorithm, SupportedResponse<keymaster_key_format_t>* response) const {
-    if (response == NULL || !check_supported(algorithm, response))
+    if (response == NULL || !check_supported(*context_, algorithm, response))
         return;
 
     size_t count;
     const keymaster_key_format_t* formats =
-        KeyFactoryRegistry::Get(algorithm)->SupportedImportFormats(&count);
+        context_->GetKeyFactory(algorithm)->SupportedImportFormats(&count);
     response->SetResults(formats, count);
 }
 
 void AndroidKeymaster::SupportedExportFormats(
     keymaster_algorithm_t algorithm, SupportedResponse<keymaster_key_format_t>* response) const {
-    if (response == NULL || !check_supported(algorithm, response))
+    if (response == NULL || !check_supported(*context_, algorithm, response))
         return;
 
     size_t count;
     const keymaster_key_format_t* formats =
-        KeyFactoryRegistry::Get(algorithm)->SupportedExportFormats(&count);
+        context_->GetKeyFactory(algorithm)->SupportedExportFormats(&count);
     response->SetResults(formats, count);
 }
 
@@ -189,7 +169,7 @@
     KeyFactory* factory = 0;
     UniquePtr<Key> key;
     if (!request.key_description.GetTagValue(TAG_ALGORITHM, &algorithm) ||
-        !(factory = KeyFactoryRegistry::Get(algorithm)))
+        !(factory = context_->GetKeyFactory(algorithm)))
         response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
     else {
         KeymasterKeyBlob key_blob;
@@ -215,14 +195,15 @@
         return;
 }
 
-static KeyFactory* GetKeyFactory(const AuthorizationSet& hw_enforced,
+static KeyFactory* GetKeyFactory(const KeymasterContext& context,
+                                 const AuthorizationSet& hw_enforced,
                                  const AuthorizationSet& sw_enforced,
                                  keymaster_algorithm_t* algorithm, keymaster_error_t* error) {
     *error = KM_ERROR_UNSUPPORTED_ALGORITHM;
     if (!hw_enforced.GetTagValue(TAG_ALGORITHM, algorithm) &&
         !sw_enforced.GetTagValue(TAG_ALGORITHM, algorithm))
         return nullptr;
-    KeyFactory* factory = KeyFactoryRegistry::Get(*algorithm);
+    KeyFactory* factory = context.GetKeyFactory(*algorithm);
     if (factory)
         *error = KM_ERROR_OK;
     return factory;
@@ -236,10 +217,10 @@
 
     AuthorizationSet hw_enforced;
     AuthorizationSet sw_enforced;
-    keymaster_algorithm_t algorithm;
+    const KeyFactory* key_factory;
     UniquePtr<Key> key;
     response->error = LoadKey(request.key_blob, request.additional_params, &hw_enforced,
-                              &sw_enforced, &algorithm, &key);
+                              &sw_enforced, &key_factory, &key);
     if (response->error != KM_ERROR_OK)
         return;
 
@@ -251,7 +232,7 @@
         return;
 
     response->error = KM_ERROR_UNSUPPORTED_PURPOSE;
-    OperationFactory* factory = OperationFactoryRegistry::Get({algorithm, request.purpose});
+    OperationFactory* factory = key_factory->GetOperationFactory(request.purpose);
     if (!factory)
         return;
 
@@ -327,7 +308,8 @@
         return;
 
     keymaster_algorithm_t algorithm;
-    KeyFactory* key_factory = GetKeyFactory(hw_enforced, sw_enforced, &algorithm, &response->error);
+    KeyFactory* key_factory =
+        GetKeyFactory(*context_, hw_enforced, sw_enforced, &algorithm, &response->error);
     if (!key_factory)
         return;
 
@@ -353,7 +335,7 @@
     KeyFactory* factory = 0;
     UniquePtr<Key> key;
     if (!request.key_description.GetTagValue(TAG_ALGORITHM, &algorithm) ||
-        !(factory = KeyFactoryRegistry::Get(algorithm)))
+        !(factory = context_->GetKeyFactory(algorithm)))
         response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
     else {
         keymaster_key_blob_t key_material = {request.key_data, request.key_data_length};
@@ -378,20 +360,19 @@
                                             const AuthorizationSet& additional_params,
                                             AuthorizationSet* hw_enforced,
                                             AuthorizationSet* sw_enforced,
-                                            keymaster_algorithm_t* algorithm, UniquePtr<Key>* key) {
+                                            const KeyFactory** factory, UniquePtr<Key>* key) {
     KeymasterKeyBlob key_material;
     keymaster_error_t error = context_->ParseKeyBlob(KeymasterKeyBlob(key_blob), additional_params,
                                                      &key_material, hw_enforced, sw_enforced);
     if (error != KM_ERROR_OK)
         return error;
 
-    KeyFactory* key_factory = GetKeyFactory(*hw_enforced, *sw_enforced, algorithm, &error);
-    if (error != KM_ERROR_OK) {
-        assert(!key_factory);
+    keymaster_algorithm_t algorithm;
+    *factory = GetKeyFactory(*context_, *hw_enforced, *sw_enforced, &algorithm, &error);
+    if (error != KM_ERROR_OK)
         return error;
-    }
 
-    return key_factory->LoadKey(key_material, *hw_enforced, *sw_enforced, key);
+    return (*factory)->LoadKey(key_material, *hw_enforced, *sw_enforced, key);
 }
 
 }  // namespace keymaster
diff --git a/asymmetric_key.cpp b/asymmetric_key.cpp
index 72c24a1..f8a6289 100644
--- a/asymmetric_key.cpp
+++ b/asymmetric_key.cpp
@@ -19,6 +19,7 @@
 #include <openssl/x509.h>
 
 #include <hardware/keymaster_defs.h>
+#include <keymaster/android_keymaster_utils.h>
 
 #include "openssl_err.h"
 #include "openssl_utils.h"
@@ -28,16 +29,16 @@
 keymaster_error_t
 AsymmetricKeyFactory::KeyMaterialToEvpKey(keymaster_key_format_t key_format,
                                           const KeymasterKeyBlob& key_material,
-                                          UniquePtr<EVP_PKEY, EVP_PKEY_Delete>* pkey) {
+                                          UniquePtr<EVP_PKEY, EVP_PKEY_Delete>* pkey) const {
     if (key_format != KM_KEY_FORMAT_PKCS8)
         return KM_ERROR_UNSUPPORTED_KEY_FORMAT;
 
     return convert_pkcs8_blob_to_evp(key_material.key_material, key_material.key_material_size,
-                                     registry_key(), pkey);
+                                     keymaster_key_type(), pkey);
 }
 
 keymaster_error_t AsymmetricKeyFactory::EvpKeyToKeyMaterial(const EVP_PKEY* pkey,
-                                                            KeymasterKeyBlob* key_blob) {
+                                                            KeymasterKeyBlob* key_blob) const {
     int key_data_size = i2d_PrivateKey(pkey, NULL /* key_data*/);
     if (key_data_size <= 0)
         return TranslateLastOpenSslError();
@@ -53,13 +54,15 @@
 }
 
 static const keymaster_key_format_t supported_import_formats[] = {KM_KEY_FORMAT_PKCS8};
-const keymaster_key_format_t* AsymmetricKeyFactory::SupportedImportFormats(size_t* format_count) {
+const keymaster_key_format_t*
+AsymmetricKeyFactory::SupportedImportFormats(size_t* format_count) const {
     *format_count = array_length(supported_import_formats);
     return supported_import_formats;
 }
 
 static const keymaster_key_format_t supported_export_formats[] = {KM_KEY_FORMAT_X509};
-const keymaster_key_format_t* AsymmetricKeyFactory::SupportedExportFormats(size_t* format_count) {
+const keymaster_key_format_t*
+AsymmetricKeyFactory::SupportedExportFormats(size_t* format_count) const {
     *format_count = array_length(supported_export_formats);
     return supported_export_formats;
 }
@@ -67,7 +70,7 @@
 keymaster_error_t AsymmetricKeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
                                                 const AuthorizationSet& hw_enforced,
                                                 const AuthorizationSet& sw_enforced,
-                                                UniquePtr<Key>* key) {
+                                                UniquePtr<Key>* key) const {
     UniquePtr<AsymmetricKey> asymmetric_key;
     keymaster_error_t error = CreateEmptyKey(hw_enforced, sw_enforced, &asymmetric_key);
     if (error != KM_ERROR_OK)
diff --git a/asymmetric_key.h b/asymmetric_key.h
index 04dac15..ee321ea 100644
--- a/asymmetric_key.h
+++ b/asymmetric_key.h
@@ -32,20 +32,24 @@
 
     keymaster_error_t KeyMaterialToEvpKey(keymaster_key_format_t key_format,
                                           const KeymasterKeyBlob& key_material,
-                                          UniquePtr<EVP_PKEY, EVP_PKEY_Delete>* evp_pkey);
-    keymaster_error_t EvpKeyToKeyMaterial(const EVP_PKEY* evp_pkey, KeymasterKeyBlob* key_blob);
+                                          UniquePtr<EVP_PKEY, EVP_PKEY_Delete>* evp_pkey) const;
+    keymaster_error_t EvpKeyToKeyMaterial(const EVP_PKEY* evp_pkey,
+                                          KeymasterKeyBlob* key_blob) const;
 
     keymaster_error_t LoadKey(const KeymasterKeyBlob& key_material,
                               const AuthorizationSet& hw_enforced,
-                              const AuthorizationSet& sw_enforced, UniquePtr<Key>* key) override;
+                              const AuthorizationSet& sw_enforced,
+                              UniquePtr<Key>* key) const override;
 
     virtual keymaster_error_t CreateEmptyKey(const AuthorizationSet& hw_enforced,
                                              const AuthorizationSet& sw_enforced,
-                                             UniquePtr<AsymmetricKey>* key) = 0;
-    virtual int evp_key_type() = 0;
+                                             UniquePtr<AsymmetricKey>* key) const = 0;
 
-    virtual const keymaster_key_format_t* SupportedImportFormats(size_t* format_count);
-    virtual const keymaster_key_format_t* SupportedExportFormats(size_t* format_count);
+    virtual keymaster_algorithm_t keymaster_key_type() const = 0;
+    virtual int evp_key_type() const = 0;
+
+    virtual const keymaster_key_format_t* SupportedImportFormats(size_t* format_count) const;
+    virtual const keymaster_key_format_t* SupportedExportFormats(size_t* format_count) const;
 };
 
 class AsymmetricKey : public Key {
diff --git a/ec_key.cpp b/ec_key.cpp
index 0cd3fa0..800ef0e 100644
--- a/ec_key.cpp
+++ b/ec_key.cpp
@@ -18,6 +18,7 @@
 
 #include <keymaster/keymaster_context.h>
 
+#include "ecdsa_operation.h"
 #include "openssl_err.h"
 #include "openssl_utils.h"
 
@@ -29,10 +30,24 @@
 
 namespace keymaster {
 
+static EcdsaSignOperationFactory sign_factory;
+static EcdsaVerifyOperationFactory verify_factory;
+
+OperationFactory* EcdsaKeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const {
+    switch (purpose) {
+    case KM_PURPOSE_SIGN:
+        return &sign_factory;
+    case KM_PURPOSE_VERIFY:
+        return &verify_factory;
+    default:
+        return nullptr;
+    }
+}
+
 keymaster_error_t EcKeyFactory::GenerateKey(const AuthorizationSet& key_description,
                                             KeymasterKeyBlob* key_blob,
                                             AuthorizationSet* hw_enforced,
-                                            AuthorizationSet* sw_enforced) {
+                                            AuthorizationSet* sw_enforced) const {
     if (!key_blob || !hw_enforced || !sw_enforced)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
@@ -82,7 +97,7 @@
                                           const KeymasterKeyBlob& input_key_material,
                                           KeymasterKeyBlob* output_key_blob,
                                           AuthorizationSet* hw_enforced,
-                                          AuthorizationSet* sw_enforced) {
+                                          AuthorizationSet* sw_enforced) const {
     if (!output_key_blob || !hw_enforced || !sw_enforced)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
@@ -101,7 +116,7 @@
                                                            keymaster_key_format_t key_format,
                                                            const KeymasterKeyBlob& key_material,
                                                            AuthorizationSet* updated_description,
-                                                           uint32_t* key_size_bits) {
+                                                           uint32_t* key_size_bits) const {
     if (!updated_description || !key_size_bits)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
@@ -179,7 +194,7 @@
 
 keymaster_error_t EcKeyFactory::CreateEmptyKey(const AuthorizationSet& hw_enforced,
                                                const AuthorizationSet& sw_enforced,
-                                               UniquePtr<AsymmetricKey>* key) {
+                                               UniquePtr<AsymmetricKey>* key) const {
     keymaster_error_t error;
     key->reset(new EcKey(hw_enforced, sw_enforced, &error));
     if (!key->get())
diff --git a/ec_key.h b/ec_key.h
index f6a53f8..c55fd27 100644
--- a/ec_key.h
+++ b/ec_key.h
@@ -29,22 +29,22 @@
 
     keymaster_error_t GenerateKey(const AuthorizationSet& key_description,
                                   KeymasterKeyBlob* key_blob, AuthorizationSet* hw_enforced,
-                                  AuthorizationSet* sw_enforced) override;
+                                  AuthorizationSet* sw_enforced) const override;
     keymaster_error_t 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) override;
+                                AuthorizationSet* sw_enforced) const override;
 
     keymaster_error_t CreateEmptyKey(const AuthorizationSet& hw_enforced,
                                      const AuthorizationSet& sw_enforced,
-                                     UniquePtr<AsymmetricKey>* key) override;
+                                     UniquePtr<AsymmetricKey>* key) const override;
 
     keymaster_error_t UpdateImportKeyDescription(const AuthorizationSet& key_description,
                                                  keymaster_key_format_t key_format,
                                                  const KeymasterKeyBlob& key_material,
                                                  AuthorizationSet* updated_description,
-                                                 uint32_t* key_size);
+                                                 uint32_t* key_size) const;
 
   private:
     static EC_GROUP* choose_group(size_t key_size_bits);
@@ -55,8 +55,10 @@
   public:
     EcdsaKeyFactory(const KeymasterContext* context) : EcKeyFactory(context) {}
 
-    keymaster_algorithm_t registry_key() const override { return KM_ALGORITHM_EC; }
-    int evp_key_type() override { return EVP_PKEY_EC; }
+    OperationFactory* GetOperationFactory(keymaster_purpose_t purpose) const override;
+
+    keymaster_algorithm_t keymaster_key_type() const override { return KM_ALGORITHM_EC; }
+    int evp_key_type() const override { return EVP_PKEY_EC; }
 };
 
 class EcdsaOperationFactory;
diff --git a/ec_keymaster0_key.cpp b/ec_keymaster0_key.cpp
index d171d58..9ed0a74 100644
--- a/ec_keymaster0_key.cpp
+++ b/ec_keymaster0_key.cpp
@@ -18,9 +18,8 @@
 
 #include <memory>
 
-#define LOG_TAG "EcKeymaster0Key"
-#include <cutils/log.h>
-
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/logger.h>
 #include <keymaster/soft_keymaster_context.h>
 
 #include "keymaster0_engine.h"
@@ -38,7 +37,7 @@
 keymaster_error_t EcdsaKeymaster0KeyFactory::GenerateKey(const AuthorizationSet& key_description,
                                                          KeymasterKeyBlob* key_blob,
                                                          AuthorizationSet* hw_enforced,
-                                                         AuthorizationSet* sw_enforced) {
+                                                         AuthorizationSet* sw_enforced) const {
     if (!key_blob || !hw_enforced || !sw_enforced)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
@@ -67,7 +66,7 @@
 keymaster_error_t EcdsaKeymaster0KeyFactory::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) {
+    AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const {
     if (!output_key_blob || !hw_enforced || !sw_enforced)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
@@ -98,7 +97,7 @@
 keymaster_error_t EcdsaKeymaster0KeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
                                                      const AuthorizationSet& hw_enforced,
                                                      const AuthorizationSet& sw_enforced,
-                                                     UniquePtr<Key>* key) {
+                                                     UniquePtr<Key>* key) const {
     if (!key)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
diff --git a/ec_keymaster0_key.h b/ec_keymaster0_key.h
index b2f8294..3671ef7 100644
--- a/ec_keymaster0_key.h
+++ b/ec_keymaster0_key.h
@@ -38,17 +38,18 @@
 
     keymaster_error_t GenerateKey(const AuthorizationSet& key_description,
                                   KeymasterKeyBlob* key_blob, AuthorizationSet* hw_enforced,
-                                  AuthorizationSet* sw_enforced) override;
+                                  AuthorizationSet* sw_enforced) const override;
 
     keymaster_error_t 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) override;
+                                AuthorizationSet* sw_enforced) const override;
 
     keymaster_error_t LoadKey(const KeymasterKeyBlob& key_material,
                               const AuthorizationSet& hw_enforced,
-                              const AuthorizationSet& sw_enforced, UniquePtr<Key>* key) override;
+                              const AuthorizationSet& sw_enforced,
+                              UniquePtr<Key>* key) const override;
 
   private:
     const Keymaster0Engine* engine_;
diff --git a/ecdsa_operation.cpp b/ecdsa_operation.cpp
index c7521c7..a28209a 100644
--- a/ecdsa_operation.cpp
+++ b/ecdsa_operation.cpp
@@ -25,17 +25,6 @@
 
 static const keymaster_digest_t supported_digests[] = {KM_DIGEST_NONE};
 
-class EcdsaOperationFactory : public OperationFactory {
-  private:
-    KeyType registry_key() const override { return KeyType(KM_ALGORITHM_EC, purpose()); }
-    Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
-                               keymaster_error_t* error) override;
-    const keymaster_digest_t* SupportedDigests(size_t* digest_count) const override;
-
-    virtual keymaster_purpose_t purpose() const = 0;
-    virtual Operation* InstantiateOperation(keymaster_digest_t digest, EC_KEY* key) = 0;
-};
-
 Operation* EcdsaOperationFactory::CreateOperation(const Key& key,
                                                   const AuthorizationSet& begin_params,
                                                   keymaster_error_t* error) {
@@ -72,25 +61,6 @@
     return supported_digests;
 }
 
-class EcdsaSignOperationFactory : public EcdsaOperationFactory {
-  private:
-    keymaster_purpose_t purpose() const override { return KM_PURPOSE_SIGN; }
-    Operation* InstantiateOperation(keymaster_digest_t digest, EC_KEY* key) {
-        return new EcdsaSignOperation(purpose(), digest, key);
-    }
-};
-
-static OperationFactoryRegistry::Registration<EcdsaSignOperationFactory> sign_registration;
-
-class EcdsaVerifyOperationFactory : public EcdsaOperationFactory {
-  public:
-    keymaster_purpose_t purpose() const override { return KM_PURPOSE_VERIFY; }
-    Operation* InstantiateOperation(keymaster_digest_t digest, EC_KEY* key) {
-        return new EcdsaVerifyOperation(KM_PURPOSE_VERIFY, digest, key);
-    }
-};
-static OperationFactoryRegistry::Registration<EcdsaVerifyOperationFactory> verify_registration;
-
 EcdsaOperation::~EcdsaOperation() {
     if (ecdsa_key_ != NULL)
         EC_KEY_free(ecdsa_key_);
diff --git a/ecdsa_operation.h b/ecdsa_operation.h
index dd5a61f..db986c8 100644
--- a/ecdsa_operation.h
+++ b/ecdsa_operation.h
@@ -65,6 +65,33 @@
                                      const Buffer& signature, Buffer* output);
 };
 
+class EcdsaOperationFactory : public OperationFactory {
+  private:
+    KeyType registry_key() const override { return KeyType(KM_ALGORITHM_EC, purpose()); }
+    Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
+                               keymaster_error_t* error) override;
+    const keymaster_digest_t* SupportedDigests(size_t* digest_count) const override;
+
+    virtual keymaster_purpose_t purpose() const = 0;
+    virtual Operation* InstantiateOperation(keymaster_digest_t digest, EC_KEY* key) = 0;
+};
+
+class EcdsaSignOperationFactory : public EcdsaOperationFactory {
+  private:
+    keymaster_purpose_t purpose() const override { return KM_PURPOSE_SIGN; }
+    Operation* InstantiateOperation(keymaster_digest_t digest, EC_KEY* key) {
+        return new EcdsaSignOperation(purpose(), digest, key);
+    }
+};
+
+class EcdsaVerifyOperationFactory : public EcdsaOperationFactory {
+  public:
+    keymaster_purpose_t purpose() const override { return KM_PURPOSE_VERIFY; }
+    Operation* InstantiateOperation(keymaster_digest_t digest, EC_KEY* key) {
+        return new EcdsaVerifyOperation(KM_PURPOSE_VERIFY, digest, key);
+    }
+};
+
 }  // namespace keymaster
 
 #endif  // SYSTEM_KEYMASTER_ECDSA_OPERATION_H_
diff --git a/hmac_key.cpp b/hmac_key.cpp
index 1f2e4a4..ac6c482 100644
--- a/hmac_key.cpp
+++ b/hmac_key.cpp
@@ -23,10 +23,24 @@
 
 namespace keymaster {
 
+static HmacSignOperationFactory sign_factory;
+static HmacVerifyOperationFactory verify_factory;
+
+OperationFactory* HmacKeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const {
+    switch (purpose) {
+    case KM_PURPOSE_SIGN:
+        return &sign_factory;
+    case KM_PURPOSE_VERIFY:
+        return &verify_factory;
+    default:
+        return nullptr;
+    }
+}
+
 keymaster_error_t HmacKeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
                                           const AuthorizationSet& hw_enforced,
                                           const AuthorizationSet& sw_enforced,
-                                          UniquePtr<Key>* key) {
+                                          UniquePtr<Key>* key) const {
     if (!key)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
diff --git a/hmac_key.h b/hmac_key.h
index c5a7b91..eaae54e 100644
--- a/hmac_key.h
+++ b/hmac_key.h
@@ -25,11 +25,12 @@
   public:
     HmacKeyFactory(const KeymasterContext* context) : SymmetricKeyFactory(context) {}
 
-    keymaster_algorithm_t registry_key() const override { return KM_ALGORITHM_HMAC; }
-
     keymaster_error_t LoadKey(const KeymasterKeyBlob& key_material,
                               const AuthorizationSet& hw_enforced,
-                              const AuthorizationSet& sw_enforced, UniquePtr<Key>* key) override;
+                              const AuthorizationSet& sw_enforced,
+                              UniquePtr<Key>* key) const override;
+
+    OperationFactory* GetOperationFactory(keymaster_purpose_t purpose) const override;
 
   private:
     bool key_size_supported(size_t key_size_bits) const override {
diff --git a/hmac_operation.cpp b/hmac_operation.cpp
index f11b388..1792487 100644
--- a/hmac_operation.cpp
+++ b/hmac_operation.cpp
@@ -31,22 +31,6 @@
 
 namespace keymaster {
 
-/**
- * Abstract base for HMAC operation factories.  This class does all of the work to create
- * HMAC operations.
- */
-class HmacOperationFactory : public OperationFactory {
-  public:
-    virtual KeyType registry_key() const { return KeyType(KM_ALGORITHM_HMAC, purpose()); }
-
-    virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
-                                       keymaster_error_t* error);
-
-    virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const;
-
-    virtual keymaster_purpose_t purpose() const = 0;
-};
-
 Operation* HmacOperationFactory::CreateOperation(const Key& key,
                                                  const AuthorizationSet& begin_params,
                                                  keymaster_error_t* error) {
@@ -92,22 +76,6 @@
     return supported_digests;
 }
 
-/**
- * Concrete factory for creating HMAC signing operations.
- */
-class HmacSignOperationFactory : public HmacOperationFactory {
-    keymaster_purpose_t purpose() const { return KM_PURPOSE_SIGN; }
-};
-static OperationFactoryRegistry::Registration<HmacSignOperationFactory> sign_registration;
-
-/**
- * Concrete factory for creating HMAC verification operations.
- */
-class HmacVerifyOperationFactory : public HmacOperationFactory {
-    keymaster_purpose_t purpose() const { return KM_PURPOSE_VERIFY; }
-};
-static OperationFactoryRegistry::Registration<HmacVerifyOperationFactory> verify_registration;
-
 HmacOperation::HmacOperation(keymaster_purpose_t purpose, const uint8_t* key_data,
                              size_t key_data_size, keymaster_digest_t digest, size_t tag_length)
     : Operation(purpose), error_(KM_ERROR_OK), tag_length_(tag_length) {
diff --git a/hmac_operation.h b/hmac_operation.h
index 776783c..70fc7a4 100644
--- a/hmac_operation.h
+++ b/hmac_operation.h
@@ -45,6 +45,30 @@
     size_t tag_length_;
 };
 
+/**
+ * Abstract base for HMAC operation factories.  This class does all of the work to create
+ * HMAC operations.
+ */
+class HmacOperationFactory : public OperationFactory {
+  public:
+    virtual KeyType registry_key() const { return KeyType(KM_ALGORITHM_HMAC, purpose()); }
+
+    virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
+                                       keymaster_error_t* error);
+
+    virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const;
+
+    virtual keymaster_purpose_t purpose() const = 0;
+};
+
+class HmacSignOperationFactory : public HmacOperationFactory {
+    keymaster_purpose_t purpose() const { return KM_PURPOSE_SIGN; }
+};
+
+class HmacVerifyOperationFactory : public HmacOperationFactory {
+    keymaster_purpose_t purpose() const { return KM_PURPOSE_VERIFY; }
+};
+
 }  // namespace keymaster
 
 #endif  // SYSTEM_KEYMASTER_HMAC_OPERATION_H_
diff --git a/include/keymaster/android_keymaster.h b/include/keymaster/android_keymaster.h
index db74b97..c9de8ee 100644
--- a/include/keymaster/android_keymaster.h
+++ b/include/keymaster/android_keymaster.h
@@ -23,6 +23,7 @@
 namespace keymaster {
 
 class Key;
+class KeyFactory;
 class KeymasterContext;
 class OperationTable;
 
@@ -79,7 +80,7 @@
     keymaster_error_t LoadKey(const keymaster_key_blob_t& key_blob,
                               const AuthorizationSet& additional_params,
                               AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced,
-                              keymaster_algorithm_t* algorithm, UniquePtr<Key>* key);
+                              const KeyFactory** factory, UniquePtr<Key>* key);
 
     UniquePtr<KeymasterContext> context_;
     UniquePtr<OperationTable> operation_table_;
diff --git a/include/keymaster/keymaster_context.h b/include/keymaster/keymaster_context.h
index 0b9b62b..be4f8d7 100644
--- a/include/keymaster/keymaster_context.h
+++ b/include/keymaster/keymaster_context.h
@@ -19,11 +19,15 @@
 
 #include <assert.h>
 
-#include <keymaster/authorization_set.h>
-#include <keymaster/android_keymaster_utils.h>
+#include <hardware/keymaster_defs.h>
 
 namespace keymaster {
 
+class AuthorizationSet;
+class KeyFactory;
+class OperationFactory;
+struct KeymasterKeyBlob;
+
 /**
  * KeymasterContext provides a singleton abstract interface that encapsulates various
  * environment-dependent elements of AndroidKeymaster.
@@ -58,12 +62,17 @@
     KeymasterContext() {}
     virtual ~KeymasterContext(){};
 
+    virtual KeyFactory* GetKeyFactory(keymaster_algorithm_t algorithm) const = 0;
+    virtual OperationFactory* GetOperationFactory(keymaster_algorithm_t algorithm,
+                                                  keymaster_purpose_t purpose) const = 0;
+    virtual keymaster_algorithm_t* GetSupportedAlgorithms(size_t* algorithms_count) const = 0;
+
     /**
      * CreateKeyBlob takes authorization sets and key material and produces a key blob and hardware
      * and software authorization lists ready to be returned to the AndroidKeymaster client
      * (Keystore, generally).  The blob is integrity-checked and may be encrypted, depending on the
      * needs of the context.
-     *
+    *
      * This method is generally called only by KeyFactory subclassses.
      */
     virtual keymaster_error_t CreateKeyBlob(const AuthorizationSet& key_description,
diff --git a/include/keymaster/soft_keymaster_context.h b/include/keymaster/soft_keymaster_context.h
index 33afe3d..7cf3703 100644
--- a/include/keymaster/soft_keymaster_context.h
+++ b/include/keymaster/soft_keymaster_context.h
@@ -34,6 +34,10 @@
   public:
     SoftKeymasterContext(keymaster0_device_t* keymaster0_device);
 
+    KeyFactory* GetKeyFactory(keymaster_algorithm_t algorithm) const override;
+    OperationFactory* GetOperationFactory(keymaster_algorithm_t algorithm,
+                                          keymaster_purpose_t purpose) const override;
+    keymaster_algorithm_t* GetSupportedAlgorithms(size_t* algorithms_count) const override;
     keymaster_error_t CreateKeyBlob(const AuthorizationSet& auths, keymaster_key_origin_t origin,
                                     const KeymasterKeyBlob& key_material, KeymasterKeyBlob* blob,
                                     AuthorizationSet* hw_enforced,
@@ -48,7 +52,10 @@
 
   private:
     std::unique_ptr<Keymaster0Engine> engine_;
-    std::unique_ptr<SoftKeymasterKeyRegistrations> registrations_;
+    std::unique_ptr<KeyFactory> rsa_factory_;
+    std::unique_ptr<KeyFactory> ec_factory_;
+    std::unique_ptr<KeyFactory> aes_factory_;
+    std::unique_ptr<KeyFactory> hmac_factory_;
 };
 
 }  // namespace keymaster
diff --git a/key.cpp b/key.cpp
index 776ca1b..eb828e1 100644
--- a/key.cpp
+++ b/key.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <assert.h>
+
 #include "key.h"
 
 #include <openssl/x509.h>
@@ -22,9 +24,6 @@
 
 namespace keymaster {
 
-/* static */
-template <> KeyFactoryRegistry* KeyFactoryRegistry::instance_ptr = 0;
-
 Key::Key(const AuthorizationSet& hw_enforced, const AuthorizationSet& sw_enforced,
          keymaster_error_t* error) {
     assert(error);
@@ -34,4 +33,5 @@
     if (authorizations_.is_valid() != AuthorizationSet::OK)
         *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
 }
+
 }  // namespace keymaster
diff --git a/key.h b/key.h
index 0eb1539..c0dc14e 100644
--- a/key.h
+++ b/key.h
@@ -17,16 +17,17 @@
 #ifndef SYSTEM_KEYMASTER_KEY_H_
 #define SYSTEM_KEYMASTER_KEY_H_
 
+#include <UniquePtr.h>
+
 #include <hardware/keymaster_defs.h>
 #include <keymaster/authorization_set.h>
-#include <keymaster/logger.h>
-
-#include "abstract_factory_registry.h"
 
 namespace keymaster {
 
 class Key;
 class KeymasterContext;
+class OperationFactory;
+struct KeymasterKeyBlob;
 
 /**
  * KeyFactory is a abstraction whose subclasses know how to construct a specific subclass of Key.
@@ -37,36 +38,33 @@
     KeyFactory(const KeymasterContext* context) : context_(context) {}
     virtual ~KeyFactory() {}
 
-    // Required for registry
-    typedef keymaster_algorithm_t KeyType;
-    virtual keymaster_algorithm_t registry_key() const = 0;
-
     // Factory methods.
     virtual keymaster_error_t GenerateKey(const AuthorizationSet& key_description,
                                           KeymasterKeyBlob* key_blob, AuthorizationSet* hw_enforced,
-                                          AuthorizationSet* sw_enforced) = 0;
+                                          AuthorizationSet* sw_enforced) const = 0;
 
     virtual keymaster_error_t 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) = 0;
+                                        AuthorizationSet* sw_enforced) const = 0;
 
     virtual keymaster_error_t LoadKey(const KeymasterKeyBlob& key_material,
                                       const AuthorizationSet& hw_enforced,
-                                      const AuthorizationSet& sw_enforced, UniquePtr<Key>* key) = 0;
+                                      const AuthorizationSet& sw_enforced,
+                                      UniquePtr<Key>* key) const = 0;
+
+    virtual OperationFactory* GetOperationFactory(keymaster_purpose_t purpose) const = 0;
 
     // Informational methods.
-    virtual const keymaster_key_format_t* SupportedImportFormats(size_t* format_count) = 0;
-    virtual const keymaster_key_format_t* SupportedExportFormats(size_t* format_count) = 0;
+    virtual const keymaster_key_format_t* SupportedImportFormats(size_t* format_count) const = 0;
+    virtual const keymaster_key_format_t* SupportedExportFormats(size_t* format_count) const = 0;
 
   protected:
     const KeymasterContext* context_;
 };
 
-typedef AbstractFactoryRegistry<KeyFactory> KeyFactoryRegistry;
-
 class KeyBlob;
 class Operation;
 class UnencryptedKeyBlob;
diff --git a/operation.cpp b/operation.cpp
index c680252..dacaf21 100644
--- a/operation.cpp
+++ b/operation.cpp
@@ -18,8 +18,6 @@
 
 namespace keymaster {
 
-DEFINE_ABSTRACT_FACTORY_REGISTRY_INSTANCE(OperationFactory);
-
 bool OperationFactory::supported(keymaster_padding_t padding) const {
     size_t padding_count;
     const keymaster_padding_t* supported_paddings = SupportedPaddingModes(&padding_count);
diff --git a/operation.h b/operation.h
index 00266ca..10e7cf7 100644
--- a/operation.h
+++ b/operation.h
@@ -25,8 +25,6 @@
 #include <hardware/keymaster_defs.h>
 #include <keymaster/logger.h>
 
-#include "abstract_factory_registry.h"
-
 namespace keymaster {
 
 class AuthorizationSet;
@@ -76,8 +74,6 @@
     bool supported(keymaster_digest_t padding) const;
 };
 
-typedef AbstractFactoryRegistry<OperationFactory> OperationFactoryRegistry;
-
 /**
  * Abstract base for all cryptographic operations.
  */
diff --git a/rsa_key.cpp b/rsa_key.cpp
index c8e3a36..94f87a9 100644
--- a/rsa_key.cpp
+++ b/rsa_key.cpp
@@ -20,6 +20,7 @@
 
 #include "openssl_err.h"
 #include "openssl_utils.h"
+#include "rsa_operation.h"
 
 #if defined(OPENSSL_IS_BORINGSSL)
 typedef size_t openssl_size_t;
@@ -29,10 +30,30 @@
 
 namespace keymaster {
 
+static RsaSigningOperationFactory sign_factory;
+static RsaVerificationOperationFactory verify_factory;
+static RsaEncryptionOperationFactory encrypt_factory;
+static RsaDecryptionOperationFactory decrypt_factory;
+
+OperationFactory* RsaKeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const {
+    switch (purpose) {
+    case KM_PURPOSE_SIGN:
+        return &sign_factory;
+    case KM_PURPOSE_VERIFY:
+        return &verify_factory;
+    case KM_PURPOSE_ENCRYPT:
+        return &encrypt_factory;
+    case KM_PURPOSE_DECRYPT:
+        return &decrypt_factory;
+    default:
+        return nullptr;
+    }
+}
+
 keymaster_error_t RsaKeyFactory::GenerateKey(const AuthorizationSet& key_description,
                                              KeymasterKeyBlob* key_blob,
                                              AuthorizationSet* hw_enforced,
-                                             AuthorizationSet* sw_enforced) {
+                                             AuthorizationSet* sw_enforced) const {
     if (!key_blob || !hw_enforced || !sw_enforced)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
@@ -77,7 +98,7 @@
                                            const KeymasterKeyBlob& input_key_material,
                                            KeymasterKeyBlob* output_key_blob,
                                            AuthorizationSet* hw_enforced,
-                                           AuthorizationSet* sw_enforced) {
+                                           AuthorizationSet* sw_enforced) const {
     if (!output_key_blob || !hw_enforced || !sw_enforced)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
@@ -98,7 +119,7 @@
                                                             const KeymasterKeyBlob& key_material,
                                                             AuthorizationSet* updated_description,
                                                             uint64_t* public_exponent,
-                                                            uint32_t* key_size) {
+                                                            uint32_t* key_size) const {
     if (!updated_description || !public_exponent || !key_size)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
@@ -138,7 +159,7 @@
 
 keymaster_error_t RsaKeyFactory::CreateEmptyKey(const AuthorizationSet& hw_enforced,
                                                 const AuthorizationSet& sw_enforced,
-                                                UniquePtr<AsymmetricKey>* key) {
+                                                UniquePtr<AsymmetricKey>* key) const {
     keymaster_error_t error;
     key->reset(new RsaKey(hw_enforced, sw_enforced, &error));
     if (!key->get())
diff --git a/rsa_key.h b/rsa_key.h
index 57fa199..4e2928e 100644
--- a/rsa_key.h
+++ b/rsa_key.h
@@ -27,32 +27,33 @@
   public:
     RsaKeyFactory(const KeymasterContext* context) : AsymmetricKeyFactory(context) {}
 
-    keymaster_algorithm_t registry_key() const override { return KM_ALGORITHM_RSA; }
-    int evp_key_type() override { return EVP_PKEY_RSA; }
+    keymaster_algorithm_t keymaster_key_type() const override { return KM_ALGORITHM_RSA; }
+    int evp_key_type() const override { return EVP_PKEY_RSA; }
 
     keymaster_error_t GenerateKey(const AuthorizationSet& key_description,
                                   KeymasterKeyBlob* key_blob, AuthorizationSet* hw_enforced,
-                                  AuthorizationSet* sw_enforced) override;
+                                  AuthorizationSet* sw_enforced) const override;
     keymaster_error_t 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) override;
+                                AuthorizationSet* sw_enforced) const override;
 
     keymaster_error_t CreateEmptyKey(const AuthorizationSet& hw_enforced,
                                      const AuthorizationSet& sw_enforced,
-                                     UniquePtr<AsymmetricKey>* key) override;
+                                     UniquePtr<AsymmetricKey>* key) const override;
+
+    OperationFactory* GetOperationFactory(keymaster_purpose_t purpose) const override;
 
   protected:
     keymaster_error_t UpdateImportKeyDescription(const AuthorizationSet& key_description,
                                                  keymaster_key_format_t import_key_format,
                                                  const KeymasterKeyBlob& import_key_material,
                                                  AuthorizationSet* updated_description,
-                                                 uint64_t* public_exponent, uint32_t* key_size);
+                                                 uint64_t* public_exponent,
+                                                 uint32_t* key_size) const;
 };
 
-class RsaOperationFactory;
-
 class RsaKey : public AsymmetricKey {
   public:
     RsaKey(const AuthorizationSet& hw_enforced, const AuthorizationSet& sw_enforced,
diff --git a/rsa_keymaster0_key.cpp b/rsa_keymaster0_key.cpp
index 25acbc3..80ce2a3 100644
--- a/rsa_keymaster0_key.cpp
+++ b/rsa_keymaster0_key.cpp
@@ -21,6 +21,8 @@
 #define LOG_TAG "RsaKeymaster0Key"
 #include <cutils/log.h>
 
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/logger.h>
 #include <keymaster/soft_keymaster_context.h>
 
 #include "keymaster0_engine.h"
@@ -38,7 +40,7 @@
 keymaster_error_t RsaKeymaster0KeyFactory::GenerateKey(const AuthorizationSet& key_description,
                                                        KeymasterKeyBlob* key_blob,
                                                        AuthorizationSet* hw_enforced,
-                                                       AuthorizationSet* sw_enforced) {
+                                                       AuthorizationSet* sw_enforced) const {
     if (!key_blob || !hw_enforced || !sw_enforced)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
@@ -74,7 +76,7 @@
 keymaster_error_t RsaKeymaster0KeyFactory::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) {
+    AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const {
     if (!output_key_blob || !hw_enforced || !sw_enforced)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
@@ -108,7 +110,7 @@
 keymaster_error_t RsaKeymaster0KeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
                                                    const AuthorizationSet& hw_enforced,
                                                    const AuthorizationSet& sw_enforced,
-                                                   UniquePtr<Key>* key) {
+                                                   UniquePtr<Key>* key) const {
     if (!key)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
diff --git a/rsa_keymaster0_key.h b/rsa_keymaster0_key.h
index 2b89cdc..2ab4bbf 100644
--- a/rsa_keymaster0_key.h
+++ b/rsa_keymaster0_key.h
@@ -34,22 +34,22 @@
     typedef RsaKeyFactory super;
 
   public:
-    RsaKeymaster0KeyFactory(const SoftKeymasterContext* context,
-                            const Keymaster0Engine* engine);
+    RsaKeymaster0KeyFactory(const SoftKeymasterContext* context, const Keymaster0Engine* engine);
 
     keymaster_error_t GenerateKey(const AuthorizationSet& key_description,
                                   KeymasterKeyBlob* key_blob, AuthorizationSet* hw_enforced,
-                                  AuthorizationSet* sw_enforced) override;
+                                  AuthorizationSet* sw_enforced) const override;
 
     keymaster_error_t 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) override;
+                                AuthorizationSet* sw_enforced) const override;
 
     keymaster_error_t LoadKey(const KeymasterKeyBlob& key_material,
                               const AuthorizationSet& hw_enforced,
-                              const AuthorizationSet& sw_enforced, UniquePtr<Key>* key) override;
+                              const AuthorizationSet& sw_enforced,
+                              UniquePtr<Key>* key) const override;
 
   private:
     const Keymaster0Engine* engine_;
diff --git a/rsa_operation.cpp b/rsa_operation.cpp
index 7761730..903f570 100644
--- a/rsa_operation.cpp
+++ b/rsa_operation.cpp
@@ -30,23 +30,6 @@
 
 static const int MIN_PSS_SALT_LEN = 8 /* salt len */ + 2 /* overhead */;
 
-/**
- * Abstract base for all RSA operation factories.  This class exists mainly to centralize some code
- * common to all RSA operation factories.
- */
-class RsaOperationFactory : public OperationFactory {
-  public:
-    KeyType registry_key() const override { return KeyType(KM_ALGORITHM_RSA, purpose()); }
-    virtual keymaster_purpose_t purpose() const = 0;
-
-  protected:
-    bool GetAndValidatePadding(const AuthorizationSet& begin_params, const Key& key,
-                               keymaster_padding_t* padding, keymaster_error_t* error) const;
-    bool GetAndValidateDigest(const AuthorizationSet& begin_params, const Key& key,
-                              keymaster_digest_t* digest, keymaster_error_t* error) const;
-    static RSA* GetRsaKey(const Key& key, keymaster_error_t* error);
-};
-
 bool RsaOperationFactory::GetAndValidatePadding(const AuthorizationSet& begin_params,
                                                 const Key& key, keymaster_padding_t* padding,
                                                 keymaster_error_t* error) const {
@@ -104,30 +87,17 @@
 static const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN,
                                                             KM_PAD_RSA_PSS};
 
-/**
- * Abstract base for RSA operations that digest their input (signing and verification).  This class
- * does most of the work of creation of RSA digesting operations, delegating only the actual
- * operation instantiation.
- */
-class RsaDigestingOperationFactory : public RsaOperationFactory {
-  public:
-    virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
-                                       keymaster_error_t* error);
+const keymaster_digest_t*
+RsaDigestingOperationFactory::SupportedDigests(size_t* digest_count) const {
+    *digest_count = array_length(supported_digests);
+    return supported_digests;
+}
 
-    virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
-        *digest_count = array_length(supported_digests);
-        return supported_digests;
-    }
-
-    virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
-        *padding_mode_count = array_length(supported_sig_padding);
-        return supported_sig_padding;
-    }
-
-  private:
-    virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
-                                            RSA* key) = 0;
-};
+const keymaster_padding_t*
+RsaDigestingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
+    *padding_mode_count = array_length(supported_sig_padding);
+    return supported_sig_padding;
+}
 
 Operation* RsaDigestingOperationFactory::CreateOperation(const Key& key,
                                                          const AuthorizationSet& begin_params,
@@ -149,29 +119,6 @@
 static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_RSA_OAEP,
                                                               KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
 
-/**
- * Abstract base for en/de-crypting RSA operation factories.  This class does most of the work of
- * creating such operations, delegating only the actual operation instantiation.
- */
-class RsaCryptingOperationFactory : public RsaOperationFactory {
-  public:
-    virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
-                                       keymaster_error_t* error);
-
-    virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
-        *padding_mode_count = array_length(supported_crypt_padding);
-        return supported_crypt_padding;
-    }
-
-    virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
-        *digest_count = 0;
-        return NULL;
-    }
-
-  private:
-    virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) = 0;
-};
-
 Operation* RsaCryptingOperationFactory::CreateOperation(const Key& key,
                                                         const AuthorizationSet& begin_params,
                                                         keymaster_error_t* error) {
@@ -187,53 +134,17 @@
     return op;
 }
 
-/**
- * Concrete factory for RSA signing operations.
- */
-class RsaSigningOperationFactory : public RsaDigestingOperationFactory {
-  public:
-    virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_SIGN; }
-    virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
-                                            RSA* key) {
-        return new RsaSignOperation(digest, padding, key);
-    }
-};
-static OperationFactoryRegistry::Registration<RsaSigningOperationFactory> sign_registration;
+const keymaster_padding_t*
+RsaCryptingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
+    *padding_mode_count = array_length(supported_crypt_padding);
+    return supported_crypt_padding;
+}
 
-/**
- * Concrete factory for RSA signing operations.
- */
-class RsaVerificationOperationFactory : public RsaDigestingOperationFactory {
-    virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_VERIFY; }
-    virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
-                                            RSA* key) {
-        return new RsaVerifyOperation(digest, padding, key);
-    }
-};
-static OperationFactoryRegistry::Registration<RsaVerificationOperationFactory> verify_registration;
-
-/**
- * Concrete factory for RSA signing operations.
- */
-class RsaEncryptionOperationFactory : public RsaCryptingOperationFactory {
-    virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_ENCRYPT; }
-    virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) {
-        return new RsaEncryptOperation(padding, key);
-    }
-};
-static OperationFactoryRegistry::Registration<RsaEncryptionOperationFactory> encrypt_registration;
-
-/**
- * Concrete factory for RSA signing operations.
- */
-class RsaDecryptionOperationFactory : public RsaCryptingOperationFactory {
-    virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_DECRYPT; }
-    virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) {
-        return new RsaDecryptOperation(padding, key);
-    }
-};
-
-static OperationFactoryRegistry::Registration<RsaDecryptionOperationFactory> decrypt_registration;
+const keymaster_digest_t*
+RsaCryptingOperationFactory::SupportedDigests(size_t* digest_count) const {
+    *digest_count = 0;
+    return NULL;
+}
 
 RsaOperation::~RsaOperation() {
     if (rsa_key_ != NULL)
diff --git a/rsa_operation.h b/rsa_operation.h
index 586aaa1..ee46283 100644
--- a/rsa_operation.h
+++ b/rsa_operation.h
@@ -37,13 +37,13 @@
         : Operation(purpose), rsa_key_(key), padding_(padding) {}
     ~RsaOperation();
 
-    virtual keymaster_error_t Begin(const AuthorizationSet& /* input_params */,
-                                    AuthorizationSet* /* output_params */) {
+    keymaster_error_t Begin(const AuthorizationSet& /* input_params */,
+                            AuthorizationSet* /* output_params */) override {
         return KM_ERROR_OK;
     }
-    virtual keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input,
-                                     Buffer* output, size_t* input_consumed);
-    virtual keymaster_error_t Abort() { return KM_ERROR_OK; }
+    keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input,
+                             Buffer* output, size_t* input_consumed) override;
+    keymaster_error_t Abort() override { return KM_ERROR_OK; }
 
   protected:
     keymaster_error_t StoreData(const Buffer& input, size_t* input_consumed);
@@ -65,10 +65,10 @@
                           keymaster_padding_t padding, RSA* key);
     ~RsaDigestingOperation();
 
-    virtual keymaster_error_t Begin(const AuthorizationSet& input_params,
-                                    AuthorizationSet* output_params);
-    virtual keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input,
-                                     Buffer* output, size_t* input_consumed);
+    keymaster_error_t Begin(const AuthorizationSet& input_params,
+                            AuthorizationSet* output_params) override;
+    keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input,
+                             Buffer* output, size_t* input_consumed) override;
 
   protected:
     bool require_digest() const { return padding_ == KM_PAD_RSA_PSS; }
@@ -89,8 +89,8 @@
   public:
     RsaSignOperation(keymaster_digest_t digest, keymaster_padding_t padding, RSA* key)
         : RsaDigestingOperation(KM_PURPOSE_SIGN, digest, padding, key) {}
-    virtual keymaster_error_t Finish(const AuthorizationSet& additional_params,
-                                     const Buffer& signature, Buffer* output);
+    keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& signature,
+                             Buffer* output) override;
 
   private:
     keymaster_error_t SignUndigested(Buffer* output);
@@ -107,8 +107,8 @@
   public:
     RsaVerifyOperation(keymaster_digest_t digest, keymaster_padding_t padding, RSA* key)
         : RsaDigestingOperation(KM_PURPOSE_VERIFY, digest, padding, key) {}
-    virtual keymaster_error_t Finish(const AuthorizationSet& additional_params,
-                                     const Buffer& signature, Buffer* output);
+    keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& signature,
+                             Buffer* output) override;
 
   private:
     keymaster_error_t VerifyUndigested(const Buffer& signature);
@@ -123,8 +123,8 @@
   public:
     RsaEncryptOperation(keymaster_padding_t padding, RSA* key)
         : RsaOperation(KM_PURPOSE_ENCRYPT, padding, key) {}
-    virtual keymaster_error_t Finish(const AuthorizationSet& additional_params,
-                                     const Buffer& signature, Buffer* output);
+    keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& signature,
+                             Buffer* output) override;
 };
 
 /**
@@ -134,8 +134,100 @@
   public:
     RsaDecryptOperation(keymaster_padding_t padding, RSA* key)
         : RsaOperation(KM_PURPOSE_DECRYPT, padding, key) {}
-    virtual keymaster_error_t Finish(const AuthorizationSet& additional_params,
-                                     const Buffer& signature, Buffer* output);
+    keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& signature,
+                             Buffer* output) override;
+};
+
+/**
+ * Abstract base for all RSA operation factories.  This class exists mainly to centralize some code
+ * common to all RSA operation factories.
+ */
+class RsaOperationFactory : public OperationFactory {
+  public:
+    KeyType registry_key() const override { return KeyType(KM_ALGORITHM_RSA, purpose()); }
+    virtual keymaster_purpose_t purpose() const = 0;
+
+  protected:
+    bool GetAndValidatePadding(const AuthorizationSet& begin_params, const Key& key,
+                               keymaster_padding_t* padding, keymaster_error_t* error) const;
+    bool GetAndValidateDigest(const AuthorizationSet& begin_params, const Key& key,
+                              keymaster_digest_t* digest, keymaster_error_t* error) const;
+    static RSA* GetRsaKey(const Key& key, keymaster_error_t* error);
+};
+
+/**
+ * Abstract base for RSA operations that digest their input (signing and verification).  This class
+ * does most of the work of creation of RSA digesting operations, delegating only the actual
+ * operation instantiation.
+ */
+class RsaDigestingOperationFactory : public RsaOperationFactory {
+  public:
+    virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
+                                       keymaster_error_t* error);
+    const keymaster_digest_t* SupportedDigests(size_t* digest_count) const override;
+    const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const override;
+
+  private:
+    virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
+                                            RSA* key) = 0;
+};
+
+/**
+ * Abstract base for en/de-crypting RSA operation factories.  This class does most of the work of
+ * creating such operations, delegating only the actual operation instantiation.
+ */
+class RsaCryptingOperationFactory : public RsaOperationFactory {
+  public:
+    virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
+                                       keymaster_error_t* error);
+    const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const override;
+    const keymaster_digest_t* SupportedDigests(size_t* digest_count) const override;
+
+  private:
+    virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) = 0;
+};
+
+/**
+ * Concrete factory for RSA signing operations.
+ */
+class RsaSigningOperationFactory : public RsaDigestingOperationFactory {
+  public:
+    keymaster_purpose_t purpose() const override { return KM_PURPOSE_SIGN; }
+    Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
+                                    RSA* key) override {
+        return new RsaSignOperation(digest, padding, key);
+    }
+};
+
+/**
+ * Concrete factory for RSA signing operations.
+ */
+class RsaVerificationOperationFactory : public RsaDigestingOperationFactory {
+    keymaster_purpose_t purpose() const override { return KM_PURPOSE_VERIFY; }
+    Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
+                                    RSA* key) override {
+        return new RsaVerifyOperation(digest, padding, key);
+    }
+};
+
+/**
+ * Concrete factory for RSA signing operations.
+ */
+class RsaEncryptionOperationFactory : public RsaCryptingOperationFactory {
+    keymaster_purpose_t purpose() const override { return KM_PURPOSE_ENCRYPT; }
+    Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) override {
+        return new RsaEncryptOperation(padding, key);
+    }
+};
+
+/**
+ * Concrete factory for RSA signing operations.
+ */
+class RsaDecryptionOperationFactory : public RsaCryptingOperationFactory {
+    keymaster_purpose_t purpose() const override { return KM_PURPOSE_DECRYPT; }
+    Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) override {
+        return new RsaDecryptOperation(padding, key);
+    }
 };
 
 }  // namespace keymaster
diff --git a/soft_keymaster_context.cpp b/soft_keymaster_context.cpp
index 8751a27..bda5dbe 100644
--- a/soft_keymaster_context.cpp
+++ b/soft_keymaster_context.cpp
@@ -47,21 +47,45 @@
 const KeymasterKeyBlob MASTER_KEY(master_key_bytes, array_length(master_key_bytes));
 }  // anonymous namespace
 
-class SoftKeymasterKeyRegistrations {
-  public:
-    SoftKeymasterKeyRegistrations(SoftKeymasterContext* context, Keymaster0Engine* engine)
-        : rsa_(context, engine), ec_(context, engine), hmac_(context), aes_(context) {}
-
-    KeyFactoryRegistry::Registration<RsaKeymaster0KeyFactory> rsa_;
-    KeyFactoryRegistry::Registration<EcdsaKeymaster0KeyFactory> ec_;
-    KeyFactoryRegistry::Registration<HmacKeyFactory> hmac_;
-    KeyFactoryRegistry::Registration<AesKeyFactory> aes_;
-};
-
 SoftKeymasterContext::SoftKeymasterContext(keymaster0_device_t* keymaster0_device) {
     if (keymaster0_device && (keymaster0_device->flags & KEYMASTER_SOFTWARE_ONLY) == 0)
         engine_.reset(new Keymaster0Engine(keymaster0_device));
-    registrations_.reset(new SoftKeymasterKeyRegistrations(this, engine_.get()));
+    rsa_factory_.reset(new RsaKeymaster0KeyFactory(this, engine_.get()));
+    ec_factory_.reset(new EcdsaKeymaster0KeyFactory(this, engine_.get()));
+    aes_factory_.reset(new AesKeyFactory(this));
+    hmac_factory_.reset(new HmacKeyFactory(this));
+}
+
+KeyFactory* SoftKeymasterContext::GetKeyFactory(keymaster_algorithm_t algorithm) const {
+    switch (algorithm) {
+    case KM_ALGORITHM_RSA:
+        return rsa_factory_.get();
+    case KM_ALGORITHM_EC:
+        return ec_factory_.get();
+    case KM_ALGORITHM_AES:
+        return aes_factory_.get();
+    case KM_ALGORITHM_HMAC:
+        return hmac_factory_.get();
+    default:
+        return nullptr;
+    }
+}
+
+static keymaster_algorithm_t supported_algorithms[] = {KM_ALGORITHM_RSA, KM_ALGORITHM_EC,
+                                                       KM_ALGORITHM_AES, KM_ALGORITHM_HMAC};
+
+keymaster_algorithm_t*
+SoftKeymasterContext::GetSupportedAlgorithms(size_t* algorithms_count) const {
+    *algorithms_count = array_length(supported_algorithms);
+    return supported_algorithms;
+}
+
+OperationFactory* SoftKeymasterContext::GetOperationFactory(keymaster_algorithm_t algorithm,
+                                                            keymaster_purpose_t purpose) const {
+    KeyFactory* key_factory = GetKeyFactory(algorithm);
+    if (!key_factory)
+        return nullptr;
+    return key_factory->GetOperationFactory(purpose);
 }
 
 static keymaster_error_t TranslateAuthorizationSetError(AuthorizationSet::Error err) {
@@ -137,7 +161,6 @@
                                                       KeymasterKeyBlob* blob,
                                                       AuthorizationSet* hw_enforced,
                                                       AuthorizationSet* sw_enforced) const {
-
     keymaster_error_t error = SetAuthorizations(key_description, origin, hw_enforced, sw_enforced);
     if (error != KM_ERROR_OK)
         return error;
diff --git a/symmetric_key.cpp b/symmetric_key.cpp
index 68fa6f1..016b40e 100644
--- a/symmetric_key.cpp
+++ b/symmetric_key.cpp
@@ -21,6 +21,7 @@
 #include <openssl/err.h>
 #include <openssl/rand.h>
 
+#include <keymaster/android_keymaster_utils.h>
 #include <keymaster/logger.h>
 #include <keymaster/keymaster_context.h>
 
@@ -33,7 +34,7 @@
 keymaster_error_t SymmetricKeyFactory::GenerateKey(const AuthorizationSet& key_description,
                                                    KeymasterKeyBlob* key_blob,
                                                    AuthorizationSet* hw_enforced,
-                                                   AuthorizationSet* sw_enforced) {
+                                                   AuthorizationSet* sw_enforced) const {
     if (!key_blob || !hw_enforced || !sw_enforced)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
@@ -62,7 +63,7 @@
                                                  const KeymasterKeyBlob& input_key_material,
                                                  KeymasterKeyBlob* output_key_blob,
                                                  AuthorizationSet* hw_enforced,
-                                                 AuthorizationSet* sw_enforced) {
+                                                 AuthorizationSet* sw_enforced) const {
     if (!output_key_blob || !hw_enforced || !sw_enforced)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
@@ -92,7 +93,8 @@
 }
 
 static const keymaster_key_format_t supported_import_formats[] = {KM_KEY_FORMAT_RAW};
-const keymaster_key_format_t* SymmetricKeyFactory::SupportedImportFormats(size_t* format_count) {
+const keymaster_key_format_t*
+SymmetricKeyFactory::SupportedImportFormats(size_t* format_count) const {
     *format_count = array_length(supported_import_formats);
     return supported_import_formats;
 }
diff --git a/symmetric_key.h b/symmetric_key.h
index 3e39364..c83abc7 100644
--- a/symmetric_key.h
+++ b/symmetric_key.h
@@ -29,22 +29,22 @@
 
     keymaster_error_t GenerateKey(const AuthorizationSet& key_description,
                                   KeymasterKeyBlob* key_blob, AuthorizationSet* hw_enforced,
-                                  AuthorizationSet* sw_enforced) override;
+                                  AuthorizationSet* sw_enforced) const override;
     keymaster_error_t 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) override;
+                                AuthorizationSet* sw_enforced) const override;
 
-    virtual const keymaster_key_format_t* SupportedImportFormats(size_t* format_count);
-    virtual const keymaster_key_format_t* SupportedExportFormats(size_t* format_count) {
+    virtual const keymaster_key_format_t* SupportedImportFormats(size_t* format_count) const;
+    virtual const keymaster_key_format_t* SupportedExportFormats(size_t* format_count) const {
         return NoFormats(format_count);
     };
 
   private:
     virtual bool key_size_supported(size_t key_size_bits) const = 0;
 
-    const keymaster_key_format_t* NoFormats(size_t* format_count) {
+    const keymaster_key_format_t* NoFormats(size_t* format_count) const {
         *format_count = 0;
         return NULL;
     }