trusty: keymaster: Remove legacy support

Library based HALs have been deprecated for several years now, and
Keymaster 2 based testing is woefully out of date compared to running
VTS against the modern 3.0 and 4.0 implementations.

Purging these modules and their resulting dependencies will make it
easier for the central system/keymaster repository to move forwards.

Test: mm
Bug: 150239636
Change-Id: Ic2ddbe685a50e65f9db25f682ad33105195efa8a
This commit is contained in:
Matthew Maurer 2020-02-25 12:51:59 -08:00
parent 7ef2b1d853
commit 1010727a48
6 changed files with 0 additions and 2055 deletions

View file

@ -14,70 +14,6 @@
// limitations under the License.
//
// WARNING: Everything listed here will be built on ALL platforms,
// including x86, the emulator, and the SDK. Modules must be uniquely
// named (liblights.panda), and must build everywhere, or limit themselves
// to only building on ARM if they include assembly. Individual makefiles
// are responsible for having their own logic, for fine-grained control.
// trusty_keymaster is a binary used only for on-device testing. It
// runs Trusty Keymaster through a basic set of operations with RSA
// and ECDSA keys.
cc_binary {
name: "trusty_keymaster_tipc",
vendor: true,
srcs: [
"ipc/trusty_keymaster_ipc.cpp",
"legacy/trusty_keymaster_device.cpp",
"legacy/trusty_keymaster_main.cpp",
],
cflags: [
"-Wall",
"-Werror",
],
local_include_dirs: ["include"],
shared_libs: [
"libcrypto",
"libcutils",
"libkeymaster_portable",
"libtrusty",
"libkeymaster_messages",
"libsoftkeymasterdevice",
"liblog",
],
}
// keystore.trusty is the HAL used by keystore on Trusty devices.
cc_library_shared {
name: "keystore.trusty",
vendor: true,
relative_install_path: "hw",
srcs: [
"ipc/trusty_keymaster_ipc.cpp",
"legacy/module.cpp",
"legacy/trusty_keymaster_device.cpp",
],
cflags: [
"-fvisibility=hidden",
"-Wall",
"-Werror",
],
local_include_dirs: ["include"],
shared_libs: [
"libcrypto",
"libkeymaster_messages",
"libtrusty",
"liblog",
"libcutils",
],
header_libs: ["libhardware_headers"],
}
cc_binary {
name: "android.hardware.keymaster@3.0-service.trusty",
defaults: ["hidl_defaults"],

View file

@ -1,199 +0,0 @@
#####
# Local unit test Makefile
#
# This makefile builds and runs the trusty_keymaster unit tests locally on the development
# machine, not on an Android device.
#
# To build and run these tests, one pre-requisite must be manually installed: BoringSSL.
# This Makefile expects to find BoringSSL in a directory adjacent to $ANDROID_BUILD_TOP.
# To get and build it, first install the Ninja build tool (e.g. apt-get install
# ninja-build), then do:
#
# cd $ANDROID_BUILD_TOP/..
# git clone https://boringssl.googlesource.com/boringssl
# cd boringssl
# mdkir build
# cd build
# cmake -GNinja ..
# ninja
#
# Then return to $ANDROID_BUILD_TOP/system/keymaster and run "make".
#####
BASE=../../../..
SUBS=system/core \
system/keymaster \
hardware/libhardware \
external/gtest
GTEST=$(BASE)/external/gtest
KM=$(BASE)/system/keymaster
INCLUDES=$(foreach dir,$(SUBS),-I $(BASE)/$(dir)/include) \
-I $(BASE)/libnativehelper/include/nativehelper \
-I ../tipc/include \
-I $(BASE)/system/keymaster \
-I $(GTEST) \
-I$(BASE)/../boringssl/include
ifdef USE_CLANG
CC=/usr/bin/clang
CXX=/usr/bin/clang
CLANG_TEST_DEFINE=-DKEYMASTER_CLANG_TEST_BUILD
COMPILER_SPECIFIC_ARGS=-std=c++11 $(CLANG_TEST_DEFINE)
else
COMPILER_SPECIFIC_ARGS=-std=c++0x -fprofile-arcs
endif
CPPFLAGS=$(INCLUDES) -g -O0 -MD
CXXFLAGS=-Wall -Werror -Wno-unused -Winit-self -Wpointer-arith -Wunused-parameter \
-Wmissing-declarations -ftest-coverage \
-Wno-deprecated-declarations -fno-exceptions -DKEYMASTER_NAME_TAGS \
$(COMPILER_SPECIFIC_ARGS)
LDLIBS=-L$(BASE)/../boringssl/build/crypto -lcrypto -lpthread -lstdc++
CPPSRCS=\
$(KM)/aead_mode_operation.cpp \
$(KM)/aes_key.cpp \
$(KM)/aes_operation.cpp \
$(KM)/android_keymaster.cpp \
$(KM)/android_keymaster_messages.cpp \
$(KM)/android_keymaster_messages_test.cpp \
$(KM)/android_keymaster_test.cpp \
$(KM)/android_keymaster_test_utils.cpp \
$(KM)/android_keymaster_utils.cpp \
$(KM)/asymmetric_key.cpp \
$(KM)/auth_encrypted_key_blob.cpp \
$(KM)/auth_encrypted_key_blob.cpp \
$(KM)/authorization_set.cpp \
$(KM)/authorization_set_test.cpp \
$(KM)/ec_key.cpp \
$(KM)/ec_keymaster0_key.cpp \
$(KM)/ecdsa_operation.cpp \
$(KM)/hmac_key.cpp \
$(KM)/hmac_operation.cpp \
$(KM)/integrity_assured_key_blob.cpp \
$(KM)/key.cpp \
$(KM)/key_blob_test.cpp \
$(KM)/keymaster0_engine.cpp \
$(KM)/logger.cpp \
$(KM)/ocb_utils.cpp \
$(KM)/openssl_err.cpp \
$(KM)/openssl_utils.cpp \
$(KM)/operation.cpp \
$(KM)/operation_table.cpp \
$(KM)/rsa_key.cpp \
$(KM)/rsa_keymaster0_key.cpp \
$(KM)/rsa_operation.cpp \
$(KM)/serializable.cpp \
$(KM)/soft_keymaster_context.cpp \
$(KM)/symmetric_key.cpp \
$(KM)/unencrypted_key_blob.cpp \
trusty_keymaster_device.cpp \
trusty_keymaster_device_test.cpp
CCSRCS=$(GTEST)/src/gtest-all.cc
CSRCS=ocb.c
OBJS=$(CPPSRCS:.cpp=.o) $(CCSRCS:.cc=.o) $(CSRCS:.c=.o)
DEPS=$(CPPSRCS:.cpp=.d) $(CCSRCS:.cc=.d) $(CSRCS:.c=.d)
GCDA=$(CPPSRCS:.cpp=.gcda) $(CCSRCS:.cc=.gcda) $(CSRCS:.c=.gcda)
GCNO=$(CPPSRCS:.cpp=.gcno) $(CCSRCS:.cc=.gcno) $(CSRCS:.c=.gcno)
LINK.o=$(LINK.cc)
BINARIES=trusty_keymaster_device_test
ifdef TRUSTY
BINARIES += trusty_keymaster_device_test
endif # TRUSTY
.PHONY: coverage memcheck massif clean run
%.run: %
./$<
touch $@
run: $(BINARIES:=.run)
coverage: coverage.info
genhtml coverage.info --output-directory coverage
coverage.info: run
lcov --capture --directory=. --output-file coverage.info
%.coverage : %
$(MAKE) clean && $(MAKE) $<
./$<
lcov --capture --directory=. --output-file coverage.info
genhtml coverage.info --output-directory coverage
#UNINIT_OPTS=--track-origins=yes
UNINIT_OPTS=--undef-value-errors=no
MEMCHECK_OPTS=--leak-check=full \
--show-reachable=yes \
--vgdb=full \
$(UNINIT_OPTS) \
--error-exitcode=1
MASSIF_OPTS=--tool=massif \
--stacks=yes
%.memcheck : %
valgrind $(MEMCHECK_OPTS) ./$< && \
touch $@
%.massif : %
valgrind $(MASSIF_OPTS) --massif-out-file=$@ ./$<
memcheck: $(BINARIES:=.memcheck)
massif: $(BINARIES:=.massif)
trusty_keymaster_device_test: trusty_keymaster_device_test.o \
trusty_keymaster_device.o \
$(KM)/aead_mode_operation.o \
$(KM)/aes_key.o \
$(KM)/aes_operation.o \
$(KM)/android_keymaster.o \
$(KM)/android_keymaster_messages.o \
$(KM)/android_keymaster_test_utils.o \
$(KM)/android_keymaster_utils.o \
$(KM)/asymmetric_key.o \
$(KM)/auth_encrypted_key_blob.o \
$(KM)/auth_encrypted_key_blob.o \
$(KM)/authorization_set.o \
$(KM)/ec_key.o \
$(KM)/ec_keymaster0_key.cpp \
$(KM)/ecdsa_operation.o \
$(KM)/hmac_key.o \
$(KM)/hmac_operation.o \
$(KM)/integrity_assured_key_blob.o \
$(KM)/key.o \
$(KM)/keymaster0_engine.o \
$(KM)/logger.o \
$(KM)/ocb.o \
$(KM)/ocb_utils.o \
$(KM)/openssl_err.o \
$(KM)/openssl_utils.o \
$(KM)/operation.o \
$(KM)/operation_table.o \
$(KM)/rsa_key.o \
$(KM)/rsa_keymaster0_key.o \
$(KM)/rsa_operation.o \
$(KM)/serializable.o \
$(KM)/soft_keymaster_context.o \
$(KM)/symmetric_key.o \
$(GTEST)/src/gtest-all.o
$(GTEST)/src/gtest-all.o: CXXFLAGS:=$(subst -Wmissing-declarations,,$(CXXFLAGS))
ocb.o: CFLAGS=$(CLANG_TEST_DEFINE)
clean:
rm -f $(OBJS) $(DEPS) $(GCDA) $(GCNO) $(BINARIES) \
$(BINARIES:=.run) $(BINARIES:=.memcheck) $(BINARIES:=.massif) \
coverage.info
rm -rf coverage
-include $(CPPSRCS:.cpp=.d)
-include $(CCSRCS:.cc=.d)

View file

@ -1,62 +0,0 @@
/*
* Copyright (C) 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.
*/
#include <errno.h>
#include <string.h>
#include <hardware/hardware.h>
#include <hardware/keymaster0.h>
#include <trusty_keymaster/legacy/trusty_keymaster_device.h>
using keymaster::TrustyKeymasterDevice;
/*
* Generic device handling
*/
static int trusty_keymaster_open(const hw_module_t* module, const char* name,
hw_device_t** device) {
if (strcmp(name, KEYSTORE_KEYMASTER) != 0) {
return -EINVAL;
}
TrustyKeymasterDevice* dev = new TrustyKeymasterDevice(module);
if (dev == NULL) {
return -ENOMEM;
}
*device = dev->hw_device();
// Do not delete dev; it will get cleaned up when the caller calls device->close(), and must
// exist until then.
return 0;
}
static struct hw_module_methods_t keystore_module_methods = {
.open = trusty_keymaster_open,
};
struct keystore_module HAL_MODULE_INFO_SYM __attribute__((visibility("default"))) = {
.common =
{
.tag = HARDWARE_MODULE_TAG,
.module_api_version = KEYMASTER_MODULE_API_VERSION_2_0,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = KEYSTORE_HARDWARE_MODULE_ID,
.name = "Trusty Keymaster HAL",
.author = "The Android Open Source Project",
.methods = &keystore_module_methods,
.dso = 0,
.reserved = {},
},
};

View file

@ -1,761 +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 LOG_TAG "TrustyKeymaster"
#include <assert.h>
#include <errno.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <algorithm>
#include <type_traits>
#include <hardware/keymaster2.h>
#include <keymaster/authorization_set.h>
#include <log/log.h>
#include <trusty_keymaster/ipc/keymaster_ipc.h>
#include <trusty_keymaster/ipc/trusty_keymaster_ipc.h>
#include <trusty_keymaster/legacy/trusty_keymaster_device.h>
const size_t kMaximumAttestationChallengeLength = 128;
const size_t kMaximumFinishInputLength = 2048;
namespace keymaster {
TrustyKeymasterDevice::TrustyKeymasterDevice(const hw_module_t* module) {
static_assert(std::is_standard_layout<TrustyKeymasterDevice>::value,
"TrustyKeymasterDevice must be standard layout");
static_assert(offsetof(TrustyKeymasterDevice, device_) == 0,
"device_ must be the first member of TrustyKeymasterDevice");
static_assert(offsetof(TrustyKeymasterDevice, device_.common) == 0,
"common must be the first member of keymaster2_device");
ALOGI("Creating device");
ALOGD("Device address: %p", this);
device_ = {};
device_.common.tag = HARDWARE_DEVICE_TAG;
device_.common.version = 1;
device_.common.module = const_cast<hw_module_t*>(module);
device_.common.close = close_device;
device_.flags = KEYMASTER_SUPPORTS_EC;
device_.configure = configure;
device_.add_rng_entropy = add_rng_entropy;
device_.generate_key = generate_key;
device_.get_key_characteristics = get_key_characteristics;
device_.import_key = import_key;
device_.export_key = export_key;
device_.attest_key = attest_key;
device_.upgrade_key = upgrade_key;
device_.delete_key = delete_key;
device_.delete_all_keys = delete_all_keys;
device_.begin = begin;
device_.update = update;
device_.finish = finish;
device_.abort = abort;
int rc = trusty_keymaster_connect();
error_ = translate_error(rc);
if (rc < 0) {
ALOGE("failed to connect to keymaster (%d)", rc);
return;
}
GetVersionRequest version_request;
GetVersionResponse version_response;
error_ = trusty_keymaster_send(KM_GET_VERSION, version_request, &version_response);
if (error_ == KM_ERROR_INVALID_ARGUMENT || error_ == KM_ERROR_UNIMPLEMENTED) {
ALOGE("\"Bad parameters\" error on GetVersion call. Version 0 is not supported.");
error_ = KM_ERROR_VERSION_MISMATCH;
return;
}
message_version_ = MessageVersion(version_response.major_ver, version_response.minor_ver,
version_response.subminor_ver);
if (message_version_ < 0) {
// Can't translate version? Keymaster implementation must be newer.
ALOGE("Keymaster version %d.%d.%d not supported.", version_response.major_ver,
version_response.minor_ver, version_response.subminor_ver);
error_ = KM_ERROR_VERSION_MISMATCH;
}
}
TrustyKeymasterDevice::~TrustyKeymasterDevice() {
trusty_keymaster_disconnect();
}
namespace {
// Allocates a new buffer with malloc and copies the contents of |buffer| to it. Caller takes
// ownership of the returned buffer.
uint8_t* DuplicateBuffer(const uint8_t* buffer, size_t size) {
uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(size));
if (tmp) {
memcpy(tmp, buffer, size);
}
return tmp;
}
template <typename RequestType>
void AddClientAndAppData(const keymaster_blob_t* client_id, const keymaster_blob_t* app_data,
RequestType* request) {
request->additional_params.Clear();
if (client_id && client_id->data_length > 0) {
request->additional_params.push_back(TAG_APPLICATION_ID, *client_id);
}
if (app_data && app_data->data_length > 0) {
request->additional_params.push_back(TAG_APPLICATION_DATA, *app_data);
}
}
} // unnamed namespace
keymaster_error_t TrustyKeymasterDevice::configure(const keymaster_key_param_set_t* params) {
ALOGD("Device received configure\n");
if (error_ != KM_ERROR_OK) {
return error_;
}
if (!params) {
return KM_ERROR_UNEXPECTED_NULL_POINTER;
}
AuthorizationSet params_copy(*params);
ConfigureRequest request(message_version_);
if (!params_copy.GetTagValue(TAG_OS_VERSION, &request.os_version) ||
!params_copy.GetTagValue(TAG_OS_PATCHLEVEL, &request.os_patchlevel)) {
ALOGD("Configuration parameters must contain OS version and patch level");
return KM_ERROR_INVALID_ARGUMENT;
}
ConfigureResponse response(message_version_);
keymaster_error_t err = trusty_keymaster_send(KM_CONFIGURE, request, &response);
if (err != KM_ERROR_OK) {
return err;
}
return KM_ERROR_OK;
}
keymaster_error_t TrustyKeymasterDevice::add_rng_entropy(const uint8_t* data, size_t data_length) {
ALOGD("Device received add_rng_entropy");
if (error_ != KM_ERROR_OK) {
return error_;
}
AddEntropyRequest request(message_version_);
request.random_data.Reinitialize(data, data_length);
AddEntropyResponse response(message_version_);
return trusty_keymaster_send(KM_ADD_RNG_ENTROPY, request, &response);
}
keymaster_error_t TrustyKeymasterDevice::generate_key(
const keymaster_key_param_set_t* params, keymaster_key_blob_t* key_blob,
keymaster_key_characteristics_t* characteristics) {
ALOGD("Device received generate_key");
if (error_ != KM_ERROR_OK) {
return error_;
}
if (!params) {
return KM_ERROR_UNEXPECTED_NULL_POINTER;
}
if (!key_blob) {
return KM_ERROR_OUTPUT_PARAMETER_NULL;
}
GenerateKeyRequest request(message_version_);
request.key_description.Reinitialize(*params);
request.key_description.push_back(TAG_CREATION_DATETIME, java_time(time(NULL)));
GenerateKeyResponse response(message_version_);
keymaster_error_t err = trusty_keymaster_send(KM_GENERATE_KEY, request, &response);
if (err != KM_ERROR_OK) {
return err;
}
key_blob->key_material_size = response.key_blob.key_material_size;
key_blob->key_material =
DuplicateBuffer(response.key_blob.key_material, response.key_blob.key_material_size);
if (!key_blob->key_material) {
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
}
if (characteristics) {
response.enforced.CopyToParamSet(&characteristics->hw_enforced);
response.unenforced.CopyToParamSet(&characteristics->sw_enforced);
}
return KM_ERROR_OK;
}
keymaster_error_t TrustyKeymasterDevice::get_key_characteristics(
const keymaster_key_blob_t* key_blob, const keymaster_blob_t* client_id,
const keymaster_blob_t* app_data, keymaster_key_characteristics_t* characteristics) {
ALOGD("Device received get_key_characteristics");
if (error_ != KM_ERROR_OK) {
return error_;
}
if (!key_blob || !key_blob->key_material) {
return KM_ERROR_UNEXPECTED_NULL_POINTER;
}
if (!characteristics) {
return KM_ERROR_OUTPUT_PARAMETER_NULL;
}
GetKeyCharacteristicsRequest request(message_version_);
request.SetKeyMaterial(*key_blob);
AddClientAndAppData(client_id, app_data, &request);
GetKeyCharacteristicsResponse response(message_version_);
keymaster_error_t err = trusty_keymaster_send(KM_GET_KEY_CHARACTERISTICS, request, &response);
if (err != KM_ERROR_OK) {
return err;
}
response.enforced.CopyToParamSet(&characteristics->hw_enforced);
response.unenforced.CopyToParamSet(&characteristics->sw_enforced);
return KM_ERROR_OK;
}
keymaster_error_t TrustyKeymasterDevice::import_key(
const keymaster_key_param_set_t* params, keymaster_key_format_t key_format,
const keymaster_blob_t* key_data, keymaster_key_blob_t* key_blob,
keymaster_key_characteristics_t* characteristics) {
ALOGD("Device received import_key");
if (error_ != KM_ERROR_OK) {
return error_;
}
if (!params || !key_data) {
return KM_ERROR_UNEXPECTED_NULL_POINTER;
}
if (!key_blob) {
return KM_ERROR_OUTPUT_PARAMETER_NULL;
}
ImportKeyRequest request(message_version_);
request.key_description.Reinitialize(*params);
request.key_description.push_back(TAG_CREATION_DATETIME, java_time(time(NULL)));
request.key_format = key_format;
request.SetKeyMaterial(key_data->data, key_data->data_length);
ImportKeyResponse response(message_version_);
keymaster_error_t err = trusty_keymaster_send(KM_IMPORT_KEY, request, &response);
if (err != KM_ERROR_OK) {
return err;
}
key_blob->key_material_size = response.key_blob.key_material_size;
key_blob->key_material =
DuplicateBuffer(response.key_blob.key_material, response.key_blob.key_material_size);
if (!key_blob->key_material) {
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
}
if (characteristics) {
response.enforced.CopyToParamSet(&characteristics->hw_enforced);
response.unenforced.CopyToParamSet(&characteristics->sw_enforced);
}
return KM_ERROR_OK;
}
keymaster_error_t TrustyKeymasterDevice::export_key(keymaster_key_format_t export_format,
const keymaster_key_blob_t* key_to_export,
const keymaster_blob_t* client_id,
const keymaster_blob_t* app_data,
keymaster_blob_t* export_data) {
ALOGD("Device received export_key");
if (error_ != KM_ERROR_OK) {
return error_;
}
if (!key_to_export || !key_to_export->key_material) {
return KM_ERROR_UNEXPECTED_NULL_POINTER;
}
if (!export_data) {
return KM_ERROR_OUTPUT_PARAMETER_NULL;
}
export_data->data = nullptr;
export_data->data_length = 0;
ExportKeyRequest request(message_version_);
request.key_format = export_format;
request.SetKeyMaterial(*key_to_export);
AddClientAndAppData(client_id, app_data, &request);
ExportKeyResponse response(message_version_);
keymaster_error_t err = trusty_keymaster_send(KM_EXPORT_KEY, request, &response);
if (err != KM_ERROR_OK) {
return err;
}
export_data->data_length = response.key_data_length;
export_data->data = DuplicateBuffer(response.key_data, response.key_data_length);
if (!export_data->data) {
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
}
return KM_ERROR_OK;
}
keymaster_error_t TrustyKeymasterDevice::attest_key(const keymaster_key_blob_t* key_to_attest,
const keymaster_key_param_set_t* attest_params,
keymaster_cert_chain_t* cert_chain) {
ALOGD("Device received attest_key");
if (error_ != KM_ERROR_OK) {
return error_;
}
if (!key_to_attest || !attest_params) {
return KM_ERROR_UNEXPECTED_NULL_POINTER;
}
if (!cert_chain) {
return KM_ERROR_OUTPUT_PARAMETER_NULL;
}
cert_chain->entry_count = 0;
cert_chain->entries = nullptr;
AttestKeyRequest request(message_version_);
request.SetKeyMaterial(*key_to_attest);
request.attest_params.Reinitialize(*attest_params);
keymaster_blob_t attestation_challenge = {};
request.attest_params.GetTagValue(TAG_ATTESTATION_CHALLENGE, &attestation_challenge);
if (attestation_challenge.data_length > kMaximumAttestationChallengeLength) {
ALOGE("%zu-byte attestation challenge; only %zu bytes allowed",
attestation_challenge.data_length, kMaximumAttestationChallengeLength);
return KM_ERROR_INVALID_INPUT_LENGTH;
}
AttestKeyResponse response(message_version_);
keymaster_error_t err = trusty_keymaster_send(KM_ATTEST_KEY, request, &response);
if (err != KM_ERROR_OK) {
return err;
}
// Allocate and clear storage for cert_chain.
keymaster_cert_chain_t& rsp_chain = response.certificate_chain;
cert_chain->entries = reinterpret_cast<keymaster_blob_t*>(
malloc(rsp_chain.entry_count * sizeof(*cert_chain->entries)));
if (!cert_chain->entries) {
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
}
cert_chain->entry_count = rsp_chain.entry_count;
for (keymaster_blob_t& entry : array_range(cert_chain->entries, cert_chain->entry_count)) {
entry = {};
}
// Copy cert_chain contents
size_t i = 0;
for (keymaster_blob_t& entry : array_range(rsp_chain.entries, rsp_chain.entry_count)) {
cert_chain->entries[i].data = DuplicateBuffer(entry.data, entry.data_length);
if (!cert_chain->entries[i].data) {
keymaster_free_cert_chain(cert_chain);
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
}
cert_chain->entries[i].data_length = entry.data_length;
++i;
}
return KM_ERROR_OK;
}
keymaster_error_t TrustyKeymasterDevice::upgrade_key(
const keymaster_key_blob_t* key_to_upgrade, const keymaster_key_param_set_t* upgrade_params,
keymaster_key_blob_t* upgraded_key) {
ALOGD("Device received upgrade_key");
if (error_ != KM_ERROR_OK) {
return error_;
}
if (!key_to_upgrade || !upgrade_params) {
return KM_ERROR_UNEXPECTED_NULL_POINTER;
}
if (!upgraded_key) {
return KM_ERROR_OUTPUT_PARAMETER_NULL;
}
UpgradeKeyRequest request(message_version_);
request.SetKeyMaterial(*key_to_upgrade);
request.upgrade_params.Reinitialize(*upgrade_params);
UpgradeKeyResponse response(message_version_);
keymaster_error_t err = trusty_keymaster_send(KM_UPGRADE_KEY, request, &response);
if (err != KM_ERROR_OK) {
return err;
}
upgraded_key->key_material_size = response.upgraded_key.key_material_size;
upgraded_key->key_material = DuplicateBuffer(response.upgraded_key.key_material,
response.upgraded_key.key_material_size);
if (!upgraded_key->key_material) {
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
}
return KM_ERROR_OK;
}
keymaster_error_t TrustyKeymasterDevice::begin(keymaster_purpose_t purpose,
const keymaster_key_blob_t* key,
const keymaster_key_param_set_t* in_params,
keymaster_key_param_set_t* out_params,
keymaster_operation_handle_t* operation_handle) {
ALOGD("Device received begin");
if (error_ != KM_ERROR_OK) {
return error_;
}
if (!key || !key->key_material) {
return KM_ERROR_UNEXPECTED_NULL_POINTER;
}
if (!operation_handle) {
return KM_ERROR_OUTPUT_PARAMETER_NULL;
}
if (out_params) {
*out_params = {};
}
BeginOperationRequest request(message_version_);
request.purpose = purpose;
request.SetKeyMaterial(*key);
request.additional_params.Reinitialize(*in_params);
BeginOperationResponse response(message_version_);
keymaster_error_t err = trusty_keymaster_send(KM_BEGIN_OPERATION, request, &response);
if (err != KM_ERROR_OK) {
return err;
}
if (response.output_params.size() > 0) {
if (out_params) {
response.output_params.CopyToParamSet(out_params);
} else {
return KM_ERROR_OUTPUT_PARAMETER_NULL;
}
}
*operation_handle = response.op_handle;
return KM_ERROR_OK;
}
keymaster_error_t TrustyKeymasterDevice::update(keymaster_operation_handle_t operation_handle,
const keymaster_key_param_set_t* in_params,
const keymaster_blob_t* input,
size_t* input_consumed,
keymaster_key_param_set_t* out_params,
keymaster_blob_t* output) {
ALOGD("Device received update");
if (error_ != KM_ERROR_OK) {
return error_;
}
if (!input) {
return KM_ERROR_UNEXPECTED_NULL_POINTER;
}
if (!input_consumed) {
return KM_ERROR_OUTPUT_PARAMETER_NULL;
}
if (out_params) {
*out_params = {};
}
if (output) {
*output = {};
}
UpdateOperationRequest request(message_version_);
request.op_handle = operation_handle;
if (in_params) {
request.additional_params.Reinitialize(*in_params);
}
if (input && input->data_length > 0) {
size_t max_input_size = TRUSTY_KEYMASTER_SEND_BUF_SIZE - request.SerializedSize();
request.input.Reinitialize(input->data, std::min(input->data_length, max_input_size));
}
UpdateOperationResponse response(message_version_);
keymaster_error_t err = trusty_keymaster_send(KM_UPDATE_OPERATION, request, &response);
if (err != KM_ERROR_OK) {
return err;
}
if (response.output_params.size() > 0) {
if (out_params) {
response.output_params.CopyToParamSet(out_params);
} else {
return KM_ERROR_OUTPUT_PARAMETER_NULL;
}
}
*input_consumed = response.input_consumed;
if (output) {
output->data_length = response.output.available_read();
output->data = DuplicateBuffer(response.output.peek_read(), output->data_length);
if (!output->data) {
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
}
} else if (response.output.available_read() > 0) {
return KM_ERROR_OUTPUT_PARAMETER_NULL;
}
return KM_ERROR_OK;
}
keymaster_error_t TrustyKeymasterDevice::finish(keymaster_operation_handle_t operation_handle,
const keymaster_key_param_set_t* in_params,
const keymaster_blob_t* input,
const keymaster_blob_t* signature,
keymaster_key_param_set_t* out_params,
keymaster_blob_t* output) {
ALOGD("Device received finish");
if (error_ != KM_ERROR_OK) {
return error_;
}
if (input && input->data_length > kMaximumFinishInputLength) {
ALOGE("%zu-byte input to finish; only %zu bytes allowed", input->data_length,
kMaximumFinishInputLength);
return KM_ERROR_INVALID_INPUT_LENGTH;
}
if (out_params) {
*out_params = {};
}
if (output) {
*output = {};
}
FinishOperationRequest request(message_version_);
request.op_handle = operation_handle;
if (signature && signature->data && signature->data_length > 0) {
request.signature.Reinitialize(signature->data, signature->data_length);
}
if (input && input->data && input->data_length) {
request.input.Reinitialize(input->data, input->data_length);
}
if (in_params) {
request.additional_params.Reinitialize(*in_params);
}
FinishOperationResponse response(message_version_);
keymaster_error_t err = trusty_keymaster_send(KM_FINISH_OPERATION, request, &response);
if (err != KM_ERROR_OK) {
return err;
}
if (response.output_params.size() > 0) {
if (out_params) {
response.output_params.CopyToParamSet(out_params);
} else {
return KM_ERROR_OUTPUT_PARAMETER_NULL;
}
}
if (output) {
output->data_length = response.output.available_read();
output->data = DuplicateBuffer(response.output.peek_read(), output->data_length);
if (!output->data) {
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
}
} else if (response.output.available_read() > 0) {
return KM_ERROR_OUTPUT_PARAMETER_NULL;
}
return KM_ERROR_OK;
}
keymaster_error_t TrustyKeymasterDevice::abort(keymaster_operation_handle_t operation_handle) {
ALOGD("Device received abort");
if (error_ != KM_ERROR_OK) {
return error_;
}
AbortOperationRequest request(message_version_);
request.op_handle = operation_handle;
AbortOperationResponse response(message_version_);
return trusty_keymaster_send(KM_ABORT_OPERATION, request, &response);
}
keymaster_error_t TrustyKeymasterDevice::delete_key(const keymaster_key_blob_t* key) {
ALOGD("Device received delete_key");
if (error_ != KM_ERROR_OK) {
return error_;
}
if (!key || !key->key_material)
return KM_ERROR_UNEXPECTED_NULL_POINTER;
DeleteKeyRequest request(message_version_);
request.SetKeyMaterial(*key);
DeleteKeyResponse response(message_version_);
return trusty_keymaster_send(KM_DELETE_KEY, request, &response);
}
keymaster_error_t TrustyKeymasterDevice::delete_all_keys() {
ALOGD("Device received delete_all_key");
if (error_ != KM_ERROR_OK) {
return error_;
}
DeleteAllKeysRequest request(message_version_);
DeleteAllKeysResponse response(message_version_);
return trusty_keymaster_send(KM_DELETE_ALL_KEYS, request, &response);
}
hw_device_t* TrustyKeymasterDevice::hw_device() {
return &device_.common;
}
static inline TrustyKeymasterDevice* convert_device(const keymaster2_device_t* dev) {
return reinterpret_cast<TrustyKeymasterDevice*>(const_cast<keymaster2_device_t*>(dev));
}
/* static */
int TrustyKeymasterDevice::close_device(hw_device_t* dev) {
delete reinterpret_cast<TrustyKeymasterDevice*>(dev);
return 0;
}
/* static */
keymaster_error_t TrustyKeymasterDevice::configure(const keymaster2_device_t* dev,
const keymaster_key_param_set_t* params) {
return convert_device(dev)->configure(params);
}
/* static */
keymaster_error_t TrustyKeymasterDevice::add_rng_entropy(const keymaster2_device_t* dev,
const uint8_t* data, size_t data_length) {
return convert_device(dev)->add_rng_entropy(data, data_length);
}
/* static */
keymaster_error_t TrustyKeymasterDevice::generate_key(
const keymaster2_device_t* dev, const keymaster_key_param_set_t* params,
keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t* characteristics) {
return convert_device(dev)->generate_key(params, key_blob, characteristics);
}
/* static */
keymaster_error_t TrustyKeymasterDevice::get_key_characteristics(
const keymaster2_device_t* dev, const keymaster_key_blob_t* key_blob,
const keymaster_blob_t* client_id, const keymaster_blob_t* app_data,
keymaster_key_characteristics_t* characteristics) {
return convert_device(dev)->get_key_characteristics(key_blob, client_id, app_data,
characteristics);
}
/* static */
keymaster_error_t TrustyKeymasterDevice::import_key(
const keymaster2_device_t* dev, const keymaster_key_param_set_t* params,
keymaster_key_format_t key_format, const keymaster_blob_t* key_data,
keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t* characteristics) {
return convert_device(dev)->import_key(params, key_format, key_data, key_blob, characteristics);
}
/* static */
keymaster_error_t TrustyKeymasterDevice::export_key(const keymaster2_device_t* dev,
keymaster_key_format_t export_format,
const keymaster_key_blob_t* key_to_export,
const keymaster_blob_t* client_id,
const keymaster_blob_t* app_data,
keymaster_blob_t* export_data) {
return convert_device(dev)->export_key(export_format, key_to_export, client_id, app_data,
export_data);
}
/* static */
keymaster_error_t TrustyKeymasterDevice::attest_key(const keymaster2_device_t* dev,
const keymaster_key_blob_t* key_to_attest,
const keymaster_key_param_set_t* attest_params,
keymaster_cert_chain_t* cert_chain) {
return convert_device(dev)->attest_key(key_to_attest, attest_params, cert_chain);
}
/* static */
keymaster_error_t TrustyKeymasterDevice::upgrade_key(
const keymaster2_device_t* dev, const keymaster_key_blob_t* key_to_upgrade,
const keymaster_key_param_set_t* upgrade_params, keymaster_key_blob_t* upgraded_key) {
return convert_device(dev)->upgrade_key(key_to_upgrade, upgrade_params, upgraded_key);
}
/* static */
keymaster_error_t TrustyKeymasterDevice::begin(const keymaster2_device_t* dev,
keymaster_purpose_t purpose,
const keymaster_key_blob_t* key,
const keymaster_key_param_set_t* in_params,
keymaster_key_param_set_t* out_params,
keymaster_operation_handle_t* operation_handle) {
return convert_device(dev)->begin(purpose, key, in_params, out_params, operation_handle);
}
/* static */
keymaster_error_t TrustyKeymasterDevice::update(
const keymaster2_device_t* dev, keymaster_operation_handle_t operation_handle,
const keymaster_key_param_set_t* in_params, const keymaster_blob_t* input,
size_t* input_consumed, keymaster_key_param_set_t* out_params, keymaster_blob_t* output) {
return convert_device(dev)->update(operation_handle, in_params, input, input_consumed,
out_params, output);
}
/* static */
keymaster_error_t TrustyKeymasterDevice::finish(const keymaster2_device_t* dev,
keymaster_operation_handle_t operation_handle,
const keymaster_key_param_set_t* in_params,
const keymaster_blob_t* input,
const keymaster_blob_t* signature,
keymaster_key_param_set_t* out_params,
keymaster_blob_t* output) {
return convert_device(dev)->finish(operation_handle, in_params, input, signature, out_params,
output);
}
/* static */
keymaster_error_t TrustyKeymasterDevice::abort(const keymaster2_device_t* dev,
keymaster_operation_handle_t operation_handle) {
return convert_device(dev)->abort(operation_handle);
}
/* static */
keymaster_error_t TrustyKeymasterDevice::delete_key(const keymaster2_device_t* dev,
const keymaster_key_blob_t* key) {
return convert_device(dev)->delete_key(key);
}
/* static */
keymaster_error_t TrustyKeymasterDevice::delete_all_keys(const keymaster2_device_t* dev) {
return convert_device(dev)->delete_all_keys();
}
} // namespace keymaster

