diff --git a/trusty/keymaster/Android.mk b/trusty/keymaster/Android.mk index 0ebf52d8a..2d614aec6 100644 --- a/trusty/keymaster/Android.mk +++ b/trusty/keymaster/Android.mk @@ -32,7 +32,7 @@ include $(CLEAR_VARS) LOCAL_MODULE := trusty_keymaster_tipc LOCAL_SRC_FILES := \ trusty_keymaster_device.cpp \ - trusty_keymaster_ipc.c \ + trusty_keymaster_ipc.cpp \ trusty_keymaster_main.cpp LOCAL_SHARED_LIBRARIES := \ libcrypto \ @@ -40,6 +40,7 @@ LOCAL_SHARED_LIBRARIES := \ libkeymaster1 \ libtrusty \ libkeymaster_messages \ + libsoftkeymasterdevice \ liblog include $(BUILD_EXECUTABLE) @@ -53,7 +54,7 @@ include $(CLEAR_VARS) LOCAL_MODULE := keystore.trusty LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_SRC_FILES := module.cpp \ - trusty_keymaster_ipc.c \ + trusty_keymaster_ipc.cpp \ trusty_keymaster_device.cpp LOCAL_CLFAGS = -fvisibility=hidden -Wall -Werror LOCAL_SHARED_LIBRARIES := \ diff --git a/trusty/keymaster/keymaster_ipc.h b/trusty/keymaster/keymaster_ipc.h index 48fa53d15..b38eb0592 100644 --- a/trusty/keymaster/keymaster_ipc.h +++ b/trusty/keymaster/keymaster_ipc.h @@ -16,13 +16,15 @@ #pragma once +// clang-format off + #define KEYMASTER_PORT "com.android.trusty.keymaster" #define KEYMASTER_MAX_BUFFER_LENGTH 4096 // Commands -enum keymaster_command { - KEYMASTER_RESP_BIT = 1, - KEYMASTER_REQ_SHIFT = 1, +enum keymaster_command : uint32_t { + KEYMASTER_RESP_BIT = 1, + KEYMASTER_REQ_SHIFT = 1, KM_GENERATE_KEY = (0 << KEYMASTER_REQ_SHIFT), KM_BEGIN_OPERATION = (1 << KEYMASTER_REQ_SHIFT), @@ -40,6 +42,9 @@ enum keymaster_command { KM_GET_SUPPORTED_IMPORT_FORMATS = (13 << KEYMASTER_REQ_SHIFT), KM_GET_SUPPORTED_EXPORT_FORMATS = (14 << KEYMASTER_REQ_SHIFT), KM_GET_KEY_CHARACTERISTICS = (15 << KEYMASTER_REQ_SHIFT), + KM_ATTEST_KEY = (16 << KEYMASTER_REQ_SHIFT), + KM_UPGRADE_KEY = (17 << KEYMASTER_REQ_SHIFT), + KM_CONFIGURE = (18 << KEYMASTER_REQ_SHIFT), }; #ifdef __ANDROID__ @@ -50,8 +55,8 @@ enum keymaster_command { * @payload: start of the serialized command specific payload */ struct keymaster_message { - uint32_t cmd; - uint8_t payload[0]; + uint32_t cmd; + uint8_t payload[0]; }; #endif diff --git a/trusty/keymaster/module.cpp b/trusty/keymaster/module.cpp index 81597d9b0..b472680fb 100644 --- a/trusty/keymaster/module.cpp +++ b/trusty/keymaster/module.cpp @@ -26,14 +26,15 @@ 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) +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) + 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. @@ -47,14 +48,14 @@ static struct hw_module_methods_t keystore_module_methods = { struct keystore_module HAL_MODULE_INFO_SYM __attribute__((visibility("default"))) = { .common = { - .tag = HARDWARE_MODULE_TAG, - .module_api_version = KEYMASTER_MODULE_API_VERSION_0_3, - .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 = {}, + .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 = {}, }, }; diff --git a/trusty/keymaster/trusty_keymaster_device.cpp b/trusty/keymaster/trusty_keymaster_device.cpp index 1368f8803..5f16fd0c0 100644 --- a/trusty/keymaster/trusty_keymaster_device.cpp +++ b/trusty/keymaster/trusty_keymaster_device.cpp @@ -25,49 +25,53 @@ #include #include +#include #include -#include +#include #include #include +#include "keymaster_ipc.h" #include "trusty_keymaster_device.h" #include "trusty_keymaster_ipc.h" -#include "keymaster_ipc.h" -const uint32_t SEND_BUF_SIZE = 8192; -const uint32_t RECV_BUF_SIZE = 8192; +const uint32_t RECV_BUF_SIZE = PAGE_SIZE; +const uint32_t SEND_BUF_SIZE = (PAGE_SIZE - sizeof(struct keymaster_message) - 16 /* tipc header */); + +const size_t kMaximumAttestationChallengeLength = 128; +const size_t kMaximumFinishInputLength = 2048; namespace keymaster { static keymaster_error_t translate_error(int err) { switch (err) { - case 0: - return KM_ERROR_OK; - case -EPERM: - case -EACCES: - return KM_ERROR_SECURE_HW_ACCESS_DENIED; + case 0: + return KM_ERROR_OK; + case -EPERM: + case -EACCES: + return KM_ERROR_SECURE_HW_ACCESS_DENIED; - case -ECANCELED: - return KM_ERROR_OPERATION_CANCELLED; + case -ECANCELED: + return KM_ERROR_OPERATION_CANCELLED; - case -ENODEV: - return KM_ERROR_UNIMPLEMENTED; + case -ENODEV: + return KM_ERROR_UNIMPLEMENTED; - case -ENOMEM: - return KM_ERROR_MEMORY_ALLOCATION_FAILED; + case -ENOMEM: + return KM_ERROR_MEMORY_ALLOCATION_FAILED; - case -EBUSY: - return KM_ERROR_SECURE_HW_BUSY; + case -EBUSY: + return KM_ERROR_SECURE_HW_BUSY; - case -EIO: - return KM_ERROR_SECURE_HW_COMMUNICATION_FAILED; + case -EIO: + return KM_ERROR_SECURE_HW_COMMUNICATION_FAILED; - case -EOVERFLOW: - return KM_ERROR_INVALID_INPUT_LENGTH; + case -EOVERFLOW: + return KM_ERROR_INVALID_INPUT_LENGTH; - default: - return KM_ERROR_UNKNOWN_ERROR; + default: + return KM_ERROR_UNKNOWN_ERROR; } } @@ -75,31 +79,36 @@ TrustyKeymasterDevice::TrustyKeymasterDevice(const hw_module_t* module) { static_assert(std::is_standard_layout::value, "TrustyKeymasterDevice must be standard layout"); static_assert(offsetof(TrustyKeymasterDevice, device_) == 0, - "device_ must be the first member of KeymasterOpenSsl"); + "device_ must be the first member of TrustyKeymasterDevice"); static_assert(offsetof(TrustyKeymasterDevice, device_.common) == 0, - "common must be the first member of keymaster_device"); + "common must be the first member of keymaster2_device"); ALOGI("Creating device"); ALOGD("Device address: %p", this); - memset(&device_, 0, sizeof(device_)); + device_ = {}; device_.common.tag = HARDWARE_DEVICE_TAG; device_.common.version = 1; device_.common.module = const_cast(module); device_.common.close = close_device; - device_.flags = KEYMASTER_BLOBS_ARE_STANDALONE | KEYMASTER_SUPPORTS_EC; + device_.flags = KEYMASTER_SUPPORTS_EC; - device_.generate_keypair = generate_keypair; - device_.import_keypair = import_keypair; - device_.get_keypair_public = get_keypair_public; - device_.delete_keypair = NULL; - device_.delete_all = NULL; - device_.sign_data = sign_data; - device_.verify_data = verify_data; - - device_.context = NULL; + 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 = nullptr; + device_.delete_all_keys = nullptr; + device_.begin = begin; + device_.update = update; + device_.finish = finish; + device_.abort = abort; int rc = trusty_keymaster_connect(); error_ = translate_error(rc); @@ -110,11 +119,11 @@ TrustyKeymasterDevice::TrustyKeymasterDevice(const hw_module_t* module) { GetVersionRequest version_request; GetVersionResponse version_response; - error_ = Send(version_request, &version_response); + error_ = Send(KM_GET_VERSION, version_request, &version_response); if (error_ == KM_ERROR_INVALID_ARGUMENT || error_ == KM_ERROR_UNIMPLEMENTED) { - ALOGI("\"Bad parameters\" error on GetVersion call. Assuming version 0."); - message_version_ = 0; - error_ = KM_ERROR_OK; + 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); @@ -130,261 +139,510 @@ TrustyKeymasterDevice::~TrustyKeymasterDevice() { trusty_keymaster_disconnect(); } -const uint64_t HUNDRED_YEARS = 1000LL * 60 * 60 * 24 * 365 * 100; +namespace { -int TrustyKeymasterDevice::generate_keypair(const keymaster_keypair_t key_type, - const void* key_params, uint8_t** key_blob, - size_t* key_blob_length) { - ALOGD("Device received generate_keypair"); +// 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(malloc(size)); + if (tmp) { + memcpy(tmp, buffer, size); + } + return tmp; +} - if (error_ != KM_ERROR_OK) +template +void AddClientAndAppData(const keymaster_blob_t* client_id, const keymaster_blob_t* app_data, + RequestType* request) { + request->additional_params.Clear(); + if (client_id) { + request->additional_params.push_back(TAG_APPLICATION_ID, *client_id); + } + if (app_data) { + 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_; - - GenerateKeyRequest req(message_version_); - StoreNewKeyParams(&req.key_description); - - switch (key_type) { - case TYPE_RSA: { - req.key_description.push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA); - const keymaster_rsa_keygen_params_t* rsa_params = - static_cast(key_params); - ALOGD("Generating RSA pair, modulus size: %u, public exponent: %lu", - rsa_params->modulus_size, rsa_params->public_exponent); - req.key_description.push_back(TAG_KEY_SIZE, rsa_params->modulus_size); - req.key_description.push_back(TAG_RSA_PUBLIC_EXPONENT, rsa_params->public_exponent); - break; + } + if (!params) { + return KM_ERROR_UNEXPECTED_NULL_POINTER; } - case TYPE_EC: { - req.key_description.push_back(TAG_ALGORITHM, KM_ALGORITHM_EC); - const keymaster_ec_keygen_params_t* ec_params = - static_cast(key_params); - ALOGD("Generating ECDSA pair, key size: %u", ec_params->field_size); - req.key_description.push_back(TAG_KEY_SIZE, ec_params->field_size); - break; - } - default: - ALOGD("Received request for unsuported key type %d", key_type); - return KM_ERROR_UNSUPPORTED_ALGORITHM; + AuthorizationSet params_copy(*params); + ConfigureRequest request; + 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; } - GenerateKeyResponse rsp(message_version_); - ALOGD("Sending generate request"); - keymaster_error_t err = Send(req, &rsp); + ConfigureResponse response; + keymaster_error_t err = Send(KM_CONFIGURE, request, &response); if (err != KM_ERROR_OK) { - ALOGE("Got error %d from send", err); return err; } - *key_blob_length = rsp.key_blob.key_material_size; - *key_blob = static_cast(malloc(*key_blob_length)); - memcpy(*key_blob, rsp.key_blob.key_material, *key_blob_length); - ALOGD("Returning %d bytes in key blob\n", (int)*key_blob_length); - return KM_ERROR_OK; } -struct EVP_PKEY_Delete { - void operator()(EVP_PKEY* p) const { EVP_PKEY_free(p); } -}; +keymaster_error_t TrustyKeymasterDevice::add_rng_entropy(const uint8_t* data, size_t data_length) { + ALOGD("Device received add_rng_entropy"); -struct PKCS8_PRIV_KEY_INFO_Delete { - void operator()(PKCS8_PRIV_KEY_INFO* p) const { PKCS8_PRIV_KEY_INFO_free(p); } -}; - -int TrustyKeymasterDevice::import_keypair(const uint8_t* key, const size_t key_length, - uint8_t** key_blob, size_t* key_blob_length) { - ALOGD("Device received import_keypair"); - if (error_ != KM_ERROR_OK) + if (error_ != KM_ERROR_OK) { return error_; + } - if (!key) + AddEntropyRequest request; + request.random_data.Reinitialize(data, data_length); + AddEntropyResponse response; + return 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 || !key_blob_length) + } + 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 = 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; + request.SetKeyMaterial(*key_blob); + AddClientAndAppData(client_id, app_data, &request); + + GetKeyCharacteristicsResponse response; + keymaster_error_t err = 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_); - StoreNewKeyParams(&request.key_description); - keymaster_algorithm_t algorithm; - keymaster_error_t err = GetPkcs8KeyAlgorithm(key, key_length, &algorithm); - if (err != KM_ERROR_OK) - return err; - request.key_description.push_back(TAG_ALGORITHM, algorithm); + 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); - request.SetKeyMaterial(key, key_length); - request.key_format = KM_KEY_FORMAT_PKCS8; ImportKeyResponse response(message_version_); - err = Send(request, &response); - if (err != KM_ERROR_OK) + keymaster_error_t err = Send(KM_IMPORT_KEY, request, &response); + if (err != KM_ERROR_OK) { return err; + } - *key_blob_length = response.key_blob.key_material_size; - *key_blob = static_cast(malloc(*key_blob_length)); - memcpy(*key_blob, response.key_blob.key_material, *key_blob_length); - printf("Returning %d bytes in key blob\n", (int)*key_blob_length); + 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::GetPkcs8KeyAlgorithm(const uint8_t* key, size_t key_length, - keymaster_algorithm_t* algorithm) { - if (key == NULL) { - ALOGE("No key specified for import"); +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; } - - UniquePtr pkcs8( - d2i_PKCS8_PRIV_KEY_INFO(NULL, &key, key_length)); - if (pkcs8.get() == NULL) { - ALOGE("Could not parse PKCS8 key blob"); - return KM_ERROR_INVALID_KEY_BLOB; + if (!export_data) { + return KM_ERROR_OUTPUT_PARAMETER_NULL; } - UniquePtr pkey(EVP_PKCS82PKEY(pkcs8.get())); - if (pkey.get() == NULL) { - ALOGE("Could not extract key from PKCS8 key blob"); - return KM_ERROR_INVALID_KEY_BLOB; - } - - switch (EVP_PKEY_type(pkey->type)) { - case EVP_PKEY_RSA: - *algorithm = KM_ALGORITHM_RSA; - break; - case EVP_PKEY_EC: - *algorithm = KM_ALGORITHM_EC; - break; - default: - ALOGE("Unsupported algorithm %d", EVP_PKEY_type(pkey->type)); - return KM_ERROR_UNSUPPORTED_ALGORITHM; - } - - return KM_ERROR_OK; -} - -int TrustyKeymasterDevice::get_keypair_public(const uint8_t* key_blob, const size_t key_blob_length, - uint8_t** x509_data, size_t* x509_data_length) { - ALOGD("Device received get_keypair_public"); - if (error_ != KM_ERROR_OK) - return error_; + export_data->data = nullptr; + export_data->data_length = 0; ExportKeyRequest request(message_version_); - request.SetKeyMaterial(key_blob, key_blob_length); - request.key_format = KM_KEY_FORMAT_X509; + request.key_format = export_format; + request.SetKeyMaterial(*key_to_export); + AddClientAndAppData(client_id, app_data, &request); + ExportKeyResponse response(message_version_); - keymaster_error_t err = Send(request, &response); - if (err != KM_ERROR_OK) + keymaster_error_t err = Send(KM_EXPORT_KEY, request, &response); + if (err != KM_ERROR_OK) { return err; + } - *x509_data_length = response.key_data_length; - *x509_data = static_cast(malloc(*x509_data_length)); - memcpy(*x509_data, response.key_data, *x509_data_length); - printf("Returning %d bytes in x509 key\n", (int)*x509_data_length); + 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; } -int TrustyKeymasterDevice::sign_data(const void* signing_params, const uint8_t* key_blob, - const size_t key_blob_length, const uint8_t* data, - const size_t data_length, uint8_t** signed_data, - size_t* signed_data_length) { - ALOGD("Device received sign_data, %d", error_); - if (error_ != 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; + } - BeginOperationRequest begin_request(message_version_); - begin_request.purpose = KM_PURPOSE_SIGN; - begin_request.SetKeyMaterial(key_blob, key_blob_length); - keymaster_error_t err = StoreSigningParams(signing_params, key_blob, key_blob_length, - &begin_request.additional_params); + cert_chain->entry_count = 0; + cert_chain->entries = nullptr; + + AttestKeyRequest request; + 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; + keymaster_error_t err = Send(KM_ATTEST_KEY, request, &response); if (err != KM_ERROR_OK) { - ALOGE("Error extracting signing params: %d", err); return err; } - BeginOperationResponse begin_response(message_version_); - ALOGD("Sending signing request begin"); - err = Send(begin_request, &begin_response); - if (err != KM_ERROR_OK) { - ALOGE("Error sending sign begin: %d", err); - return err; + // Allocate and clear storage for cert_chain. + keymaster_cert_chain_t& rsp_chain = response.certificate_chain; + cert_chain->entries = reinterpret_cast( + 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 = {}; } - UpdateOperationRequest update_request(message_version_); - update_request.op_handle = begin_response.op_handle; - update_request.input.Reinitialize(data, data_length); - UpdateOperationResponse update_response(message_version_); - ALOGD("Sending signing request update"); - err = Send(update_request, &update_response); - if (err != KM_ERROR_OK) { - ALOGE("Error sending sign update: %d", err); - return err; + // 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; } - FinishOperationRequest finish_request(message_version_); - finish_request.op_handle = begin_response.op_handle; - FinishOperationResponse finish_response(message_version_); - ALOGD("Sending signing request finish"); - err = Send(finish_request, &finish_response); - if (err != KM_ERROR_OK) { - ALOGE("Error sending sign finish: %d", err); - return err; - } - - *signed_data_length = finish_response.output.available_read(); - *signed_data = static_cast(malloc(*signed_data_length)); - if (!finish_response.output.read(*signed_data, *signed_data_length)) { - ALOGE("Error reading response data: %d", err); - return KM_ERROR_UNKNOWN_ERROR; - } return KM_ERROR_OK; } -int TrustyKeymasterDevice::verify_data(const void* signing_params, const uint8_t* key_blob, - const size_t key_blob_length, const uint8_t* signed_data, - const size_t signed_data_length, const uint8_t* signature, - const size_t signature_length) { - ALOGD("Device received verify_data"); - if (error_ != 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; + } - BeginOperationRequest begin_request(message_version_); - begin_request.purpose = KM_PURPOSE_VERIFY; - begin_request.SetKeyMaterial(key_blob, key_blob_length); - keymaster_error_t err = StoreSigningParams(signing_params, key_blob, key_blob_length, - &begin_request.additional_params); - if (err != KM_ERROR_OK) - return err; + UpgradeKeyRequest request; + request.SetKeyMaterial(*key_to_upgrade); + request.upgrade_params.Reinitialize(*upgrade_params); - BeginOperationResponse begin_response(message_version_); - err = Send(begin_request, &begin_response); - if (err != KM_ERROR_OK) + UpgradeKeyResponse response; + keymaster_error_t err = Send(KM_UPGRADE_KEY, request, &response); + if (err != KM_ERROR_OK) { return err; + } - UpdateOperationRequest update_request(message_version_); - update_request.op_handle = begin_response.op_handle; - update_request.input.Reinitialize(signed_data, signed_data_length); - UpdateOperationResponse update_response(message_version_); - err = Send(update_request, &update_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; + } - FinishOperationRequest finish_request(message_version_); - finish_request.op_handle = begin_response.op_handle; - finish_request.signature.Reinitialize(signature, signature_length); - FinishOperationResponse finish_response(message_version_); - err = Send(finish_request, &finish_response); - if (err != KM_ERROR_OK) - return err; 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; + request.purpose = purpose; + request.SetKeyMaterial(*key); + request.additional_params.Reinitialize(*in_params); + + BeginOperationResponse response; + keymaster_error_t err = 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; + 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 = SEND_BUF_SIZE - request.SerializedSize(); + request.input.Reinitialize(input->data, std::min(input->data_length, max_input_size)); + } + + UpdateOperationResponse response; + keymaster_error_t err = 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) { + return KM_ERROR_INVALID_ARGUMENT; + } + + if (out_params) { + *out_params = {}; + } + if (output) { + *output = {}; + } + + FinishOperationRequest request; + 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; + keymaster_error_t err = 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; + request.op_handle = operation_handle; + AbortOperationResponse response; + return Send(KM_ABORT_OPERATION, request, &response); +} + hw_device_t* TrustyKeymasterDevice::hw_device() { return &device_.common; } -static inline TrustyKeymasterDevice* convert_device(const keymaster0_device_t* dev) { - return reinterpret_cast(const_cast(dev)); +static inline TrustyKeymasterDevice* convert_device(const keymaster2_device_t* dev) { + return reinterpret_cast(const_cast(dev)); } /* static */ @@ -394,52 +652,111 @@ int TrustyKeymasterDevice::close_device(hw_device_t* dev) { } /* static */ -int TrustyKeymasterDevice::generate_keypair(const keymaster0_device_t* dev, - const keymaster_keypair_t key_type, - const void* key_params, uint8_t** keyBlob, - size_t* keyBlobLength) { - ALOGD("Generate keypair, sending to device: %p", convert_device(dev)); - return convert_device(dev)->generate_keypair(key_type, key_params, keyBlob, keyBlobLength); +keymaster_error_t TrustyKeymasterDevice::configure(const keymaster2_device_t* dev, + const keymaster_key_param_set_t* params) { + return convert_device(dev)->configure(params); } /* static */ -int TrustyKeymasterDevice::import_keypair(const keymaster0_device_t* dev, const uint8_t* key, - const size_t key_length, uint8_t** key_blob, - size_t* key_blob_length) { - return convert_device(dev)->import_keypair(key, key_length, key_blob, key_blob_length); +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 */ -int TrustyKeymasterDevice::get_keypair_public(const keymaster0_device_t* dev, - const uint8_t* key_blob, const size_t key_blob_length, - uint8_t** x509_data, size_t* x509_data_length) { - return convert_device(dev) - ->get_keypair_public(key_blob, key_blob_length, x509_data, x509_data_length); +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 */ -int TrustyKeymasterDevice::sign_data(const keymaster0_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) { - return convert_device(dev) - ->sign_data(params, keyBlob, keyBlobLength, data, dataLength, signedData, signedDataLength); +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 */ -int TrustyKeymasterDevice::verify_data(const keymaster0_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) { - return convert_device(dev)->verify_data(params, keyBlob, keyBlobLength, signedData, - signedDataLength, signature, signatureLength); +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); } keymaster_error_t TrustyKeymasterDevice::Send(uint32_t command, const Serializable& req, KeymasterResponse* rsp) { uint32_t req_size = req.SerializedSize(); - if (req_size > SEND_BUF_SIZE) + if (req_size > SEND_BUF_SIZE) { return KM_ERROR_MEMORY_ALLOCATION_FAILED; + } uint8_t send_buf[SEND_BUF_SIZE]; Eraser send_buf_eraser(send_buf, SEND_BUF_SIZE); req.Serialize(send_buf, send_buf + req_size); @@ -448,7 +765,7 @@ keymaster_error_t TrustyKeymasterDevice::Send(uint32_t command, const Serializab uint8_t recv_buf[RECV_BUF_SIZE]; Eraser recv_buf_eraser(recv_buf, RECV_BUF_SIZE); uint32_t rsp_size = RECV_BUF_SIZE; - printf("Sending %d byte request\n", (int)req.SerializedSize()); + ALOGV("Sending %d byte request\n", (int)req.SerializedSize()); int rc = trusty_keymaster_call(command, send_buf, req_size, recv_buf, &rsp_size); if (rc < 0) { ALOGE("tipc error: %d\n", rc); @@ -458,8 +775,8 @@ keymaster_error_t TrustyKeymasterDevice::Send(uint32_t command, const Serializab ALOGV("Received %d byte response\n", rsp_size); } - const keymaster_message* msg = (keymaster_message *) recv_buf; - const uint8_t *p = msg->payload; + const keymaster_message* msg = (keymaster_message*)recv_buf; + const uint8_t* p = msg->payload; if (!rsp->Deserialize(&p, p + rsp_size)) { ALOGE("Error deserializing response of size %d\n", (int)rsp_size); return KM_ERROR_UNKNOWN_ERROR; @@ -470,65 +787,4 @@ keymaster_error_t TrustyKeymasterDevice::Send(uint32_t command, const Serializab return rsp->error; } -keymaster_error_t TrustyKeymasterDevice::StoreSigningParams(const void* signing_params, - const uint8_t* key_blob, - size_t key_blob_length, - AuthorizationSet* auth_set) { - uint8_t* pub_key_data; - size_t pub_key_data_length; - int err = get_keypair_public(&device_, key_blob, key_blob_length, &pub_key_data, - &pub_key_data_length); - if (err < 0) { - ALOGE("Error %d extracting public key to determine algorithm", err); - return KM_ERROR_INVALID_KEY_BLOB; - } - UniquePtr pub_key(pub_key_data); - - const uint8_t* p = pub_key_data; - UniquePtr pkey( - d2i_PUBKEY(nullptr /* allocate new struct */, &p, pub_key_data_length)); - - switch (EVP_PKEY_type(pkey->type)) { - case EVP_PKEY_RSA: { - const keymaster_rsa_sign_params_t* rsa_params = - reinterpret_cast(signing_params); - if (rsa_params->digest_type != DIGEST_NONE) - return KM_ERROR_UNSUPPORTED_DIGEST; - if (rsa_params->padding_type != PADDING_NONE) - return KM_ERROR_UNSUPPORTED_PADDING_MODE; - if (!auth_set->push_back(TAG_DIGEST, KM_DIGEST_NONE) || - !auth_set->push_back(TAG_PADDING, KM_PAD_NONE)) - return KM_ERROR_MEMORY_ALLOCATION_FAILED; - } break; - case EVP_PKEY_EC: { - const keymaster_ec_sign_params_t* ecdsa_params = - reinterpret_cast(signing_params); - if (ecdsa_params->digest_type != DIGEST_NONE) - return KM_ERROR_UNSUPPORTED_DIGEST; - if (!auth_set->push_back(TAG_DIGEST, KM_DIGEST_NONE)) - return KM_ERROR_MEMORY_ALLOCATION_FAILED; - } break; - default: - return KM_ERROR_UNSUPPORTED_ALGORITHM; - } - return KM_ERROR_OK; -} - -void TrustyKeymasterDevice::StoreNewKeyParams(AuthorizationSet* auth_set) { - auth_set->push_back(TAG_PURPOSE, KM_PURPOSE_SIGN); - auth_set->push_back(TAG_PURPOSE, KM_PURPOSE_VERIFY); - auth_set->push_back(TAG_ALL_USERS); - auth_set->push_back(TAG_NO_AUTH_REQUIRED); - uint64_t now = java_time(time(NULL)); - auth_set->push_back(TAG_CREATION_DATETIME, now); - auth_set->push_back(TAG_ORIGINATION_EXPIRE_DATETIME, now + HUNDRED_YEARS); - if (message_version_ == 0) { - auth_set->push_back(TAG_DIGEST_OLD, KM_DIGEST_NONE); - auth_set->push_back(TAG_PADDING_OLD, KM_PAD_NONE); - } else { - auth_set->push_back(TAG_DIGEST, KM_DIGEST_NONE); - auth_set->push_back(TAG_PADDING, KM_PAD_NONE); - } -} - } // namespace keymaster diff --git a/trusty/keymaster/trusty_keymaster_device.h b/trusty/keymaster/trusty_keymaster_device.h index 68cf40ca2..cfada1b3c 100644 --- a/trusty/keymaster/trusty_keymaster_device.h +++ b/trusty/keymaster/trusty_keymaster_device.h @@ -14,19 +14,16 @@ * limitations under the License. */ -#ifndef EXTERNAL_KEYMASTER_TRUSTY_KEYMASTER_DEVICE_H_ -#define EXTERNAL_KEYMASTER_TRUSTY_KEYMASTER_DEVICE_H_ - -#include +#ifndef TRUSTY_KEYMASTER_TRUSTY_KEYMASTER_DEVICE_H_ +#define TRUSTY_KEYMASTER_TRUSTY_KEYMASTER_DEVICE_H_ +#include #include -#include "keymaster_ipc.h" - namespace keymaster { /** - * Software OpenSSL-based Keymaster device. + * Trusty Keymaster device. * * IMPORTANT MAINTAINER NOTE: Pointers to instances of this class must be castable to hw_device_t * and keymaster_device. This means it must remain a standard layout class (no virtual functions and @@ -46,79 +43,111 @@ class TrustyKeymasterDevice { keymaster_error_t session_error() { return error_; } - int generate_keypair(const keymaster_keypair_t key_type, const void* key_params, - uint8_t** key_blob, size_t* key_blob_length); - int import_keypair(const uint8_t* key, const size_t key_length, uint8_t** key_blob, - size_t* key_blob_length); - int get_keypair_public(const uint8_t* key_blob, const size_t key_blob_length, - uint8_t** x509_data, size_t* x509_data_length); - int sign_data(const void* signing_params, const uint8_t* key_blob, const size_t key_blob_length, - const uint8_t* data, const size_t data_length, uint8_t** signed_data, - size_t* signed_data_length); - int verify_data(const void* signing_params, const uint8_t* key_blob, - const size_t key_blob_length, const uint8_t* signed_data, - const size_t signed_data_length, const uint8_t* signature, - const size_t signature_length); + keymaster_error_t configure(const keymaster_key_param_set_t* params); + keymaster_error_t add_rng_entropy(const uint8_t* data, size_t data_length); + keymaster_error_t generate_key(const keymaster_key_param_set_t* params, + keymaster_key_blob_t* key_blob, + keymaster_key_characteristics_t* characteristics); + keymaster_error_t 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* character); + keymaster_error_t 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); + keymaster_error_t 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); + keymaster_error_t attest_key(const keymaster_key_blob_t* key_to_attest, + const keymaster_key_param_set_t* attest_params, + keymaster_cert_chain_t* cert_chain); + keymaster_error_t upgrade_key(const keymaster_key_blob_t* key_to_upgrade, + const keymaster_key_param_set_t* upgrade_params, + keymaster_key_blob_t* upgraded_key); + keymaster_error_t 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); + keymaster_error_t 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); + keymaster_error_t 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); + keymaster_error_t abort(keymaster_operation_handle_t operation_handle); private: keymaster_error_t Send(uint32_t command, const Serializable& request, KeymasterResponse* response); - keymaster_error_t Send(const GenerateKeyRequest& request, GenerateKeyResponse* response) { - return Send(KM_GENERATE_KEY, request, response); - } - keymaster_error_t Send(const BeginOperationRequest& request, BeginOperationResponse* response) { - return Send(KM_BEGIN_OPERATION, request, response); - } - keymaster_error_t Send(const UpdateOperationRequest& request, - UpdateOperationResponse* response) { - return Send(KM_UPDATE_OPERATION, request, response); - } - keymaster_error_t Send(const FinishOperationRequest& request, - FinishOperationResponse* response) { - return Send(KM_FINISH_OPERATION, request, response); - } - keymaster_error_t Send(const ImportKeyRequest& request, ImportKeyResponse* response) { - return Send(KM_IMPORT_KEY, request, response); - } - keymaster_error_t Send(const ExportKeyRequest& request, ExportKeyResponse* response) { - return Send(KM_EXPORT_KEY, request, response); - } - keymaster_error_t Send(const GetVersionRequest& request, GetVersionResponse* response) { - return Send(KM_GET_VERSION, request, response); - } - - keymaster_error_t StoreSigningParams(const void* signing_params, const uint8_t* key_blob, - size_t key_blob_length, AuthorizationSet* auth_set); - void StoreNewKeyParams(AuthorizationSet* auth_set); - keymaster_error_t GetPkcs8KeyAlgorithm(const uint8_t* key, size_t key_length, - keymaster_algorithm_t* algorithm); /* * These static methods are the functions referenced through the function pointers in * keymaster_device. They're all trivial wrappers. */ static int close_device(hw_device_t* dev); - static int generate_keypair(const keymaster0_device_t* dev, const keymaster_keypair_t key_type, - const void* key_params, uint8_t** keyBlob, size_t* keyBlobLength); - static int import_keypair(const keymaster0_device_t* dev, const uint8_t* key, - const size_t key_length, uint8_t** key_blob, size_t* key_blob_length); - static int get_keypair_public(const keymaster0_device_t* dev, const uint8_t* key_blob, - const size_t key_blob_length, uint8_t** x509_data, - size_t* x509_data_length); - static int sign_data(const keymaster0_device_t* dev, const void* signing_params, - const uint8_t* key_blob, const size_t key_blob_length, const uint8_t* data, - const size_t data_length, uint8_t** signed_data, - size_t* signed_data_length); - static int verify_data(const keymaster0_device_t* dev, const void* signing_params, - const uint8_t* key_blob, const size_t key_blob_length, - const uint8_t* signed_data, const size_t signed_data_length, - const uint8_t* signature, const size_t signature_length); + static keymaster_error_t configure(const keymaster2_device_t* dev, + const keymaster_key_param_set_t* params); + static keymaster_error_t add_rng_entropy(const keymaster2_device_t* dev, const uint8_t* data, + size_t data_length); + static keymaster_error_t 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); + static keymaster_error_t 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* character); + static keymaster_error_t 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); + static keymaster_error_t 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); + static keymaster_error_t 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); + static keymaster_error_t 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); + static keymaster_error_t delete_key(const keymaster2_device_t* dev, + const keymaster_key_blob_t* key); + static keymaster_error_t delete_all_keys(const keymaster2_device_t* dev); + static keymaster_error_t 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); + static keymaster_error_t 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); + static keymaster_error_t 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); + static keymaster_error_t abort(const keymaster2_device_t* dev, + keymaster_operation_handle_t operation_handle); - keymaster0_device_t device_; + keymaster2_device_t device_; keymaster_error_t error_; int32_t message_version_; }; } // namespace keymaster -#endif // EXTERNAL_KEYMASTER_TRUSTY_KEYMASTER_DEVICE_H_ +#endif // TRUSTY_KEYMASTER_TRUSTY_KEYMASTER_DEVICE_H_ diff --git a/trusty/keymaster/trusty_keymaster_ipc.c b/trusty/keymaster/trusty_keymaster_ipc.cpp similarity index 75% rename from trusty/keymaster/trusty_keymaster_ipc.c rename to trusty/keymaster/trusty_keymaster_ipc.cpp index 88546af28..cdc27782a 100644 --- a/trusty/keymaster/trusty_keymaster_ipc.c +++ b/trusty/keymaster/trusty_keymaster_ipc.cpp @@ -26,8 +26,8 @@ #include #include -#include "trusty_keymaster_ipc.h" #include "keymaster_ipc.h" +#include "trusty_keymaster_ipc.h" #define TRUSTY_DEVICE_NAME "/dev/trusty-ipc-dev0" @@ -43,15 +43,15 @@ int trusty_keymaster_connect() { return 0; } -int trusty_keymaster_call(uint32_t cmd, void *in, uint32_t in_size, uint8_t *out, - uint32_t *out_size) { +int trusty_keymaster_call(uint32_t cmd, void* in, uint32_t in_size, uint8_t* out, + uint32_t* out_size) { if (handle_ == 0) { ALOGE("not connected\n"); return -EINVAL; } size_t msg_size = in_size + sizeof(struct keymaster_message); - struct keymaster_message *msg = malloc(msg_size); + struct keymaster_message* msg = reinterpret_cast(malloc(msg_size)); msg->cmd = cmd; memcpy(msg->payload, in, in_size); @@ -59,31 +59,30 @@ int trusty_keymaster_call(uint32_t cmd, void *in, uint32_t in_size, uint8_t *out free(msg); if (rc < 0) { - ALOGE("failed to send cmd (%d) to %s: %s\n", cmd, - KEYMASTER_PORT, strerror(errno)); + ALOGE("failed to send cmd (%d) to %s: %s\n", cmd, KEYMASTER_PORT, strerror(errno)); return -errno; } rc = read(handle_, out, *out_size); if (rc < 0) { - ALOGE("failed to retrieve response for cmd (%d) to %s: %s\n", - cmd, KEYMASTER_PORT, strerror(errno)); + ALOGE("failed to retrieve response for cmd (%d) to %s: %s\n", cmd, KEYMASTER_PORT, + strerror(errno)); return -errno; } - if ((size_t) rc < sizeof(struct keymaster_message)) { - ALOGE("invalid response size (%d)\n", (int) rc); + if ((size_t)rc < sizeof(struct keymaster_message)) { + ALOGE("invalid response size (%d)\n", (int)rc); return -EINVAL; } - msg = (struct keymaster_message *) out; + msg = (struct keymaster_message*)out; if ((cmd | KEYMASTER_RESP_BIT) != msg->cmd) { ALOGE("invalid command (%d)", msg->cmd); return -EINVAL; } - *out_size = ((size_t) rc) - sizeof(struct keymaster_message); + *out_size = ((size_t)rc) - sizeof(struct keymaster_message); return rc; } @@ -92,4 +91,3 @@ void trusty_keymaster_disconnect() { tipc_close(handle_); } } - diff --git a/trusty/keymaster/trusty_keymaster_ipc.h b/trusty/keymaster/trusty_keymaster_ipc.h index 978524766..c15f7c1da 100644 --- a/trusty/keymaster/trusty_keymaster_ipc.h +++ b/trusty/keymaster/trusty_keymaster_ipc.h @@ -14,11 +14,16 @@ * limitations under the License. */ +#ifndef TRUSTY_KEYMASTER_TRUSTY_KEYMASTER_IPC_H_ +#define TRUSTY_KEYMASTER_TRUSTY_KEYMASTER_IPC_H_ + __BEGIN_DECLS int trusty_keymaster_connect(void); -int trusty_keymaster_call(uint32_t cmd, void *in, uint32_t in_size, uint8_t *out, - uint32_t *out_size); +int trusty_keymaster_call(uint32_t cmd, void* in, uint32_t in_size, uint8_t* out, + uint32_t* out_size); void trusty_keymaster_disconnect(void); __END_DECLS + +#endif // TRUSTY_KEYMASTER_TRUSTY_KEYMASTER_IPC_H_ diff --git a/trusty/keymaster/trusty_keymaster_main.cpp b/trusty/keymaster/trusty_keymaster_main.cpp index 7ed880e6d..9c2ae2d0a 100644 --- a/trusty/keymaster/trusty_keymaster_main.cpp +++ b/trusty/keymaster/trusty_keymaster_main.cpp @@ -14,7 +14,10 @@ * limitations under the License. */ +#include + #include +#include #include #include @@ -102,6 +105,28 @@ unsigned char ec_privkey_pk8_der[] = { 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); } }; @@ -110,41 +135,70 @@ 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, ¶m_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"); - uint8_t* key; - size_t size; - int error = device->import_keypair(rsa_privkey_pk8_der, rsa_privkey_pk8_der_len, &key, &size); + 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 key pair: %d\n\n", error); + printf("Error importing RSA key: %d\n\n", error); return false; } - UniquePtr key_deleter(key); + std::unique_ptr key_deleter(key.key_material); printf("=== Signing with imported RSA key ===\n"); - keymaster_rsa_sign_params_t sign_params = {DIGEST_NONE, PADDING_NONE}; size_t message_len = 1024 / 8; - UniquePtr message(new uint8_t[message_len]); + std::unique_ptr message(new uint8_t[message_len]); memset(message.get(), 'a', message_len); - uint8_t* signature; - size_t signature_len; - error = device->sign_data(&sign_params, key, size, message.get(), message_len, &signature, - &signature_len); - if (error != KM_ERROR_OK) { - printf("Error signing data with imported RSA key: %d\n\n", error); + 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; } - UniquePtr signature_deleter(signature); + std::unique_ptr signature_deleter(signature.data); printf("=== Verifying with imported RSA key === \n"); - error = device->verify_data(&sign_params, key, size, message.get(), message_len, signature, - signature_len); - if (error != KM_ERROR_OK) { - printf("Error verifying data with imported RSA key: %d\n\n", error); + if (!do_operation(device, KM_PURPOSE_VERIFY, &key, &input, &signature, nullptr)) { + printf("Error verifying data with imported RSA key\n\n"); return false; } @@ -158,67 +212,58 @@ static bool test_rsa(TrustyKeymasterDevice* device) { printf("============\n\n"); printf("=== Generating RSA key pair ===\n"); - keymaster_rsa_keygen_params_t params; - params.public_exponent = 65537; - params.modulus_size = 2048; - - uint8_t* key; - size_t size; - int error = device->generate_keypair(TYPE_RSA, ¶ms, &key, &size); + 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; } - UniquePtr deleter(key); + std::unique_ptr key_deleter(key.key_material); printf("=== Signing with RSA key === \n"); - keymaster_rsa_sign_params_t sign_params = {DIGEST_NONE, PADDING_NONE}; - size_t message_len = params.modulus_size / 8; - UniquePtr message(new uint8_t[message_len]); + size_t message_len = 1024 / 8; + std::unique_ptr message(new uint8_t[message_len]); memset(message.get(), 'a', message_len); - uint8_t* signature; - size_t signature_len; - error = device->sign_data(&sign_params, key, size, message.get(), message_len, &signature, - &signature_len); - if (error != KM_ERROR_OK) { - printf("Error signing data with RSA key: %d\n\n", error); + 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; } - UniquePtr signature_deleter(signature); + std::unique_ptr signature_deleter(signature.data); printf("=== Verifying with RSA key === \n"); - error = device->verify_data(&sign_params, key, size, message.get(), message_len, signature, - signature_len); - if (error != KM_ERROR_OK) { - printf("Error verifying data with RSA key: %d\n\n", error); + 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"); - uint8_t* exported_key; - size_t exported_size; - error = device->get_keypair_public(key, size, &exported_key, &exported_size); + 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; - UniquePtr pkey(d2i_PUBKEY(NULL, &tmp, exported_size)); - UniquePtr ctx(EVP_PKEY_CTX_new(pkey.get(), NULL)); + const uint8_t* tmp = exported_key.data; + std::unique_ptr pkey( + d2i_PUBKEY(NULL, &tmp, exported_key.data_length)); + std::unique_ptr ctx(EVP_PKEY_CTX_new(pkey.get(), NULL)); if (EVP_PKEY_verify_init(ctx.get()) != 1) { - printf("Error initializing openss EVP context\n"); + 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"); + 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, signature_len, message.get(), message_len) != 1) { - printf("Verification with exported pubkey failed.\n"); + 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"); @@ -234,35 +279,31 @@ static bool test_import_ecdsa(TrustyKeymasterDevice* device) { printf("=====================\n\n"); printf("=== Importing ECDSA keypair === \n"); - uint8_t* key; - size_t size; - int error = device->import_keypair(ec_privkey_pk8_der, ec_privkey_pk8_der_len, &key, &size); + 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 key pair: %d\n\n", error); + printf("Error importing ECDSA key: %d\n\n", error); return false; } - UniquePtr deleter(key); + std::unique_ptr deleter(key.key_material); printf("=== Signing with imported ECDSA key ===\n"); keymaster_ec_sign_params_t sign_params = {DIGEST_NONE}; size_t message_len = 30 /* arbitrary */; - UniquePtr message(new uint8_t[message_len]); + std::unique_ptr message(new uint8_t[message_len]); memset(message.get(), 'a', message_len); - uint8_t* signature; - size_t signature_len; - error = device->sign_data(&sign_params, key, size, message.get(), message_len, &signature, - &signature_len); - if (error != KM_ERROR_OK) { - printf("Error signing data with imported ECDSA key: %d\n\n", error); + 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; } - UniquePtr signature_deleter(signature); + std::unique_ptr signature_deleter(signature.data); printf("=== Verifying with imported ECDSA key === \n"); - error = device->verify_data(&sign_params, key, size, message.get(), message_len, signature, - signature_len); - if (error != KM_ERROR_OK) { - printf("Error verifying data with imported ECDSA key: %d\n\n", error); + if (!do_operation(device, KM_PURPOSE_VERIFY, &key, &input, &signature, nullptr)) { + printf("Error verifying data with imported ECDSA key\n\n"); return false; } @@ -276,64 +317,57 @@ static bool test_ecdsa(TrustyKeymasterDevice* device) { printf("==============\n\n"); printf("=== Generating ECDSA key pair ===\n"); - keymaster_ec_keygen_params_t params; - params.field_size = 521; - uint8_t* key; - size_t size; - int error = device->generate_keypair(TYPE_EC, ¶ms, &key, &size); - if (error != 0) { + 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; } - UniquePtr deleter(key); + std::unique_ptr key_deleter(key.key_material); printf("=== Signing with ECDSA key === \n"); - keymaster_ec_sign_params_t sign_params = {DIGEST_NONE}; size_t message_len = 30 /* arbitrary */; - UniquePtr message(new uint8_t[message_len]); + std::unique_ptr message(new uint8_t[message_len]); memset(message.get(), 'a', message_len); - uint8_t* signature; - size_t signature_len; - error = device->sign_data(&sign_params, key, size, message.get(), message_len, &signature, - &signature_len); - if (error != KM_ERROR_OK) { - printf("Error signing data with ECDSA key: %d\n\n", error); + 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; } - UniquePtr signature_deleter(signature); + std::unique_ptr signature_deleter(signature.data); printf("=== Verifying with ECDSA key === \n"); - error = device->verify_data(&sign_params, key, size, message.get(), message_len, signature, - signature_len); - if (error != KM_ERROR_OK) { - printf("Error verifying data with ECDSA key: %d\n\n", error); + 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"); - uint8_t* exported_key; - size_t exported_size; - error = device->get_keypair_public(key, size, &exported_key, &exported_size); + 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; - UniquePtr pkey(d2i_PUBKEY(NULL, &tmp, exported_size)); - UniquePtr ctx(EVP_PKEY_CTX_new(pkey.get(), NULL)); + const uint8_t* tmp = exported_key.data; + std::unique_ptr pkey( + d2i_PUBKEY(NULL, &tmp, exported_key.data_length)); + std::unique_ptr ctx(EVP_PKEY_CTX_new(pkey.get(), NULL)); if (EVP_PKEY_verify_init(ctx.get()) != 1) { - printf("Error initializing openss EVP context\n"); + 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"); + printf("Exported key was the wrong type?!?\n\n"); return false; } - if (EVP_PKEY_verify(ctx.get(), signature, signature_len, message.get(), message_len) != 1) { - printf("Verification with exported pubkey failed.\n"); + 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"); @@ -344,8 +378,8 @@ static bool test_ecdsa(TrustyKeymasterDevice* device) { } int main(void) { - TrustyKeymasterDevice device(NULL); + keymaster::ConfigureDevice(reinterpret_cast(&device)); if (device.session_error() != KM_ERROR_OK) { printf("Failed to initialize Trusty session: %d\n", device.session_error()); return 1;