Provide fallback for keymaster implementations
Some implementations won't support ECDSA or DSA, so provide a fallback
for them by using the softkeymaster implementation. This will allow us
to universally support ECDSA and DSA on all platforms regardless of HAL
version.
Bug: 10600582
Change-Id: Ib842816cc1415ec00abb7d22c8e9b6bbe58f6a86
diff --git a/softkeymaster/Android.mk b/softkeymaster/Android.mk
index 8e19a93..0064d01 100644
--- a/softkeymaster/Android.mk
+++ b/softkeymaster/Android.mk
@@ -15,23 +15,27 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-
LOCAL_MODULE := keystore.default
-
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
-
-LOCAL_SRC_FILES := keymaster_openssl.cpp
-
+LOCAL_SRC_FILES := module.cpp
LOCAL_C_INCLUDES := \
system/security/keystore \
external/openssl/include
-
-LOCAL_C_FLAGS = -fvisibility=hidden -Wall -Werror
-
-LOCAL_SHARED_LIBRARIES := libcrypto liblog libkeystore_binder
-
+LOCAL_CFLAGS = -fvisibility=hidden -Wall -Werror
+LOCAL_SHARED_LIBRARIES := libcrypto liblog libkeystore_binder libsoftkeymaster
LOCAL_MODULE_TAGS := optional
-
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_SHARED_LIBRARY)
+include $(CLEAR_VARS)
+LOCAL_MODULE := libsoftkeymaster
+LOCAL_SRC_FILES := keymaster_openssl.cpp
+LOCAL_C_INCLUDES := \
+ system/security/keystore \
+ external/openssl/include
+LOCAL_CFLAGS = -fvisibility=hidden -Wall -Werror
+LOCAL_SHARED_LIBRARIES := libcrypto liblog libkeystore_binder
+LOCAL_MODULE_TAGS := optional
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
include $(BUILD_SHARED_LIBRARY)
diff --git a/softkeymaster/include/keymaster/softkeymaster.h b/softkeymaster/include/keymaster/softkeymaster.h
new file mode 100644
index 0000000..7d43099
--- /dev/null
+++ b/softkeymaster/include/keymaster/softkeymaster.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hardware/keymaster.h>
+
+#ifndef SOFTKEYMASTER_INCLUDE_KEYMASTER_SOFTKEYMASTER_H
+#define SOFTKEYMASTER_INCLUDE_KEYMASTER_SOFTKEYMASTER_H
+
+int openssl_generate_keypair(const keymaster_device_t* dev,
+ const keymaster_keypair_t key_type, const void* key_params,
+ uint8_t** keyBlob, size_t* keyBlobLength);
+
+int openssl_import_keypair(const keymaster_device_t* dev,
+ const uint8_t* key, const size_t key_length,
+ uint8_t** key_blob, size_t* key_blob_length);
+
+int openssl_get_keypair_public(const struct keymaster_device* dev,
+ const uint8_t* key_blob, const size_t key_blob_length,
+ uint8_t** x509_data, size_t* x509_data_length);
+
+int openssl_sign_data(const keymaster_device_t* dev,
+ const void* params,
+ const uint8_t* keyBlob, const size_t keyBlobLength,
+ const uint8_t* data, const size_t dataLength,
+ uint8_t** signedData, size_t* signedDataLength);
+
+int openssl_verify_data(const keymaster_device_t* dev,
+ const void* params,
+ const uint8_t* keyBlob, const size_t keyBlobLength,
+ const uint8_t* signedData, const size_t signedDataLength,
+ const uint8_t* signature, const size_t signatureLength);
+
+#endif /* SOFTKEYMASTER_INCLUDE_KEYMASTER_SOFTKEYMASTER_H */
diff --git a/softkeymaster/keymaster_openssl.cpp b/softkeymaster/keymaster_openssl.cpp
index 19ec999..4aaaea2 100644
--- a/softkeymaster/keymaster_openssl.cpp
+++ b/softkeymaster/keymaster_openssl.cpp
@@ -194,7 +194,6 @@
ALOGE("public key length encoding error: size=%ld, end=%d", publicLen, end - p);
return NULL;
}
- const uint8_t *pubKey = p;
p += publicLen;
if (end - p < 2) {
@@ -378,11 +377,10 @@
return 0;
}
-static int openssl_generate_keypair(const keymaster_device_t* dev,
+__attribute__ ((visibility ("default")))
+int openssl_generate_keypair(const keymaster_device_t*,
const keymaster_keypair_t key_type, const void* key_params,
uint8_t** keyBlob, size_t* keyBlobLength) {
- ssize_t privateLen, publicLen;
-
Unique_EVP_PKEY pkey(EVP_PKEY_new());
if (pkey.get() == NULL) {
logOpenSSLError("openssl_generate_keypair");
@@ -416,11 +414,10 @@
return 0;
}
-static int openssl_import_keypair(const keymaster_device_t* dev,
+__attribute__ ((visibility ("default")))
+int openssl_import_keypair(const keymaster_device_t*,
const uint8_t* key, const size_t key_length,
uint8_t** key_blob, size_t* key_blob_length) {
- int response = -1;
-
if (key == NULL) {
ALOGW("input key == NULL");
return -1;
@@ -450,7 +447,8 @@
return 0;
}
-static int openssl_get_keypair_public(const struct keymaster_device* dev,
+__attribute__ ((visibility ("default")))
+int openssl_get_keypair_public(const struct keymaster_device*,
const uint8_t* key_blob, const size_t key_blob_length,
uint8_t** x509_data, size_t* x509_data_length) {
@@ -588,16 +586,12 @@
return 0;
}
-static int openssl_sign_data(const keymaster_device_t* dev,
+__attribute__ ((visibility ("default")))
+int openssl_sign_data(const keymaster_device_t*,
const void* params,
const uint8_t* keyBlob, const size_t keyBlobLength,
const uint8_t* data, const size_t dataLength,
uint8_t** signedData, size_t* signedDataLength) {
-
- int result = -1;
- EVP_MD_CTX ctx;
- size_t maxSize;
-
if (data == NULL) {
ALOGW("input data to sign == NULL");
return -1;
@@ -711,7 +705,8 @@
return result == 0 ? 0 : -1;
}
-static int openssl_verify_data(const keymaster_device_t* dev,
+__attribute__ ((visibility ("default")))
+int openssl_verify_data(const keymaster_device_t*,
const void* params,
const uint8_t* keyBlob, const size_t keyBlobLength,
const uint8_t* signedData, const size_t signedDataLength,
@@ -728,7 +723,11 @@
}
int type = EVP_PKEY_type(pkey->type);
- if (type == EVP_PKEY_RSA) {
+ if (type == EVP_PKEY_DSA) {
+ keymaster_dsa_sign_params_t* sign_params = (keymaster_dsa_sign_params_t*) params;
+ return verify_dsa(pkey.get(), sign_params, signedData, signedDataLength, signature,
+ signatureLength);
+ } else if (type == EVP_PKEY_RSA) {
keymaster_rsa_sign_params_t* sign_params = (keymaster_rsa_sign_params_t*) params;
return verify_rsa(pkey.get(), sign_params, signedData, signedDataLength, signature,
signatureLength);
@@ -741,63 +740,3 @@
return -1;
}
}
-
-/* Close an opened OpenSSL instance */
-static int openssl_close(hw_device_t *dev) {
- delete dev;
- return 0;
-}
-
-/*
- * Generic device handling
- */
-static int openssl_open(const hw_module_t* module, const char* name,
- hw_device_t** device) {
- if (strcmp(name, KEYSTORE_KEYMASTER) != 0)
- return -EINVAL;
-
- Unique_keymaster_device_t dev(new keymaster_device_t);
- if (dev.get() == NULL)
- return -ENOMEM;
-
- dev->common.tag = HARDWARE_DEVICE_TAG;
- dev->common.version = 1;
- dev->common.module = (struct hw_module_t*) module;
- dev->common.close = openssl_close;
-
- dev->flags = KEYMASTER_SOFTWARE_ONLY;
-
- dev->generate_keypair = openssl_generate_keypair;
- dev->import_keypair = openssl_import_keypair;
- dev->get_keypair_public = openssl_get_keypair_public;
- dev->delete_keypair = NULL;
- dev->delete_all = NULL;
- dev->sign_data = openssl_sign_data;
- dev->verify_data = openssl_verify_data;
-
- ERR_load_crypto_strings();
- ERR_load_BIO_strings();
-
- *device = reinterpret_cast<hw_device_t*>(dev.release());
-
- return 0;
-}
-
-static struct hw_module_methods_t keystore_module_methods = {
- open: openssl_open,
-};
-
-struct keystore_module HAL_MODULE_INFO_SYM
-__attribute__ ((visibility ("default"))) = {
- common: {
- tag: HARDWARE_MODULE_TAG,
- version_major: 1,
- version_minor: 0,
- id: KEYSTORE_HARDWARE_MODULE_ID,
- name: "Keymaster OpenSSL HAL",
- author: "The Android Open Source Project",
- methods: &keystore_module_methods,
- dso: 0,
- reserved: {},
- },
-};
diff --git a/softkeymaster/module.cpp b/softkeymaster/module.cpp
new file mode 100644
index 0000000..758dfe7
--- /dev/null
+++ b/softkeymaster/module.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <errno.h>
+#include <string.h>
+#include <stdint.h>
+
+#include <keymaster/softkeymaster.h>
+
+#include <keystore/keystore.h>
+
+#include <hardware/hardware.h>
+#include <hardware/keymaster.h>
+
+#include <openssl/err.h>
+
+#include <utils/UniquePtr.h>
+
+// For debugging
+//#define LOG_NDEBUG 0
+
+#define LOG_TAG "OpenSSLKeyMaster"
+#include <cutils/log.h>
+
+typedef UniquePtr<keymaster_device_t> Unique_keymaster_device_t;
+
+/* Close an opened OpenSSL instance */
+static int openssl_close(hw_device_t *dev) {
+ delete dev;
+ return 0;
+}
+
+/*
+ * Generic device handling
+ */
+static int openssl_open(const hw_module_t* module, const char* name,
+ hw_device_t** device) {
+ if (strcmp(name, KEYSTORE_KEYMASTER) != 0)
+ return -EINVAL;
+
+ Unique_keymaster_device_t dev(new keymaster_device_t);
+ if (dev.get() == NULL)
+ return -ENOMEM;
+
+ dev->common.tag = HARDWARE_DEVICE_TAG;
+ dev->common.version = 1;
+ dev->common.module = (struct hw_module_t*) module;
+ dev->common.close = openssl_close;
+
+ dev->flags = KEYMASTER_SOFTWARE_ONLY;
+
+ dev->generate_keypair = openssl_generate_keypair;
+ dev->import_keypair = openssl_import_keypair;
+ dev->get_keypair_public = openssl_get_keypair_public;
+ dev->delete_keypair = NULL;
+ dev->delete_all = NULL;
+ dev->sign_data = openssl_sign_data;
+ dev->verify_data = openssl_verify_data;
+
+ ERR_load_crypto_strings();
+ ERR_load_BIO_strings();
+
+ *device = reinterpret_cast<hw_device_t*>(dev.release());
+
+ return 0;
+}
+
+static struct hw_module_methods_t keystore_module_methods = {
+ open: openssl_open,
+};
+
+struct keystore_module HAL_MODULE_INFO_SYM
+__attribute__ ((visibility ("default"))) = {
+ common: {
+ tag: HARDWARE_MODULE_TAG,
+ module_api_version: KEYMASTER_MODULE_API_VERSION_0_2,
+ hal_api_version: HARDWARE_HAL_API_VERSION,
+ id: KEYSTORE_HARDWARE_MODULE_ID,
+ name: "Keymaster OpenSSL HAL",
+ author: "The Android Open Source Project",
+ methods: &keystore_module_methods,
+ dso: 0,
+ reserved: {},
+ },
+};