View file

@ -1,561 +0,0 @@
/*
* Copyright (C) 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.
*/
#include <algorithm>
#include <fstream>
#include <memory>
#include <gtest/gtest.h>
#include <openssl/engine.h>
#include <hardware/keymaster0.h>
#include <keymaster/android_keymaster.h>
#include <keymaster/android_keymaster_messages.h>
#include <keymaster/android_keymaster_utils.h>
#include <keymaster/keymaster_tags.h>
#include <keymaster/soft_keymaster_context.h>
#include <trusty_keymaster/legacy/trusty_keymaster_device.h>
#include "android_keymaster_test_utils.h"
#include "openssl_utils.h"
using std::ifstream;
using std::istreambuf_iterator;
using std::string;
static keymaster::AndroidKeymaster* impl_ = nullptr;
extern "C" {
int __android_log_print();
}
int __android_log_print() {
return 0;
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
int result = RUN_ALL_TESTS();
// Clean up stuff OpenSSL leaves around, so Valgrind doesn't complain.
CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
return result;
}
int trusty_keymaster_connect() {
impl_ = new keymaster::AndroidKeymaster(new keymaster::SoftKeymasterContext(nullptr), 16);
}
void trusty_keymaster_disconnect() {
delete static_cast<keymaster::AndroidKeymaster*>(priv_);
}
template <typename Req, typename Rsp>
static int fake_call(keymaster::AndroidKeymaster* device,
void (keymaster::AndroidKeymaster::*method)(const Req&, Rsp*), void* in_buf,
uint32_t in_size, void* out_buf, uint32_t* out_size) {
Req req;
const uint8_t* in = static_cast<uint8_t*>(in_buf);
req.Deserialize(&in, in + in_size);
Rsp rsp;
(device->*method)(req, &rsp);
*out_size = rsp.SerializedSize();
uint8_t* out = static_cast<uint8_t*>(out_buf);
rsp.Serialize(out, out + *out_size);
return 0;
}
int trusty_keymaster_call(uint32_t cmd, void* in_buf, uint32_t in_size, void* out_buf,
uint32_t* out_size) {
switch (cmd) {
case KM_GENERATE_KEY:
return fake_call(impl_, &keymaster::AndroidKeymaster::GenerateKey, in_buf, in_size,
out_buf, out_size);
case KM_BEGIN_OPERATION:
return fake_call(impl_, &keymaster::AndroidKeymaster::BeginOperation, in_buf, in_size,
out_buf, out_size);
case KM_UPDATE_OPERATION:
return fake_call(impl_, &keymaster::AndroidKeymaster::UpdateOperation, in_buf, in_size,
out_buf, out_size);
case KM_FINISH_OPERATION:
return fake_call(impl_, &keymaster::AndroidKeymaster::FinishOperation, in_buf, in_size,
out_buf, out_size);
case KM_IMPORT_KEY:
return fake_call(impl_, &keymaster::AndroidKeymaster::ImportKey, in_buf, in_size,
out_buf, out_size);
case KM_EXPORT_KEY:
return fake_call(impl_, &keymaster::AndroidKeymaster::ExportKey, in_buf, in_size,
out_buf, out_size);
}
return -EINVAL;
}
namespace keymaster {
namespace test {
class TrustyKeymasterTest : public testing::Test {
protected:
TrustyKeymasterTest() : device(NULL) {}
keymaster_rsa_keygen_params_t build_rsa_params() {
keymaster_rsa_keygen_params_t rsa_params;
rsa_params.public_exponent = 65537;
rsa_params.modulus_size = 2048;
return rsa_params;
}
uint8_t* build_message(size_t length) {
uint8_t* msg = new uint8_t[length];
memset(msg, 'a', length);
return msg;
}
size_t dsa_message_len(const keymaster_dsa_keygen_params_t& params) {
switch (params.key_size) {
case 256:
case 1024:
return 48;
case 2048:
case 4096:
return 72;
default:
// Oops.
return 0;
}
}
TrustyKeymasterDevice device;
};
class Malloc_Delete {
public:
Malloc_Delete(void* p) : p_(p) {}
~Malloc_Delete() { free(p_); }
private:
void* p_;
};
typedef TrustyKeymasterTest KeyGenTest;
TEST_F(KeyGenTest, RsaSuccess) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
}
TEST_F(KeyGenTest, EcdsaSuccess) {
keymaster_ec_keygen_params_t ec_params = {256};
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_EC, &ec_params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
}
typedef TrustyKeymasterTest SigningTest;
TEST_F(SigningTest, RsaSuccess) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_len = params.modulus_size / 8;
std::unique_ptr<uint8_t[]> message(build_message(message_len));
uint8_t* signature;
size_t siglen;
EXPECT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message.get(), message_len,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(message_len, siglen);
}
TEST_F(SigningTest, RsaShortMessage) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_len = params.modulus_size / 8 - 1;
std::unique_ptr<uint8_t[]> message(build_message(message_len));
uint8_t* signature;
size_t siglen;
EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, device.sign_data(&sig_params, ptr, size, message.get(),
message_len, &signature, &siglen));
}
TEST_F(SigningTest, RsaLongMessage) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_len = params.modulus_size / 8 + 1;
std::unique_ptr<uint8_t[]> message(build_message(message_len));
uint8_t* signature;
size_t siglen;
EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, device.sign_data(&sig_params, ptr, size, message.get(),
message_len, &signature, &siglen));
}
TEST_F(SigningTest, EcdsaSuccess) {
keymaster_ec_keygen_params_t params = {256};
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_EC, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_ec_sign_params_t sig_params = {DIGEST_NONE};
uint8_t message[] = "12345678901234567890123456789012";
uint8_t* signature;
size_t siglen;
ASSERT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message,
array_size(message) - 1, &signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_GT(siglen, 69U);
EXPECT_LT(siglen, 73U);
}
TEST_F(SigningTest, EcdsaEmptyMessageSuccess) {
keymaster_ec_keygen_params_t params = {256};
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_EC, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_ec_sign_params_t sig_params = {DIGEST_NONE};
uint8_t message[] = "";
uint8_t* signature;
size_t siglen;
ASSERT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message,
array_size(message) - 1, &signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_GT(siglen, 69U);
EXPECT_LT(siglen, 73U);
}
TEST_F(SigningTest, EcdsaLargeMessageSuccess) {
keymaster_ec_keygen_params_t params = {256};
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_EC, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_ec_sign_params_t sig_params = {DIGEST_NONE};
size_t message_len = 1024 * 7;
std::unique_ptr<uint8_t[]> message(new uint8_t[message_len]);
// contents of message don't matter.
uint8_t* signature;
size_t siglen;
ASSERT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message.get(), message_len,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_GT(siglen, 69U);
EXPECT_LT(siglen, 73U);
}
typedef TrustyKeymasterTest VerificationTest;
TEST_F(VerificationTest, RsaSuccess) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_len = params.modulus_size / 8;
std::unique_ptr<uint8_t[]> message(build_message(message_len));
uint8_t* signature;
size_t siglen;
EXPECT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message.get(), message_len,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(KM_ERROR_OK, device.verify_data(&sig_params, ptr, size, message.get(), message_len,
signature, siglen));
}
TEST_F(VerificationTest, RsaBadSignature) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_len = params.modulus_size / 8;
std::unique_ptr<uint8_t[]> message(build_message(message_len));
uint8_t* signature;
size_t siglen;
EXPECT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message.get(), message_len,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
signature[siglen / 2]++;
EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED,
device.verify_data(&sig_params, ptr, size, message.get(), message_len, signature,
siglen));
}
TEST_F(VerificationTest, RsaBadMessage) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_len = params.modulus_size / 8;
std::unique_ptr<uint8_t[]> message(build_message(message_len));
uint8_t* signature;
size_t siglen;
EXPECT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message.get(), message_len,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
message[0]++;
EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED,
device.verify_data(&sig_params, ptr, size, message.get(), message_len, signature,
siglen));
}
TEST_F(VerificationTest, RsaShortMessage) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_len = params.modulus_size / 8;
std::unique_ptr<uint8_t[]> message(build_message(message_len));
uint8_t* signature;
size_t siglen;
EXPECT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message.get(), message_len,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH,
device.verify_data(&sig_params, ptr, size, message.get(), message_len - 1, signature,
siglen));
}
TEST_F(VerificationTest, RsaLongMessage) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_len = params.modulus_size / 8;
std::unique_ptr<uint8_t[]> message(build_message(message_len + 1));
uint8_t* signature;
size_t siglen;
EXPECT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message.get(), message_len,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH,
device.verify_data(&sig_params, ptr, size, message.get(), message_len + 1, signature,
siglen));
}
TEST_F(VerificationTest, EcdsaSuccess) {
keymaster_ec_keygen_params_t params = {256};
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_EC, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_ec_sign_params_t sig_params = {DIGEST_NONE};
uint8_t message[] = "12345678901234567890123456789012";
uint8_t* signature;
size_t siglen;
ASSERT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message,
array_size(message) - 1, &signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(KM_ERROR_OK, device.verify_data(&sig_params, ptr, size, message,
array_size(message) - 1, signature, siglen));
}
TEST_F(VerificationTest, EcdsaLargeMessageSuccess) {
keymaster_ec_keygen_params_t params = {256};
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_EC, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_ec_sign_params_t sig_params = {DIGEST_NONE};
size_t message_len = 1024 * 7;
std::unique_ptr<uint8_t[]> message(new uint8_t[message_len]);
// contents of message don't matter.
uint8_t* signature;
size_t siglen;
ASSERT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message.get(), message_len,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(KM_ERROR_OK, device.verify_data(&sig_params, ptr, size, message.get(), message_len,
signature, siglen));
}
static string read_file(const string& file_name) {
ifstream file_stream(file_name, std::ios::binary);
istreambuf_iterator<char> file_begin(file_stream);
istreambuf_iterator<char> file_end;
return string(file_begin, file_end);
}
typedef TrustyKeymasterTest ImportKeyTest;
TEST_F(ImportKeyTest, RsaSuccess) {
string pk8_key = read_file("../../../../system/keymaster/rsa_privkey_pk8.der");
ASSERT_EQ(633U, pk8_key.size());
uint8_t* key = NULL;
size_t size;
ASSERT_EQ(KM_ERROR_OK, device.import_keypair(reinterpret_cast<const uint8_t*>(pk8_key.data()),
pk8_key.size(), &key, &size));
Malloc_Delete key_deleter(key);
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_size = 1024 /* key size */ / 8;
std::unique_ptr<uint8_t[]> message(new uint8_t[message_size]);
memset(message.get(), 'a', message_size);
uint8_t* signature;
size_t siglen;
ASSERT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, key, size, message.get(), message_size,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(KM_ERROR_OK, device.verify_data(&sig_params, key, size, message.get(), message_size,
signature, siglen));
}
TEST_F(ImportKeyTest, EcdsaSuccess) {
string pk8_key = read_file("../../../../system/keymaster/ec_privkey_pk8.der");
ASSERT_EQ(138U, pk8_key.size());
uint8_t* key = NULL;
size_t size;
ASSERT_EQ(KM_ERROR_OK, device.import_keypair(reinterpret_cast<const uint8_t*>(pk8_key.data()),
pk8_key.size(), &key, &size));
Malloc_Delete key_deleter(key);
keymaster_ec_sign_params_t sig_params = {DIGEST_NONE};
uint8_t message[] = "12345678901234567890123456789012";
uint8_t* signature;
size_t siglen;
ASSERT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, key, size, message,
array_size(message) - 1, &signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(KM_ERROR_OK, device.verify_data(&sig_params, key, size, message,
array_size(message) - 1, signature, siglen));
}
struct EVP_PKEY_CTX_Delete {
void operator()(EVP_PKEY_CTX* p) { EVP_PKEY_CTX_free(p); }
};
static void VerifySignature(const uint8_t* key, size_t key_len, const uint8_t* signature,
size_t signature_len, const uint8_t* message, size_t message_len) {
std::unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(d2i_PUBKEY(NULL, &key, key_len));
ASSERT_TRUE(pkey.get() != NULL);
std::unique_ptr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(EVP_PKEY_CTX_new(pkey.get(), NULL));
ASSERT_TRUE(ctx.get() != NULL);
ASSERT_EQ(1, EVP_PKEY_verify_init(ctx.get()));
if (EVP_PKEY_type(pkey->type) == EVP_PKEY_RSA)
ASSERT_EQ(1, EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_NO_PADDING));
EXPECT_EQ(1, EVP_PKEY_verify(ctx.get(), signature, signature_len, message, message_len));
}
typedef TrustyKeymasterTest ExportKeyTest;
TEST_F(ExportKeyTest, RsaSuccess) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
uint8_t* exported;
size_t exported_size;
EXPECT_EQ(KM_ERROR_OK, device.get_keypair_public(ptr, size, &exported, &exported_size));
Malloc_Delete exported_deleter(exported);
// Sign a message so we can verify it with the exported pubkey.
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_len = params.modulus_size / 8;
std::unique_ptr<uint8_t[]> message(build_message(message_len));
uint8_t* signature;
size_t siglen;
EXPECT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message.get(), message_len,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(message_len, siglen);
const uint8_t* tmp = exported;
VerifySignature(exported, exported_size, signature, siglen, message.get(), message_len);
}
typedef TrustyKeymasterTest ExportKeyTest;
TEST_F(ExportKeyTest, EcdsaSuccess) {
keymaster_ec_keygen_params_t params = {256};
uint8_t* key = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_EC, &params, &key, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(key);
uint8_t* exported;
size_t exported_size;
EXPECT_EQ(KM_ERROR_OK, device.get_keypair_public(key, size, &exported, &exported_size));
Malloc_Delete exported_deleter(exported);
// Sign a message so we can verify it with the exported pubkey.
keymaster_ec_sign_params_t sig_params = {DIGEST_NONE};
uint8_t message[] = "12345678901234567890123456789012";
uint8_t* signature;
size_t siglen;
ASSERT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, key, size, message,
array_size(message) - 1, &signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(KM_ERROR_OK, device.verify_data(&sig_params, key, size, message,
array_size(message) - 1, signature, siglen));
VerifySignature(exported, exported_size, signature, siglen, message, array_size(message) - 1);
}
} // namespace test
} // namespace keymaster

