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;
}