View file

@ -1,408 +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.
*/
#include <keymaster/keymaster_configuration.h>
#include <stdio.h>
#include <memory>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <trusty_keymaster/legacy/trusty_keymaster_device.h>
using keymaster::TrustyKeymasterDevice;
unsigned char rsa_privkey_pk8_der[] = {
0x30, 0x82, 0x02, 0x75, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x5f, 0x30, 0x82, 0x02, 0x5b,
0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xc6, 0x09, 0x54, 0x09, 0x04, 0x7d, 0x86, 0x34,
0x81, 0x2d, 0x5a, 0x21, 0x81, 0x76, 0xe4, 0x5c, 0x41, 0xd6, 0x0a, 0x75, 0xb1, 0x39, 0x01,
0xf2, 0x34, 0x22, 0x6c, 0xff, 0xe7, 0x76, 0x52, 0x1c, 0x5a, 0x77, 0xb9, 0xe3, 0x89, 0x41,
0x7b, 0x71, 0xc0, 0xb6, 0xa4, 0x4d, 0x13, 0xaf, 0xe4, 0xe4, 0xa2, 0x80, 0x5d, 0x46, 0xc9,
0xda, 0x29, 0x35, 0xad, 0xb1, 0xff, 0x0c, 0x1f, 0x24, 0xea, 0x06, 0xe6, 0x2b, 0x20, 0xd7,
0x76, 0x43, 0x0a, 0x4d, 0x43, 0x51, 0x57, 0x23, 0x3c, 0x6f, 0x91, 0x67, 0x83, 0xc3, 0x0e,
0x31, 0x0f, 0xcb, 0xd8, 0x9b, 0x85, 0xc2, 0xd5, 0x67, 0x71, 0x16, 0x97, 0x85, 0xac, 0x12,
0xbc, 0xa2, 0x44, 0xab, 0xda, 0x72, 0xbf, 0xb1, 0x9f, 0xc4, 0x4d, 0x27, 0xc8, 0x1e, 0x1d,
0x92, 0xde, 0x28, 0x4f, 0x40, 0x61, 0xed, 0xfd, 0x99, 0x28, 0x07, 0x45, 0xea, 0x6d, 0x25,
0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x1b, 0xe0, 0xf0, 0x4d, 0x9c, 0xae, 0x37,
0x18, 0x69, 0x1f, 0x03, 0x53, 0x38, 0x30, 0x8e, 0x91, 0x56, 0x4b, 0x55, 0x89, 0x9f, 0xfb,
0x50, 0x84, 0xd2, 0x46, 0x0e, 0x66, 0x30, 0x25, 0x7e, 0x05, 0xb3, 0xce, 0xab, 0x02, 0x97,
0x2d, 0xfa, 0xbc, 0xd6, 0xce, 0x5f, 0x6e, 0xe2, 0x58, 0x9e, 0xb6, 0x79, 0x11, 0xed, 0x0f,
0xac, 0x16, 0xe4, 0x3a, 0x44, 0x4b, 0x8c, 0x86, 0x1e, 0x54, 0x4a, 0x05, 0x93, 0x36, 0x57,
0x72, 0xf8, 0xba, 0xf6, 0xb2, 0x2f, 0xc9, 0xe3, 0xc5, 0xf1, 0x02, 0x4b, 0x06, 0x3a, 0xc0,
0x80, 0xa7, 0xb2, 0x23, 0x4c, 0xf8, 0xae, 0xe8, 0xf6, 0xc4, 0x7b, 0xbf, 0x4f, 0xd3, 0xac,
0xe7, 0x24, 0x02, 0x90, 0xbe, 0xf1, 0x6c, 0x0b, 0x3f, 0x7f, 0x3c, 0xdd, 0x64, 0xce, 0x3a,
0xb5, 0x91, 0x2c, 0xf6, 0xe3, 0x2f, 0x39, 0xab, 0x18, 0x83, 0x58, 0xaf, 0xcc, 0xcd, 0x80,
0x81, 0x02, 0x41, 0x00, 0xe4, 0xb4, 0x9e, 0xf5, 0x0f, 0x76, 0x5d, 0x3b, 0x24, 0xdd, 0xe0,
0x1a, 0xce, 0xaa, 0xf1, 0x30, 0xf2, 0xc7, 0x66, 0x70, 0xa9, 0x1a, 0x61, 0xae, 0x08, 0xaf,
0x49, 0x7b, 0x4a, 0x82, 0xbe, 0x6d, 0xee, 0x8f, 0xcd, 0xd5, 0xe3, 0xf7, 0xba, 0x1c, 0xfb,
0x1f, 0x0c, 0x92, 0x6b, 0x88, 0xf8, 0x8c, 0x92, 0xbf, 0xab, 0x13, 0x7f, 0xba, 0x22, 0x85,
0x22, 0x7b, 0x83, 0xc3, 0x42, 0xff, 0x7c, 0x55, 0x02, 0x41, 0x00, 0xdd, 0xab, 0xb5, 0x83,
0x9c, 0x4c, 0x7f, 0x6b, 0xf3, 0xd4, 0x18, 0x32, 0x31, 0xf0, 0x05, 0xb3, 0x1a, 0xa5, 0x8a,
0xff, 0xdd, 0xa5, 0xc7, 0x9e, 0x4c, 0xce, 0x21, 0x7f, 0x6b, 0xc9, 0x30, 0xdb, 0xe5, 0x63,
0xd4, 0x80, 0x70, 0x6c, 0x24, 0xe9, 0xeb, 0xfc, 0xab, 0x28, 0xa6, 0xcd, 0xef, 0xd3, 0x24,
0xb7, 0x7e, 0x1b, 0xf7, 0x25, 0x1b, 0x70, 0x90, 0x92, 0xc2, 0x4f, 0xf5, 0x01, 0xfd, 0x91,
0x02, 0x40, 0x23, 0xd4, 0x34, 0x0e, 0xda, 0x34, 0x45, 0xd8, 0xcd, 0x26, 0xc1, 0x44, 0x11,
0xda, 0x6f, 0xdc, 0xa6, 0x3c, 0x1c, 0xcd, 0x4b, 0x80, 0xa9, 0x8a, 0xd5, 0x2b, 0x78, 0xcc,
0x8a, 0xd8, 0xbe, 0xb2, 0x84, 0x2c, 0x1d, 0x28, 0x04, 0x05, 0xbc, 0x2f, 0x6c, 0x1b, 0xea,
0x21, 0x4a, 0x1d, 0x74, 0x2a, 0xb9, 0x96, 0xb3, 0x5b, 0x63, 0xa8, 0x2a, 0x5e, 0x47, 0x0f,
0xa8, 0x8d, 0xbf, 0x82, 0x3c, 0xdd, 0x02, 0x40, 0x1b, 0x7b, 0x57, 0x44, 0x9a, 0xd3, 0x0d,
0x15, 0x18, 0x24, 0x9a, 0x5f, 0x56, 0xbb, 0x98, 0x29, 0x4d, 0x4b, 0x6a, 0xc1, 0x2f, 0xfc,
0x86, 0x94, 0x04, 0x97, 0xa5, 0xa5, 0x83, 0x7a, 0x6c, 0xf9, 0x46, 0x26, 0x2b, 0x49, 0x45,
0x26, 0xd3, 0x28, 0xc1, 0x1e, 0x11, 0x26, 0x38, 0x0f, 0xde, 0x04, 0xc2, 0x4f, 0x91, 0x6d,
0xec, 0x25, 0x08, 0x92, 0xdb, 0x09, 0xa6, 0xd7, 0x7c, 0xdb, 0xa3, 0x51, 0x02, 0x40, 0x77,
0x62, 0xcd, 0x8f, 0x4d, 0x05, 0x0d, 0xa5, 0x6b, 0xd5, 0x91, 0xad, 0xb5, 0x15, 0xd2, 0x4d,
0x7c, 0xcd, 0x32, 0xcc, 0xa0, 0xd0, 0x5f, 0x86, 0x6d, 0x58, 0x35, 0x14, 0xbd, 0x73, 0x24,
0xd5, 0xf3, 0x36, 0x45, 0xe8, 0xed, 0x8b, 0x4a, 0x1c, 0xb3, 0xcc, 0x4a, 0x1d, 0x67, 0x98,
0x73, 0x99, 0xf2, 0xa0, 0x9f, 0x5b, 0x3f, 0xb6, 0x8c, 0x88, 0xd5, 0xe5, 0xd9, 0x0a, 0xc3,
0x34, 0x92, 0xd6};
unsigned int rsa_privkey_pk8_der_len = 633;
unsigned char dsa_privkey_pk8_der[] = {
0x30, 0x82, 0x01, 0x4b, 0x02, 0x01, 0x00, 0x30, 0x82, 0x01, 0x2b, 0x06, 0x07, 0x2a, 0x86,
0x48, 0xce, 0x38, 0x04, 0x01, 0x30, 0x82, 0x01, 0x1e, 0x02, 0x81, 0x81, 0x00, 0xa3, 0xf3,
0xe9, 0xb6, 0x7e, 0x7d, 0x88, 0xf6, 0xb7, 0xe5, 0xf5, 0x1f, 0x3b, 0xee, 0xac, 0xd7, 0xad,
0xbc, 0xc9, 0xd1, 0x5a, 0xf8, 0x88, 0xc4, 0xef, 0x6e, 0x3d, 0x74, 0x19, 0x74, 0xe7, 0xd8,
0xe0, 0x26, 0x44, 0x19, 0x86, 0xaf, 0x19, 0xdb, 0x05, 0xe9, 0x3b, 0x8b, 0x58, 0x58, 0xde,
0xe5, 0x4f, 0x48, 0x15, 0x01, 0xea, 0xe6, 0x83, 0x52, 0xd7, 0xc1, 0x21, 0xdf, 0xb9, 0xb8,
0x07, 0x66, 0x50, 0xfb, 0x3a, 0x0c, 0xb3, 0x85, 0xee, 0xbb, 0x04, 0x5f, 0xc2, 0x6d, 0x6d,
0x95, 0xfa, 0x11, 0x93, 0x1e, 0x59, 0x5b, 0xb1, 0x45, 0x8d, 0xe0, 0x3d, 0x73, 0xaa, 0xf2,
0x41, 0x14, 0x51, 0x07, 0x72, 0x3d, 0xa2, 0xf7, 0x58, 0xcd, 0x11, 0xa1, 0x32, 0xcf, 0xda,
0x42, 0xb7, 0xcc, 0x32, 0x80, 0xdb, 0x87, 0x82, 0xec, 0x42, 0xdb, 0x5a, 0x55, 0x24, 0x24,
0xa2, 0xd1, 0x55, 0x29, 0xad, 0xeb, 0x02, 0x15, 0x00, 0xeb, 0xea, 0x17, 0xd2, 0x09, 0xb3,
0xd7, 0x21, 0x9a, 0x21, 0x07, 0x82, 0x8f, 0xab, 0xfe, 0x88, 0x71, 0x68, 0xf7, 0xe3, 0x02,
0x81, 0x80, 0x19, 0x1c, 0x71, 0xfd, 0xe0, 0x03, 0x0c, 0x43, 0xd9, 0x0b, 0xf6, 0xcd, 0xd6,
0xa9, 0x70, 0xe7, 0x37, 0x86, 0x3a, 0x78, 0xe9, 0xa7, 0x47, 0xa7, 0x47, 0x06, 0x88, 0xb1,
0xaf, 0xd7, 0xf3, 0xf1, 0xa1, 0xd7, 0x00, 0x61, 0x28, 0x88, 0x31, 0x48, 0x60, 0xd8, 0x11,
0xef, 0xa5, 0x24, 0x1a, 0x81, 0xc4, 0x2a, 0xe2, 0xea, 0x0e, 0x36, 0xd2, 0xd2, 0x05, 0x84,
0x37, 0xcf, 0x32, 0x7d, 0x09, 0xe6, 0x0f, 0x8b, 0x0c, 0xc8, 0xc2, 0xa4, 0xb1, 0xdc, 0x80,
0xca, 0x68, 0xdf, 0xaf, 0xd2, 0x90, 0xc0, 0x37, 0x58, 0x54, 0x36, 0x8f, 0x49, 0xb8, 0x62,
0x75, 0x8b, 0x48, 0x47, 0xc0, 0xbe, 0xf7, 0x9a, 0x92, 0xa6, 0x68, 0x05, 0xda, 0x9d, 0xaf,
0x72, 0x9a, 0x67, 0xb3, 0xb4, 0x14, 0x03, 0xae, 0x4f, 0x4c, 0x76, 0xb9, 0xd8, 0x64, 0x0a,
0xba, 0x3b, 0xa8, 0x00, 0x60, 0x4d, 0xae, 0x81, 0xc3, 0xc5, 0x04, 0x17, 0x02, 0x15, 0x00,
0x81, 0x9d, 0xfd, 0x53, 0x0c, 0xc1, 0x8f, 0xbe, 0x8b, 0xea, 0x00, 0x26, 0x19, 0x29, 0x33,
0x91, 0x84, 0xbe, 0xad, 0x81};
unsigned int dsa_privkey_pk8_der_len = 335;
unsigned char ec_privkey_pk8_der[] = {
0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce,
0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x04,
0x6d, 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04, 0x20, 0x73, 0x7c, 0x2e, 0xcd, 0x7b, 0x8d,
0x19, 0x40, 0xbf, 0x29, 0x30, 0xaa, 0x9b, 0x4e, 0xd3, 0xff, 0x94, 0x1e, 0xed, 0x09,
0x36, 0x6b, 0xc0, 0x32, 0x99, 0x98, 0x64, 0x81, 0xf3, 0xa4, 0xd8, 0x59, 0xa1, 0x44,
0x03, 0x42, 0x00, 0x04, 0xbf, 0x85, 0xd7, 0x72, 0x0d, 0x07, 0xc2, 0x54, 0x61, 0x68,
0x3b, 0xc6, 0x48, 0xb4, 0x77, 0x8a, 0x9a, 0x14, 0xdd, 0x8a, 0x02, 0x4e, 0x3b, 0xdd,
0x8c, 0x7d, 0xdd, 0x9a, 0xb2, 0xb5, 0x28, 0xbb, 0xc7, 0xaa, 0x1b, 0x51, 0xf1, 0x4e,
0xbb, 0xbb, 0x0b, 0xd0, 0xce, 0x21, 0xbc, 0xc4, 0x1c, 0x6e, 0xb0, 0x00, 0x83, 0xcf,
0x33, 0x76, 0xd1, 0x1f, 0xd4, 0x49, 0x49, 0xe0, 0xb2, 0x18, 0x3b, 0xfe};
unsigned int ec_privkey_pk8_der_len = 138;
keymaster_key_param_t ec_params[] = {
keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_EC),
keymaster_param_long(KM_TAG_EC_CURVE, KM_EC_CURVE_P_521),
keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_SIGN),
keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_VERIFY),
keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE),
keymaster_param_bool(KM_TAG_NO_AUTH_REQUIRED),
};
keymaster_key_param_set_t ec_param_set = {ec_params, sizeof(ec_params) / sizeof(*ec_params)};
keymaster_key_param_t rsa_params[] = {
keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_RSA),
keymaster_param_int(KM_TAG_KEY_SIZE, 1024),
keymaster_param_long(KM_TAG_RSA_PUBLIC_EXPONENT, 65537),
keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_SIGN),
keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_VERIFY),
keymaster_param_enum(KM_TAG_PADDING, KM_PAD_NONE),
keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE),
keymaster_param_bool(KM_TAG_NO_AUTH_REQUIRED),
};
keymaster_key_param_set_t rsa_param_set = {rsa_params, sizeof(rsa_params) / sizeof(*rsa_params)};
struct EVP_PKEY_Delete {
void operator()(EVP_PKEY* p) const { EVP_PKEY_free(p); }
};
struct EVP_PKEY_CTX_Delete {
void operator()(EVP_PKEY_CTX* p) { EVP_PKEY_CTX_free(p); }
};
static bool do_operation(TrustyKeymasterDevice* device, keymaster_purpose_t purpose,
keymaster_key_blob_t* key, keymaster_blob_t* input,
keymaster_blob_t* signature, keymaster_blob_t* output) {
keymaster_key_param_t params[] = {
keymaster_param_enum(KM_TAG_PADDING, KM_PAD_NONE),
keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE),
};
keymaster_key_param_set_t param_set = {params, sizeof(params) / sizeof(*params)};
keymaster_operation_handle_t op_handle;
keymaster_error_t error = device->begin(purpose, key, &param_set, nullptr, &op_handle);
if (error != KM_ERROR_OK) {
printf("Keymaster begin() failed: %d\n", error);
return false;
}
size_t input_consumed;
error = device->update(op_handle, nullptr, input, &input_consumed, nullptr, nullptr);
if (error != KM_ERROR_OK) {
printf("Keymaster update() failed: %d\n", error);
return false;
}
if (input_consumed != input->data_length) {
// This should never happen. If it does, it's a bug in the keymaster implementation.
printf("Keymaster update() did not consume all data.\n");
device->abort(op_handle);
return false;
}
error = device->finish(op_handle, nullptr, nullptr, signature, nullptr, output);
if (error != KM_ERROR_OK) {
printf("Keymaster finish() failed: %d\n", error);
return false;
}
return true;
}
static bool test_import_rsa(TrustyKeymasterDevice* device) {
printf("===================\n");
printf("= RSA Import Test =\n");
printf("===================\n\n");
printf("=== Importing RSA keypair === \n");
keymaster_key_blob_t key;
keymaster_blob_t private_key = {rsa_privkey_pk8_der, rsa_privkey_pk8_der_len};
int error =
device->import_key(&rsa_param_set, KM_KEY_FORMAT_PKCS8, &private_key, &key, nullptr);
if (error != KM_ERROR_OK) {
printf("Error importing RSA key: %d\n\n", error);
return false;
}
std::unique_ptr<const uint8_t[]> key_deleter(key.key_material);
printf("=== Signing with imported RSA key ===\n");
size_t message_len = 1024 / 8;
std::unique_ptr<uint8_t[]> message(new uint8_t[message_len]);
memset(message.get(), 'a', message_len);
keymaster_blob_t input = {message.get(), message_len}, signature;
if (!do_operation(device, KM_PURPOSE_SIGN, &key, &input, nullptr, &signature)) {
printf("Error signing data with imported RSA key\n\n");
return false;
}
std::unique_ptr<const uint8_t[]> signature_deleter(signature.data);
printf("=== Verifying with imported RSA key === \n");
if (!do_operation(device, KM_PURPOSE_VERIFY, &key, &input, &signature, nullptr)) {
printf("Error verifying data with imported RSA key\n\n");
return false;
}
printf("\n");
return true;
}
static bool test_rsa(TrustyKeymasterDevice* device) {
printf("============\n");
printf("= RSA Test =\n");
printf("============\n\n");
printf("=== Generating RSA key pair ===\n");
keymaster_key_blob_t key;
int error = device->generate_key(&rsa_param_set, &key, nullptr);
if (error != KM_ERROR_OK) {
printf("Error generating RSA key pair: %d\n\n", error);
return false;
}
std::unique_ptr<const uint8_t[]> key_deleter(key.key_material);
printf("=== Signing with RSA key === \n");
size_t message_len = 1024 / 8;
std::unique_ptr<uint8_t[]> message(new uint8_t[message_len]);
memset(message.get(), 'a', message_len);
keymaster_blob_t input = {message.get(), message_len}, signature;
if (!do_operation(device, KM_PURPOSE_SIGN, &key, &input, nullptr, &signature)) {
printf("Error signing data with RSA key\n\n");
return false;
}
std::unique_ptr<const uint8_t[]> signature_deleter(signature.data);
printf("=== Verifying with RSA key === \n");
if (!do_operation(device, KM_PURPOSE_VERIFY, &key, &input, &signature, nullptr)) {
printf("Error verifying data with RSA key\n\n");
return false;
}
printf("=== Exporting RSA public key ===\n");
keymaster_blob_t exported_key;
error = device->export_key(KM_KEY_FORMAT_X509, &key, nullptr, nullptr, &exported_key);
if (error != KM_ERROR_OK) {
printf("Error exporting RSA public key: %d\n\n", error);
return false;
}
printf("=== Verifying with exported key ===\n");
const uint8_t* tmp = exported_key.data;
std::unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(
d2i_PUBKEY(NULL, &tmp, exported_key.data_length));
std::unique_ptr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(EVP_PKEY_CTX_new(pkey.get(), NULL));
if (EVP_PKEY_verify_init(ctx.get()) != 1) {
printf("Error initializing openss EVP context\n\n");
return false;
}
if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) {
printf("Exported key was the wrong type?!?\n\n");
return false;
}
EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_NO_PADDING);
if (EVP_PKEY_verify(ctx.get(), signature.data, signature.data_length, message.get(),
message_len) != 1) {
printf("Verification with exported pubkey failed.\n\n");
return false;
} else {
printf("Verification succeeded\n");
}
printf("\n");
return true;
}
static bool test_import_ecdsa(TrustyKeymasterDevice* device) {
printf("=====================\n");
printf("= ECDSA Import Test =\n");
printf("=====================\n\n");
printf("=== Importing ECDSA keypair === \n");
keymaster_key_blob_t key;
keymaster_blob_t private_key = {ec_privkey_pk8_der, ec_privkey_pk8_der_len};
int error = device->import_key(&ec_param_set, KM_KEY_FORMAT_PKCS8, &private_key, &key, nullptr);
if (error != KM_ERROR_OK) {
printf("Error importing ECDSA key: %d\n\n", error);
return false;
}
std::unique_ptr<const uint8_t[]> deleter(key.key_material);
printf("=== Signing with imported ECDSA key ===\n");
size_t message_len = 30 /* arbitrary */;
std::unique_ptr<uint8_t[]> message(new uint8_t[message_len]);
memset(message.get(), 'a', message_len);
keymaster_blob_t input = {message.get(), message_len}, signature;
if (!do_operation(device, KM_PURPOSE_SIGN, &key, &input, nullptr, &signature)) {
printf("Error signing data with imported ECDSA key\n\n");
return false;
}
std::unique_ptr<const uint8_t[]> signature_deleter(signature.data);
printf("=== Verifying with imported ECDSA key === \n");
if (!do_operation(device, KM_PURPOSE_VERIFY, &key, &input, &signature, nullptr)) {
printf("Error verifying data with imported ECDSA key\n\n");
return false;
}
printf("\n");
return true;
}
static bool test_ecdsa(TrustyKeymasterDevice* device) {
printf("==============\n");
printf("= ECDSA Test =\n");
printf("==============\n\n");
printf("=== Generating ECDSA key pair ===\n");
keymaster_key_blob_t key;
int error = device->generate_key(&ec_param_set, &key, nullptr);
if (error != KM_ERROR_OK) {
printf("Error generating ECDSA key pair: %d\n\n", error);
return false;
}
std::unique_ptr<const uint8_t[]> key_deleter(key.key_material);
printf("=== Signing with ECDSA key === \n");
size_t message_len = 30 /* arbitrary */;
std::unique_ptr<uint8_t[]> message(new uint8_t[message_len]);
memset(message.get(), 'a', message_len);
keymaster_blob_t input = {message.get(), message_len}, signature;
if (!do_operation(device, KM_PURPOSE_SIGN, &key, &input, nullptr, &signature)) {
printf("Error signing data with ECDSA key\n\n");
return false;
}
std::unique_ptr<const uint8_t[]> signature_deleter(signature.data);
printf("=== Verifying with ECDSA key === \n");
if (!do_operation(device, KM_PURPOSE_VERIFY, &key, &input, &signature, nullptr)) {
printf("Error verifying data with ECDSA key\n\n");
return false;
}
printf("=== Exporting ECDSA public key ===\n");
keymaster_blob_t exported_key;
error = device->export_key(KM_KEY_FORMAT_X509, &key, nullptr, nullptr, &exported_key);
if (error != KM_ERROR_OK) {
printf("Error exporting ECDSA public key: %d\n\n", error);
return false;
}
printf("=== Verifying with exported key ===\n");
const uint8_t* tmp = exported_key.data;
std::unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(
d2i_PUBKEY(NULL, &tmp, exported_key.data_length));
std::unique_ptr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(EVP_PKEY_CTX_new(pkey.get(), NULL));
if (EVP_PKEY_verify_init(ctx.get()) != 1) {
printf("Error initializing openssl EVP context\n\n");
return false;
}
if (EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) {
printf("Exported key was the wrong type?!?\n\n");
return false;
}
if (EVP_PKEY_verify(ctx.get(), signature.data, signature.data_length, message.get(),
message_len) != 1) {
printf("Verification with exported pubkey failed.\n\n");
return false;
} else {
printf("Verification succeeded\n");
}
printf("\n");
return true;
}
int main(void) {
TrustyKeymasterDevice device(NULL);
keymaster::ConfigureDevice(reinterpret_cast<keymaster2_device_t*>(&device));
if (device.session_error() != KM_ERROR_OK) {
printf("Failed to initialize Trusty session: %d\n", device.session_error());
return 1;
}
printf("Trusty session initialized\n");
bool success = true;
success &= test_rsa(&device);
success &= test_import_rsa(&device);
success &= test_ecdsa(&device);
success &= test_import_ecdsa(&device);
if (success) {
printf("\nTESTS PASSED!\n");
} else {
printf("\n!!!!TESTS FAILED!!!\n");
}
return success ? 0 : 1;
}