From 8e10baee45a1bfab4094869159b8ede270b6d416 Mon Sep 17 00:00:00 2001 From: Keun Soo Yim Date: Wed, 29 Mar 2017 20:18:52 +0000 Subject: [PATCH] Revert "Add keymaster VTS tests." This reverts commit dda22ea8845f6906d4bccc13bf142d96a43976c5. Change-Id: Ie6a60e17ed5258840eba3d3f6b8092636160b2c2 --- keymaster/3.0/default/KeymasterDevice.cpp | 19 +- keymaster/3.0/vts/functional/Android.mk | 37 - .../3.0/vts/functional/attestation_record.cpp | 289 -- keymaster/3.0/vts/functional/attestation_record.h | 57 - keymaster/3.0/vts/functional/authorization_set.cpp | 422 --- keymaster/3.0/vts/functional/authorization_set.h | 420 --- keymaster/3.0/vts/functional/key_param_output.cpp | 131 - keymaster/3.0/vts/functional/key_param_output.h | 50 - .../3.0/vts/functional/keymaster_hidl_hal_test.cpp | 3909 -------------------- keymaster/3.0/vts/functional/keymaster_tags.h | 450 --- .../3.0/vts/functional/keystore_tags_utils.cpp | 50 - keymaster/3.0/vts/functional/openssl_utils.h | 52 - 12 files changed, 6 insertions(+), 5880 deletions(-) delete mode 100644 keymaster/3.0/vts/functional/Android.mk delete mode 100644 keymaster/3.0/vts/functional/attestation_record.cpp delete mode 100644 keymaster/3.0/vts/functional/attestation_record.h delete mode 100644 keymaster/3.0/vts/functional/authorization_set.cpp delete mode 100644 keymaster/3.0/vts/functional/authorization_set.h delete mode 100644 keymaster/3.0/vts/functional/key_param_output.cpp delete mode 100644 keymaster/3.0/vts/functional/key_param_output.h delete mode 100644 keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp delete mode 100644 keymaster/3.0/vts/functional/keymaster_tags.h delete mode 100644 keymaster/3.0/vts/functional/keystore_tags_utils.cpp delete mode 100644 keymaster/3.0/vts/functional/openssl_utils.h diff --git a/keymaster/3.0/default/KeymasterDevice.cpp b/keymaster/3.0/default/KeymasterDevice.cpp index 6b4524b4..720b9460 100644 --- a/keymaster/3.0/default/KeymasterDevice.cpp +++ b/keymaster/3.0/default/KeymasterDevice.cpp @@ -698,21 +698,14 @@ Return KeymasterDevice::abort(uint64_t operationHandle) { return legacy_enum_conversion(keymaster_device_->abort(keymaster_device_, operationHandle)); } -IKeymasterDevice* HIDL_FETCH_IKeymasterDevice(const char* name) { +IKeymasterDevice* HIDL_FETCH_IKeymasterDevice(const char* /* name */) { keymaster2_device_t* dev = nullptr; - ALOGI("Fetching keymaster device name %s", name); - - uint32_t version = -1; - bool supports_ec = false; - bool supports_all_digests = false; - - if (name && strcmp(name, "softwareonly") == 0) { - dev = (new SoftKeymasterDevice(new SoftwareOnlyHidlKeymasterContext))->keymaster2_device(); - } else if (name && strcmp(name, "default") == 0) { - auto rc = keymaster_device_initialize(&dev, &version, &supports_ec, &supports_all_digests); - if (rc) return nullptr; - } + uint32_t version; + bool supports_ec; + bool supports_all_digests; + auto rc = keymaster_device_initialize(&dev, &version, &supports_ec, &supports_all_digests); + if (rc) return nullptr; auto kmrc = ::keymaster::ConfigureDevice(dev); if (kmrc != KM_ERROR_OK) { diff --git a/keymaster/3.0/vts/functional/Android.mk b/keymaster/3.0/vts/functional/Android.mk deleted file mode 100644 index 1b29cde2..00000000 --- a/keymaster/3.0/vts/functional/Android.mk +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (C) 2017 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. - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := keymaster_hidl_hal_test -LOCAL_SRC_FILES := \ - authorization_set.cpp \ - attestation_record.cpp \ - key_param_output.cpp \ - keymaster_hidl_hal_test.cpp \ - keystore_tags_utils.cpp \ - -LOCAL_SHARED_LIBRARIES := \ - android.hardware.keymaster@3.0 \ - libcrypto \ - libhidlbase \ - liblog \ - libsoftkeymasterdevice \ - libutils \ - -LOCAL_STATIC_LIBRARIES := \ - VtsHalHidlTargetTestBase \ - -include $(BUILD_NATIVE_TEST) diff --git a/keymaster/3.0/vts/functional/attestation_record.cpp b/keymaster/3.0/vts/functional/attestation_record.cpp deleted file mode 100644 index 6cdd44c0..00000000 --- a/keymaster/3.0/vts/functional/attestation_record.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright 2016 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 "attestation_record.h" - -#include - -#include -#include -#include -#include - -#include "openssl_utils.h" - -namespace android { -namespace hardware { -namespace keymaster { -namespace V3_0 { - -struct stack_st_ASN1_TYPE_Delete { - void operator()(stack_st_ASN1_TYPE* p) { sk_ASN1_TYPE_free(p); } -}; - -struct ASN1_STRING_Delete { - void operator()(ASN1_STRING* p) { ASN1_STRING_free(p); } -}; - -struct ASN1_TYPE_Delete { - void operator()(ASN1_TYPE* p) { ASN1_TYPE_free(p); } -}; - -#define ASN1_INTEGER_SET STACK_OF(ASN1_INTEGER) - -typedef struct km_root_of_trust { - ASN1_OCTET_STRING* verified_boot_key; - ASN1_BOOLEAN* device_locked; - ASN1_ENUMERATED* verified_boot_state; -} KM_ROOT_OF_TRUST; - -ASN1_SEQUENCE(KM_ROOT_OF_TRUST) = { - ASN1_SIMPLE(KM_ROOT_OF_TRUST, verified_boot_key, ASN1_OCTET_STRING), - ASN1_SIMPLE(KM_ROOT_OF_TRUST, device_locked, ASN1_BOOLEAN), - ASN1_SIMPLE(KM_ROOT_OF_TRUST, verified_boot_state, ASN1_ENUMERATED), -} ASN1_SEQUENCE_END(KM_ROOT_OF_TRUST); -IMPLEMENT_ASN1_FUNCTIONS(KM_ROOT_OF_TRUST); - -typedef struct km_auth_list { - ASN1_INTEGER_SET* purpose; - ASN1_INTEGER* algorithm; - ASN1_INTEGER* key_size; - ASN1_INTEGER_SET* digest; - ASN1_INTEGER_SET* padding; - ASN1_INTEGER_SET* kdf; - ASN1_INTEGER* ec_curve; - ASN1_INTEGER* rsa_public_exponent; - ASN1_INTEGER* active_date_time; - ASN1_INTEGER* origination_expire_date_time; - ASN1_INTEGER* usage_expire_date_time; - ASN1_NULL* no_auth_required; - ASN1_INTEGER* user_auth_type; - ASN1_INTEGER* auth_timeout; - ASN1_NULL* allow_while_on_body; - ASN1_NULL* all_applications; - ASN1_OCTET_STRING* application_id; - ASN1_INTEGER* creation_date_time; - ASN1_INTEGER* origin; - ASN1_NULL* rollback_resistant; - KM_ROOT_OF_TRUST* root_of_trust; - ASN1_INTEGER* os_version; - ASN1_INTEGER* os_patchlevel; - ASN1_OCTET_STRING* attestation_application_id; -} KM_AUTH_LIST; - -ASN1_SEQUENCE(KM_AUTH_LIST) = { - ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, purpose, ASN1_INTEGER, TAG_PURPOSE.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, algorithm, ASN1_INTEGER, TAG_ALGORITHM.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, key_size, ASN1_INTEGER, TAG_KEY_SIZE.maskedTag()), - ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, digest, ASN1_INTEGER, TAG_DIGEST.maskedTag()), - ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, padding, ASN1_INTEGER, TAG_PADDING.maskedTag()), - ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, kdf, ASN1_INTEGER, TAG_KDF.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, ec_curve, ASN1_INTEGER, TAG_EC_CURVE.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, rsa_public_exponent, ASN1_INTEGER, - TAG_RSA_PUBLIC_EXPONENT.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, active_date_time, ASN1_INTEGER, TAG_ACTIVE_DATETIME.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, origination_expire_date_time, ASN1_INTEGER, - TAG_ORIGINATION_EXPIRE_DATETIME.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, usage_expire_date_time, ASN1_INTEGER, - TAG_USAGE_EXPIRE_DATETIME.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, no_auth_required, ASN1_NULL, TAG_NO_AUTH_REQUIRED.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, user_auth_type, ASN1_INTEGER, TAG_USER_AUTH_TYPE.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, auth_timeout, ASN1_INTEGER, TAG_AUTH_TIMEOUT.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, allow_while_on_body, ASN1_NULL, TAG_ALLOW_WHILE_ON_BODY.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, all_applications, ASN1_NULL, TAG_ALL_APPLICATIONS.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, application_id, ASN1_OCTET_STRING, TAG_APPLICATION_ID.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, creation_date_time, ASN1_INTEGER, TAG_CREATION_DATETIME.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, origin, ASN1_INTEGER, TAG_ORIGIN.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, rollback_resistant, ASN1_NULL, TAG_ROLLBACK_RESISTANT.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, root_of_trust, KM_ROOT_OF_TRUST, TAG_ROOT_OF_TRUST.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, os_version, ASN1_INTEGER, TAG_OS_VERSION.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, os_patchlevel, ASN1_INTEGER, TAG_OS_PATCHLEVEL.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, attestation_application_id, ASN1_OCTET_STRING, - TAG_ATTESTATION_APPLICATION_ID.maskedTag()), -} ASN1_SEQUENCE_END(KM_AUTH_LIST); -IMPLEMENT_ASN1_FUNCTIONS(KM_AUTH_LIST); - -typedef struct km_key_description { - ASN1_INTEGER* attestation_version; - ASN1_ENUMERATED* attestation_security_level; - ASN1_INTEGER* keymaster_version; - ASN1_ENUMERATED* keymaster_security_level; - ASN1_OCTET_STRING* attestation_challenge; - KM_AUTH_LIST* software_enforced; - KM_AUTH_LIST* tee_enforced; - ASN1_INTEGER* unique_id; -} KM_KEY_DESCRIPTION; - -ASN1_SEQUENCE(KM_KEY_DESCRIPTION) = { - ASN1_SIMPLE(KM_KEY_DESCRIPTION, attestation_version, ASN1_INTEGER), - ASN1_SIMPLE(KM_KEY_DESCRIPTION, attestation_security_level, ASN1_ENUMERATED), - ASN1_SIMPLE(KM_KEY_DESCRIPTION, keymaster_version, ASN1_INTEGER), - ASN1_SIMPLE(KM_KEY_DESCRIPTION, keymaster_security_level, ASN1_ENUMERATED), - ASN1_SIMPLE(KM_KEY_DESCRIPTION, attestation_challenge, ASN1_OCTET_STRING), - ASN1_SIMPLE(KM_KEY_DESCRIPTION, unique_id, ASN1_OCTET_STRING), - ASN1_SIMPLE(KM_KEY_DESCRIPTION, software_enforced, KM_AUTH_LIST), - ASN1_SIMPLE(KM_KEY_DESCRIPTION, tee_enforced, KM_AUTH_LIST), -} ASN1_SEQUENCE_END(KM_KEY_DESCRIPTION); -IMPLEMENT_ASN1_FUNCTIONS(KM_KEY_DESCRIPTION); - -template -void copyAuthTag(const stack_st_ASN1_INTEGER* stack, TypedTag ttag, - AuthorizationSet* auth_list) { - typedef typename TypedTag2ValueType::type ValueT; - for (size_t i = 0; i < sk_ASN1_INTEGER_num(stack); ++i) { - auth_list->push_back( - ttag, static_cast(ASN1_INTEGER_get(sk_ASN1_INTEGER_value(stack, i)))); - } -} - -template -void copyAuthTag(const ASN1_INTEGER* asn1_int, TypedTag ttag, - AuthorizationSet* auth_list) { - typedef typename TypedTag2ValueType::type ValueT; - if (!asn1_int) return; - auth_list->push_back(ttag, static_cast(ASN1_INTEGER_get(asn1_int))); -} - -template -void copyAuthTag(const ASN1_INTEGER* asn1_int, TypedTag ttag, - AuthorizationSet* auth_list) { - if (!asn1_int) return; - auth_list->push_back(ttag, ASN1_INTEGER_get(asn1_int)); -} - -BIGNUM* construct_uint_max() { - BIGNUM* value = BN_new(); - BIGNUM_Ptr one(BN_new()); - BN_one(one.get()); - BN_lshift(value, one.get(), 32); - return value; -} - -uint64_t BignumToUint64(BIGNUM* num) { - static_assert((sizeof(BN_ULONG) == sizeof(uint32_t)) || (sizeof(BN_ULONG) == sizeof(uint64_t)), - "This implementation only supports 32 and 64-bit BN_ULONG"); - if (sizeof(BN_ULONG) == sizeof(uint32_t)) { - BIGNUM_Ptr uint_max(construct_uint_max()); - BIGNUM_Ptr hi(BN_new()), lo(BN_new()); - BN_CTX_Ptr ctx(BN_CTX_new()); - BN_div(hi.get(), lo.get(), num, uint_max.get(), ctx.get()); - return static_cast(BN_get_word(hi.get())) << 32 | BN_get_word(lo.get()); - } else if (sizeof(BN_ULONG) == sizeof(uint64_t)) { - return BN_get_word(num); - } else { - return 0; - } -} - -template -void copyAuthTag(const ASN1_INTEGER* asn1_int, TypedTag ttag, - AuthorizationSet* auth_list) { - if (!asn1_int) return; - BIGNUM_Ptr num(ASN1_INTEGER_to_BN(asn1_int, nullptr)); - auth_list->push_back(ttag, BignumToUint64(num.get())); -} - -template -void copyAuthTag(const ASN1_INTEGER* asn1_int, TypedTag ttag, - AuthorizationSet* auth_list) { - if (!asn1_int) return; - BIGNUM_Ptr num(ASN1_INTEGER_to_BN(asn1_int, nullptr)); - auth_list->push_back(ttag, BignumToUint64(num.get())); -} - -template -void copyAuthTag(const ASN1_NULL* asn1_null, TypedTag ttag, - AuthorizationSet* auth_list) { - if (!asn1_null) return; - auth_list->push_back(ttag); -} - -template -void copyAuthTag(const ASN1_OCTET_STRING* asn1_string, TypedTag ttag, - AuthorizationSet* auth_list) { - if (!asn1_string) return; - hidl_vec buf; - buf.setToExternal(asn1_string->data, asn1_string->length); - auth_list->push_back(ttag, buf); -} - -// Extract the values from the specified ASN.1 record and place them in auth_list. -static ErrorCode extract_auth_list(const KM_AUTH_LIST* record, AuthorizationSet* auth_list) { - if (!record) return ErrorCode::OK; - - copyAuthTag(record->active_date_time, TAG_ACTIVE_DATETIME, auth_list); - copyAuthTag(record->algorithm, TAG_ALGORITHM, auth_list); - copyAuthTag(record->all_applications, TAG_ALL_APPLICATIONS, auth_list); - copyAuthTag(record->application_id, TAG_APPLICATION_ID, auth_list); - copyAuthTag(record->auth_timeout, TAG_AUTH_TIMEOUT, auth_list); - copyAuthTag(record->creation_date_time, TAG_CREATION_DATETIME, auth_list); - copyAuthTag(record->digest, TAG_DIGEST, auth_list); - copyAuthTag(record->ec_curve, TAG_EC_CURVE, auth_list); - copyAuthTag(record->key_size, TAG_KEY_SIZE, auth_list); - copyAuthTag(record->no_auth_required, TAG_NO_AUTH_REQUIRED, auth_list); - copyAuthTag(record->origin, TAG_ORIGIN, auth_list); - copyAuthTag(record->origination_expire_date_time, TAG_ORIGINATION_EXPIRE_DATETIME, auth_list); - copyAuthTag(record->os_patchlevel, TAG_OS_PATCHLEVEL, auth_list); - copyAuthTag(record->os_version, TAG_OS_VERSION, auth_list); - copyAuthTag(record->padding, TAG_PADDING, auth_list); - copyAuthTag(record->purpose, TAG_PURPOSE, auth_list); - copyAuthTag(record->rollback_resistant, TAG_ROLLBACK_RESISTANT, auth_list); - copyAuthTag(record->rsa_public_exponent, TAG_RSA_PUBLIC_EXPONENT, auth_list); - copyAuthTag(record->usage_expire_date_time, TAG_USAGE_EXPIRE_DATETIME, auth_list); - copyAuthTag(record->user_auth_type, TAG_USER_AUTH_TYPE, auth_list); - - return ErrorCode::OK; -} - -MAKE_OPENSSL_PTR_TYPE(KM_KEY_DESCRIPTION) - -// Parse the DER-encoded attestation record, placing the results in keymaster_version, -// attestation_challenge, software_enforced, tee_enforced and unique_id. -ErrorCode parse_attestation_record(const uint8_t* asn1_key_desc, size_t asn1_key_desc_len, - uint32_t* attestation_version, // - SecurityLevel* attestation_security_level, - uint32_t* keymaster_version, - SecurityLevel* keymaster_security_level, - hidl_vec* attestation_challenge, - AuthorizationSet* software_enforced, - AuthorizationSet* tee_enforced, // - hidl_vec* unique_id) { - const uint8_t* p = asn1_key_desc; - KM_KEY_DESCRIPTION_Ptr record(d2i_KM_KEY_DESCRIPTION(nullptr, &p, asn1_key_desc_len)); - if (!record.get()) return ErrorCode::UNKNOWN_ERROR; - - *attestation_version = ASN1_INTEGER_get(record->attestation_version); - *attestation_security_level = - static_cast(ASN1_ENUMERATED_get(record->attestation_security_level)); - *keymaster_version = ASN1_INTEGER_get(record->keymaster_version); - *keymaster_security_level = - static_cast(ASN1_ENUMERATED_get(record->keymaster_security_level)); - - attestation_challenge->setToExternal(record->attestation_challenge->data, - record->attestation_challenge->length); - - unique_id->setToExternal(record->unique_id->data, record->unique_id->length); - - ErrorCode error = extract_auth_list(record->software_enforced, software_enforced); - if (error != ErrorCode::OK) return error; - - return extract_auth_list(record->tee_enforced, tee_enforced); -} - -} // namespace V3_0 -} // namespace keymaster -} // namespace hardware -} // namespace android diff --git a/keymaster/3.0/vts/functional/attestation_record.h b/keymaster/3.0/vts/functional/attestation_record.h deleted file mode 100644 index a042055d..00000000 --- a/keymaster/3.0/vts/functional/attestation_record.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef HARDWARE_INTERFACES_KEYMASTER_30_VTS_FUNCTIONAL_ATTESTATION_RECORD_H_ -#define HARDWARE_INTERFACES_KEYMASTER_30_VTS_FUNCTIONAL_ATTESTATION_RECORD_H_ - -#include "authorization_set.h" - -namespace android { -namespace hardware { -namespace keymaster { -namespace V3_0 { - -/** - * The OID for Android attestation records. For the curious, it breaks down as follows: - * - * 1 = ISO - * 3 = org - * 6 = DoD (Huh? OIDs are weird.) - * 1 = IANA - * 4 = Private - * 1 = Enterprises - * 11129 = Google - * 2 = Google security - * 1 = certificate extension - * 17 = Android attestation extension. - */ -static const char kAttestionRecordOid[] = "1.3.6.1.4.1.11129.2.1.17"; - -ErrorCode parse_attestation_record(const uint8_t* asn1_key_desc, size_t asn1_key_desc_len, - uint32_t* attestation_version, // - SecurityLevel* attestation_security_level, - uint32_t* keymaster_version, - SecurityLevel* keymaster_security_level, - hidl_vec* attestation_challenge, - AuthorizationSet* software_enforced, - AuthorizationSet* tee_enforced, // - hidl_vec* unique_id); -} // namespace V3_0 -} // namespace keymaster -} // namespace hardware -} // namespace android - -#endif // HARDWARE_INTERFACES_KEYMASTER_30_VTS_FUNCTIONAL_ATTESTATION_RECORD_H_ diff --git a/keymaster/3.0/vts/functional/authorization_set.cpp b/keymaster/3.0/vts/functional/authorization_set.cpp deleted file mode 100644 index 303f7e7c..00000000 --- a/keymaster/3.0/vts/functional/authorization_set.cpp +++ /dev/null @@ -1,422 +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 "authorization_set.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace android { -namespace hardware { -namespace keymaster { -namespace V3_0 { - -inline bool keyParamLess(const KeyParameter& a, const KeyParameter& b) { - if (a.tag != b.tag) return a.tag < b.tag; - int retval; - switch (typeFromTag(a.tag)) { - case TagType::INVALID: - case TagType::BOOL: - return false; - case TagType::ENUM: - case TagType::ENUM_REP: - case TagType::UINT: - case TagType::UINT_REP: - return a.f.integer < b.f.integer; - case TagType::ULONG: - case TagType::ULONG_REP: - return a.f.longInteger < b.f.longInteger; - case TagType::DATE: - return a.f.dateTime < b.f.dateTime; - case TagType::BIGNUM: - case TagType::BYTES: - // Handle the empty cases. - if (a.blob.size() == 0) return b.blob.size() != 0; - if (b.blob.size() == 0) return false; - - retval = memcmp(&a.blob[0], &b.blob[0], std::min(a.blob.size(), b.blob.size())); - if (retval == 0) { - // One is the prefix of the other, so the longer wins - return a.blob.size() < b.blob.size(); - } else { - return retval < 0; - } - } - return false; -} - -inline bool keyParamEqual(const KeyParameter& a, const KeyParameter& b) { - if (a.tag != b.tag) return false; - - switch (typeFromTag(a.tag)) { - case TagType::INVALID: - case TagType::BOOL: - return true; - case TagType::ENUM: - case TagType::ENUM_REP: - case TagType::UINT: - case TagType::UINT_REP: - return a.f.integer == b.f.integer; - case TagType::ULONG: - case TagType::ULONG_REP: - return a.f.longInteger == b.f.longInteger; - case TagType::DATE: - return a.f.dateTime == b.f.dateTime; - case TagType::BIGNUM: - case TagType::BYTES: - if (a.blob.size() != b.blob.size()) return false; - return a.blob.size() == 0 || memcmp(&a.blob[0], &b.blob[0], a.blob.size()) == 0; - } - return false; -} - -void AuthorizationSet::Sort() { - std::sort(data_.begin(), data_.end(), keyParamLess); -} - -void AuthorizationSet::Deduplicate() { - if (data_.empty()) return; - - Sort(); - std::vector result; - - auto curr = data_.begin(); - auto prev = curr++; - for (; curr != data_.end(); ++prev, ++curr) { - if (prev->tag == Tag::INVALID) continue; - - if (!keyParamEqual(*prev, *curr)) { - result.emplace_back(std::move(*prev)); - } - } - result.emplace_back(std::move(*prev)); - - std::swap(data_, result); -} - -void AuthorizationSet::Union(const AuthorizationSet& other) { - data_.insert(data_.end(), other.data_.begin(), other.data_.end()); - Deduplicate(); -} - -void AuthorizationSet::Subtract(const AuthorizationSet& other) { - Deduplicate(); - - auto i = other.begin(); - while (i != other.end()) { - int pos = -1; - do { - pos = find(i->tag, pos); - if (pos != -1 && keyParamEqual(*i, data_[pos])) { - data_.erase(data_.begin() + pos); - break; - } - } while (pos != -1); - ++i; - } -} - -int AuthorizationSet::find(Tag tag, int begin) const { - auto iter = data_.begin() + (1 + begin); - - while (iter != data_.end() && iter->tag != tag) - ++iter; - - if (iter != data_.end()) return iter - data_.begin(); - return -1; -} - -bool AuthorizationSet::erase(int index) { - auto pos = data_.begin() + index; - if (pos != data_.end()) { - data_.erase(pos); - return true; - } - return false; -} - -KeyParameter& AuthorizationSet::operator[](int at) { - return data_[at]; -} - -const KeyParameter& AuthorizationSet::operator[](int at) const { - return data_[at]; -} - -void AuthorizationSet::Clear() { - data_.clear(); -} - -size_t AuthorizationSet::GetTagCount(Tag tag) const { - size_t count = 0; - for (int pos = -1; (pos = find(tag, pos)) != -1;) - ++count; - return count; -} - -NullOr AuthorizationSet::GetEntry(Tag tag) const { - int pos = find(tag); - if (pos == -1) return {}; - return data_[pos]; -} - -/** - * Persistent format is: - * | 32 bit indirect_size | - * -------------------------------- - * | indirect_size bytes of data | this is where the blob data is stored - * -------------------------------- - * | 32 bit element_count | number of entries - * | 32 bit elements_size | total bytes used by entries (entries have variable length) - * -------------------------------- - * | elementes_size bytes of data | where the elements are stored - */ - -/** - * Persistent format of blobs and bignums: - * | 32 bit tag | - * | 32 bit blob_length | - * | 32 bit indirect_offset | - */ - -struct OutStreams { - std::ostream& indirect; - std::ostream& elements; -}; - -OutStreams& serializeParamValue(OutStreams& out, const hidl_vec& blob) { - uint32_t buffer; - - // write blob_length - auto blob_length = blob.size(); - if (blob_length > std::numeric_limits::max()) { - out.elements.setstate(std::ios_base::badbit); - return out; - } - buffer = blob_length; - out.elements.write(reinterpret_cast(&buffer), sizeof(uint32_t)); - - // write indirect_offset - auto offset = out.indirect.tellp(); - if (offset < 0 || offset > std::numeric_limits::max() || - static_cast((std::numeric_limits::max() - offset)) < - blob_length) { // overflow check - out.elements.setstate(std::ios_base::badbit); - return out; - } - buffer = offset; - out.elements.write(reinterpret_cast(&buffer), sizeof(uint32_t)); - - // write blob to indirect stream - if (blob_length) out.indirect.write(reinterpret_cast(&blob[0]), blob_length); - - return out; -} - -template OutStreams& serializeParamValue(OutStreams& out, const T& value) { - out.elements.write(reinterpret_cast(&value), sizeof(T)); - return out; -} - -OutStreams& serialize(TAG_INVALID_t&&, OutStreams& out, const KeyParameter&) { - // skip invalid entries. - return out; -} -template OutStreams& serialize(T ttag, OutStreams& out, const KeyParameter& param) { - out.elements.write(reinterpret_cast(¶m.tag), sizeof(int32_t)); - return serializeParamValue(out, accessTagValue(ttag, param)); -} - -template struct choose_serializer; -template struct choose_serializer> { - static OutStreams& serialize(OutStreams& out, const KeyParameter& param) { - return choose_serializer::serialize(out, param); - } -}; -template <> struct choose_serializer<> { - static OutStreams& serialize(OutStreams& out, const KeyParameter&) { return out; } -}; -template -struct choose_serializer, Tail...> { - static OutStreams& serialize(OutStreams& out, const KeyParameter& param) { - if (param.tag == tag) { - return V3_0::serialize(TypedTag(), out, param); - } else { - return choose_serializer::serialize(out, param); - } - } -}; - -OutStreams& serialize(OutStreams& out, const KeyParameter& param) { - return choose_serializer::serialize(out, param); -} - -std::ostream& serialize(std::ostream& out, const std::vector& params) { - std::stringstream indirect; - std::stringstream elements; - OutStreams streams = {indirect, elements}; - for (const auto& param : params) { - serialize(streams, param); - } - if (indirect.bad() || elements.bad()) { - out.setstate(std::ios_base::badbit); - return out; - } - auto pos = indirect.tellp(); - if (pos < 0 || pos > std::numeric_limits::max()) { - out.setstate(std::ios_base::badbit); - return out; - } - uint32_t indirect_size = pos; - pos = elements.tellp(); - if (pos < 0 || pos > std::numeric_limits::max()) { - out.setstate(std::ios_base::badbit); - return out; - } - uint32_t elements_size = pos; - uint32_t element_count = params.size(); - - out.write(reinterpret_cast(&indirect_size), sizeof(uint32_t)); - - pos = out.tellp(); - if (indirect_size) out << indirect.rdbuf(); - assert(out.tellp() - pos == indirect_size); - - out.write(reinterpret_cast(&element_count), sizeof(uint32_t)); - out.write(reinterpret_cast(&elements_size), sizeof(uint32_t)); - - pos = out.tellp(); - if (elements_size) out << elements.rdbuf(); - assert(out.tellp() - pos == elements_size); - - return out; -} - -struct InStreams { - std::istream& indirect; - std::istream& elements; -}; - -InStreams& deserializeParamValue(InStreams& in, hidl_vec* blob) { - uint32_t blob_length = 0; - uint32_t offset = 0; - in.elements.read(reinterpret_cast(&blob_length), sizeof(uint32_t)); - blob->resize(blob_length); - in.elements.read(reinterpret_cast(&offset), sizeof(uint32_t)); - in.indirect.seekg(offset); - in.indirect.read(reinterpret_cast(&(*blob)[0]), blob->size()); - return in; -} - -template InStreams& deserializeParamValue(InStreams& in, T* value) { - in.elements.read(reinterpret_cast(value), sizeof(T)); - return in; -} - -InStreams& deserialize(TAG_INVALID_t&&, InStreams& in, KeyParameter*) { - // there should be no invalid KeyParamaters but if handle them as zero sized. - return in; -} - -template InStreams& deserialize(T&& ttag, InStreams& in, KeyParameter* param) { - return deserializeParamValue(in, &accessTagValue(ttag, *param)); -} - -template struct choose_deserializer; -template struct choose_deserializer> { - static InStreams& deserialize(InStreams& in, KeyParameter* param) { - return choose_deserializer::deserialize(in, param); - } -}; -template <> struct choose_deserializer<> { - static InStreams& deserialize(InStreams& in, KeyParameter*) { - // encountered an unknown tag -> fail parsing - in.elements.setstate(std::ios_base::badbit); - return in; - } -}; -template -struct choose_deserializer, Tail...> { - static InStreams& deserialize(InStreams& in, KeyParameter* param) { - if (param->tag == tag) { - return V3_0::deserialize(TypedTag(), in, param); - } else { - return choose_deserializer::deserialize(in, param); - } - } -}; - -InStreams& deserialize(InStreams& in, KeyParameter* param) { - in.elements.read(reinterpret_cast(¶m->tag), sizeof(Tag)); - return choose_deserializer::deserialize(in, param); -} - -std::istream& deserialize(std::istream& in, std::vector* params) { - uint32_t indirect_size = 0; - in.read(reinterpret_cast(&indirect_size), sizeof(uint32_t)); - std::string indirect_buffer(indirect_size, '\0'); - if (indirect_buffer.size() != indirect_size) { - in.setstate(std::ios_base::badbit); - return in; - } - in.read(&indirect_buffer[0], indirect_buffer.size()); - - uint32_t element_count = 0; - in.read(reinterpret_cast(&element_count), sizeof(uint32_t)); - uint32_t elements_size = 0; - in.read(reinterpret_cast(&elements_size), sizeof(uint32_t)); - - std::string elements_buffer(elements_size, '\0'); - if (elements_buffer.size() != elements_size) { - in.setstate(std::ios_base::badbit); - return in; - } - in.read(&elements_buffer[0], elements_buffer.size()); - - if (in.bad()) return in; - - // TODO write one-shot stream buffer to avoid copying here - std::stringstream indirect(indirect_buffer); - std::stringstream elements(elements_buffer); - InStreams streams = {indirect, elements}; - - params->resize(element_count); - - for (uint32_t i = 0; i < element_count; ++i) { - deserialize(streams, &(*params)[i]); - } - return in; -} - -void AuthorizationSet::Serialize(std::ostream* out) const { - serialize(*out, data_); -} - -void AuthorizationSet::Deserialize(std::istream* in) { - deserialize(*in, &data_); -} - -} // namespace V3_0 -} // namespace keymaster -} // namespace hardware -} // namespace android diff --git a/keymaster/3.0/vts/functional/authorization_set.h b/keymaster/3.0/vts/functional/authorization_set.h deleted file mode 100644 index 5f92d816..00000000 --- a/keymaster/3.0/vts/functional/authorization_set.h +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Copyright 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef HARDWARE_INTERFACES_KEYMASTER_30_VTS_FUNCTIONAL_AUTHORIZATION_SET_H_ -#define HARDWARE_INTERFACES_KEYMASTER_30_VTS_FUNCTIONAL_AUTHORIZATION_SET_H_ - -#include "keymaster_tags.h" - -#include -#include - -namespace android { -namespace hardware { -namespace keymaster { -namespace V3_0 { - -class AuthorizationSetBuilder; - -/** - * An ordered collection of KeyParameters. It provides memory ownership and some convenient - * functionality for sorting, deduplicating, joining, and subtracting sets of KeyParameters. - * For serialization, wrap the backing store of this structure in a hidl_vec. - */ -class AuthorizationSet { - public: - typedef KeyParameter value_type; - - /** - * Construct an empty, dynamically-allocated, growable AuthorizationSet. - */ - AuthorizationSet(){}; - - // Copy constructor. - AuthorizationSet(const AuthorizationSet& other) : data_(other.data_) {} - - // Move constructor. - AuthorizationSet(AuthorizationSet&& other) : data_(std::move(other.data_)) {} - - // Constructor from hidl_vec - AuthorizationSet(const hidl_vec& other) { *this = other; } - - // Copy assignment. - AuthorizationSet& operator=(const AuthorizationSet& other) { - data_ = other.data_; - return *this; - } - - // Move assignment. - AuthorizationSet& operator=(AuthorizationSet&& other) { - data_ = std::move(other.data_); - return *this; - } - - AuthorizationSet& operator=(const hidl_vec& other) { - if (other.size() > 0) { - data_.resize(other.size()); - for (size_t i = 0; i < data_.size(); ++i) { - /* This makes a deep copy even of embedded blobs. - * See assignment operator/copy constructor of hidl_vec.*/ - data_[i] = other[i]; - } - } - return *this; - } - - /** - * Clear existing authorization set data - */ - void Clear(); - - ~AuthorizationSet() = default; - - /** - * Returns the size of the set. - */ - size_t size() const { return data_.size(); } - - /** - * Returns true if the set is empty. - */ - bool empty() const { return size() == 0; } - - /** - * Returns the data in the set, directly. Be careful with this. - */ - const KeyParameter* data() const { return data_.data(); } - - /** - * Sorts the set - */ - void Sort(); - - /** - * Sorts the set and removes duplicates (inadvertently duplicating tags is easy to do with the - * AuthorizationSetBuilder). - */ - void Deduplicate(); - - /** - * Adds all elements from \p set that are not already present in this AuthorizationSet. As a - * side-effect, if \p set is not null this AuthorizationSet will end up sorted. - */ - void Union(const AuthorizationSet& set); - - /** - * Removes all elements in \p set from this AuthorizationSet. - */ - void Subtract(const AuthorizationSet& set); - - /** - * Returns the offset of the next entry that matches \p tag, starting from the element after \p - * begin. If not found, returns -1. - */ - int find(Tag tag, int begin = -1) const; - - /** - * Removes the entry at the specified index. Returns true if successful, false if the index was - * out of bounds. - */ - bool erase(int index); - - /** - * Returns iterator (pointer) to beginning of elems array, to enable STL-style iteration - */ - std::vector::const_iterator begin() const { return data_.begin(); } - - /** - * Returns iterator (pointer) one past end of elems array, to enable STL-style iteration - */ - std::vector::const_iterator end() const { return data_.end(); } - - /** - * Returns the nth element of the set. - * Like for std::vector::operator[] there is no range check performed. Use of out of range - * indices is undefined. - */ - KeyParameter& operator[](int n); - - /** - * Returns the nth element of the set. - * Like for std::vector::operator[] there is no range check performed. Use of out of range - * indices is undefined. - */ - const KeyParameter& operator[](int n) const; - - /** - * Returns true if the set contains at least one instance of \p tag - */ - bool Contains(Tag tag) const { return find(tag) != -1; } - - template bool Contains(T tag) const { return find(tag) != -1; } - - template - bool Contains(TypedTag ttag, const ValueT& value) const { - for (const auto& param : data_) { - auto entry = authorizationValue(ttag, param); - if (entry.isOk() && static_cast(entry.value()) == value) return true; - } - return false; - } - /** - * Returns the number of \p tag entries. - */ - size_t GetTagCount(Tag tag) const; - - template - inline NullOr::type&> GetTagValue(T tag) const { - auto entry = GetEntry(tag); - if (entry.isOk()) return authorizationValue(tag, entry.value()); - return {}; - } - - void push_back(const KeyParameter& param) { data_.push_back(param); } - void push_back(KeyParameter&& param) { data_.push_back(std::move(param)); } - - void push_back(const AuthorizationSet& set) { - for (auto& entry : set) { - push_back(entry); - } - } - - void push_back(AuthorizationSet&& set) { - move(set.begin(), set.end()); - set.Clear(); - } - - template - void push_back(TypedTag ttag, const uint8_t* data, size_t data_length) { - hidl_vec new_blob; - new_blob.setToExternal(const_cast(data), data_length); - push_back(ttag, std::move(new_blob)); - } - - /** - * Append the tag and enumerated value to the set. - * "val" may be exactly one parameter unless a boolean parameter is added. - * In this case "val" is omitted. This condition is checked at compile time by Authorization() - */ - template void push_back(TypedTagT tag, Value&&... val) { - push_back(Authorization(tag, std::forward(val)...)); - } - - template void push_back(Iterator begin, Iterator end) { - while (begin != end) { - push_back(*begin); - ++begin; - } - } - - template void move(Iterator begin, Iterator end) { - std::move(begin, end, std::back_inserter(data_)); - } - - hidl_vec hidl_data() const { - hidl_vec result; - result.setToExternal(const_cast(data()), size()); - return result; - } - - void Serialize(std::ostream* out) const; - void Deserialize(std::istream* in); - - private: - NullOr GetEntry(Tag tag) const; - - std::vector data_; -}; - -class AuthorizationSetBuilder : public AuthorizationSet { - public: - template - AuthorizationSetBuilder& Authorization(TagType ttag, ValueType&&... value) { - push_back(ttag, std::forward(value)...); - return *this; - } - - template - AuthorizationSetBuilder& Authorization(TypedTag ttag, const uint8_t* data, - size_t data_length) { - hidl_vec new_blob; - new_blob.setToExternal(const_cast(data), data_length); - push_back(ttag, std::move(new_blob)); - return *this; - } - - template - AuthorizationSetBuilder& Authorization(TypedTag ttag, const char* data, - size_t data_length) { - return Authorization(ttag, reinterpret_cast(data), data_length); - } - - AuthorizationSetBuilder& Authorizations(AuthorizationSet&& set); - AuthorizationSetBuilder& Authorizations(const AuthorizationSet& set); - - AuthorizationSetBuilder& RsaKey(uint32_t key_size, uint64_t public_exponent); - AuthorizationSetBuilder& EcdsaKey(uint32_t key_size); - AuthorizationSetBuilder& EcdsaKey(EcCurve curve); - AuthorizationSetBuilder& AesKey(uint32_t key_size); - AuthorizationSetBuilder& HmacKey(uint32_t key_size); - - AuthorizationSetBuilder& RsaSigningKey(uint32_t key_size, uint64_t public_exponent); - AuthorizationSetBuilder& RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent); - AuthorizationSetBuilder& EcdsaSigningKey(uint32_t key_size); - AuthorizationSetBuilder& EcdsaSigningKey(EcCurve curve); - AuthorizationSetBuilder& AesEncryptionKey(uint32_t key_size); - - AuthorizationSetBuilder& SigningKey(); - AuthorizationSetBuilder& EncryptionKey(); - AuthorizationSetBuilder& NoDigestOrPadding(); - AuthorizationSetBuilder& EcbMode(); - - AuthorizationSetBuilder& BlockMode(std::initializer_list block_modes); - AuthorizationSetBuilder& Digest(std::initializer_list digests); - AuthorizationSetBuilder& Padding(std::initializer_list padding_modes); - - // The following forwarding templates enable BlockMode,Digest and Padding to be called with a - // variable number of arguments; no need to wrap them in braces to make them an initalizer_list. - template AuthorizationSetBuilder& BlockMode(T&&... a) { - return BlockMode({std::forward(a)...}); - } - template AuthorizationSetBuilder& Digest(T&&... a) { - return Digest({std::forward(a)...}); - } - template AuthorizationSetBuilder& Padding(T&&... a) { - return Padding({std::forward(a)...}); - } -}; - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::Authorizations(AuthorizationSet&& set) { - move(set.begin(), set.end()); - set.Clear(); - return *this; -} - -inline AuthorizationSetBuilder& -AuthorizationSetBuilder::Authorizations(const AuthorizationSet& set) { - push_back(set.begin(), set.end()); - return *this; -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaKey(uint32_t key_size, - uint64_t public_exponent) { - Authorization(TAG_ALGORITHM, Algorithm::RSA); - Authorization(TAG_KEY_SIZE, key_size); - Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent); - return *this; -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(uint32_t key_size) { - Authorization(TAG_ALGORITHM, Algorithm::EC); - Authorization(TAG_KEY_SIZE, key_size); - return *this; -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(EcCurve curve) { - Authorization(TAG_ALGORITHM, Algorithm::EC); - Authorization(TAG_EC_CURVE, curve); - return *this; -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesKey(uint32_t key_size) { - Authorization(TAG_ALGORITHM, Algorithm::AES); - return Authorization(TAG_KEY_SIZE, key_size); -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::HmacKey(uint32_t key_size) { - Authorization(TAG_ALGORITHM, Algorithm::HMAC); - Authorization(TAG_KEY_SIZE, key_size); - return SigningKey(); -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaSigningKey(uint32_t key_size, - uint64_t public_exponent) { - RsaKey(key_size, public_exponent); - return SigningKey(); -} - -inline AuthorizationSetBuilder& -AuthorizationSetBuilder::RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent) { - RsaKey(key_size, public_exponent); - return EncryptionKey(); -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(uint32_t key_size) { - EcdsaKey(key_size); - return SigningKey(); -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(EcCurve curve) { - EcdsaKey(curve); - return SigningKey(); -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesEncryptionKey(uint32_t key_size) { - AesKey(key_size); - return EncryptionKey(); -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::SigningKey() { - Authorization(TAG_PURPOSE, KeyPurpose::SIGN); - return Authorization(TAG_PURPOSE, KeyPurpose::VERIFY); -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::EncryptionKey() { - Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT); - return Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT); -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::NoDigestOrPadding() { - Authorization(TAG_DIGEST, Digest::NONE); - return Authorization(TAG_PADDING, PaddingMode::NONE); -} - -inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() { - return BlockMode(BlockMode::ECB); -} - -inline AuthorizationSetBuilder& -AuthorizationSetBuilder::BlockMode(std::initializer_list block_modes) { - for (auto block_mode : block_modes) { - Authorization(TAG_BLOCK_MODE, block_mode); - } - return *this; -} - -inline AuthorizationSetBuilder& -AuthorizationSetBuilder::Digest(std::initializer_list digests) { - for (auto digest : digests) { - Authorization(TAG_DIGEST, digest); - } - return *this; -} - -inline AuthorizationSetBuilder& -AuthorizationSetBuilder::Padding(std::initializer_list padding_modes) { - for (auto padding : padding_modes) { - Authorization(TAG_PADDING, padding); - } - return *this; -} - -} // namespace V3_0 -} // namespace keymaster -} // namespace hardware -} // namespace android - -#endif // HARDWARE_INTERFACES_KEYMASTER_30_VTS_FUNCTIONAL_AUTHORIZATION_SET_H_ diff --git a/keymaster/3.0/vts/functional/key_param_output.cpp b/keymaster/3.0/vts/functional/key_param_output.cpp deleted file mode 100644 index fc9f6852..00000000 --- a/keymaster/3.0/vts/functional/key_param_output.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2016 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 "key_param_output.h" - -#include - -namespace android { -namespace hardware { - -namespace keymaster { -namespace V3_0 { - -::std::ostream& operator<<(::std::ostream& os, const hidl_vec& set) { - if (set.size() == 0) { - os << "(Empty)" << ::std::endl; - } else { - os << "\n"; - for (size_t i = 0; i < set.size(); ++i) - os << set[i] << ::std::endl; - } - return os; -} - -::std::ostream& operator<<(::std::ostream& os, ErrorCode value) { - return os << (int)value; -} - -::std::ostream& operator<<(::std::ostream& os, Digest value) { - return os << stringify(value); -} - -::std::ostream& operator<<(::std::ostream& os, Algorithm value) { - return os << stringify(value); -} - -::std::ostream& operator<<(::std::ostream& os, BlockMode value) { - return os << stringify(value); -} - -::std::ostream& operator<<(::std::ostream& os, PaddingMode value) { - return os << stringify(value); -} - -::std::ostream& operator<<(::std::ostream& os, KeyOrigin value) { - return os << stringify(value); -} - -::std::ostream& operator<<(::std::ostream& os, KeyPurpose value) { - return os << stringify(value); -} - -::std::ostream& operator<<(::std::ostream& os, EcCurve value) { - return os << stringify(value); -} - -::std::ostream& operator<<(::std::ostream& os, const KeyParameter& param) { - os << stringifyTag(param.tag) << ": "; - switch (typeFromTag(param.tag)) { - case TagType::INVALID: - return os << " Invalid"; - case TagType::UINT_REP: - case TagType::UINT: - return os << param.f.integer; - case TagType::ENUM_REP: - case TagType::ENUM: - switch (param.tag) { - case Tag::ALGORITHM: - return os << param.f.algorithm; - case Tag::BLOCK_MODE: - return os << param.f.blockMode; - case Tag::PADDING: - return os << param.f.paddingMode; - case Tag::DIGEST: - return os << param.f.digest; - case Tag::EC_CURVE: - return os << (int)param.f.ecCurve; - case Tag::ORIGIN: - return os << param.f.origin; - case Tag::BLOB_USAGE_REQUIREMENTS: - return os << (int)param.f.keyBlobUsageRequirements; - case Tag::PURPOSE: - return os << param.f.purpose; - default: - return os << " UNKNOWN ENUM " << param.f.integer; - } - case TagType::ULONG_REP: - case TagType::ULONG: - return os << param.f.longInteger; - case TagType::DATE: - return os << param.f.dateTime; - case TagType::BOOL: - return os << "true"; - case TagType::BIGNUM: - os << " Bignum: "; - for (size_t i = 0; i < param.blob.size(); ++i) { - os << ::std::hex << ::std::setw(2) << static_cast(param.blob[i]) << ::std::dec; - } - return os; - case TagType::BYTES: - os << " Bytes: "; - for (size_t i = 0; i < param.blob.size(); ++i) { - os << ::std::hex << ::std::setw(2) << static_cast(param.blob[i]) << ::std::dec; - } - return os; - } - return os << "UNKNOWN TAG TYPE!"; -} - -::std::ostream& operator<<(::std::ostream& os, const KeyCharacteristics& chars) { - return os << "SW: " << chars.softwareEnforced << ::std::endl - << "TEE: " << chars.teeEnforced << ::std::endl; -} - -} // namespace V3_0 -} // namespace keymaster -} // namespace hardware -} // namespace android diff --git a/keymaster/3.0/vts/functional/key_param_output.h b/keymaster/3.0/vts/functional/key_param_output.h deleted file mode 100644 index 5edec2d6..00000000 --- a/keymaster/3.0/vts/functional/key_param_output.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2016 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 - -#include - -#include "keymaster_tags.h" - -namespace android { -namespace hardware { -namespace keymaster { -namespace V3_0 { - -template -::std::ostream& operator<<(::std::ostream& os, const NullOr& value) { - if (!value.isOk()) { - os << "(value not present)"; - } else { - os << value.value(); - } - return os; -} - -::std::ostream& operator<<(::std::ostream& os, const hidl_vec& set); -::std::ostream& operator<<(::std::ostream& os, BlockMode value); -::std::ostream& operator<<(::std::ostream& os, Digest value); -::std::ostream& operator<<(::std::ostream& os, EcCurve value); -::std::ostream& operator<<(::std::ostream& os, ErrorCode value); -::std::ostream& operator<<(::std::ostream& os, PaddingMode value); -::std::ostream& operator<<(::std::ostream& os, const KeyCharacteristics& value); -::std::ostream& operator<<(::std::ostream& os, const KeyParameter& value); - -} // namespace V3_0 -} // namespace keymaster -} // namespace hardware -} // namespace android diff --git a/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp deleted file mode 100644 index 92266b55..00000000 --- a/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp +++ /dev/null @@ -1,3909 +0,0 @@ -/* - * Copyright (C) 2016 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 "keymaster_hidl_hal_test" -#include - -#include - -#include -#include - -#include -#include - -#include - -#include - -#include "authorization_set.h" -#include "key_param_output.h" - -#include - -#include "attestation_record.h" -#include "openssl_utils.h" - -using ::android::sp; - -using ::std::string; - -// This service_name will be passed to getService when retrieving the keymaster service to test. To -// change it from "default" specify the selected service name on the command line. The first -// non-gtest argument will be used as the service name. -string service_name = "default"; - -namespace android { -namespace hardware { - -template bool operator==(const hidl_vec& a, const hidl_vec& b) { - if (a.size() != b.size()) { - return false; - } - for (size_t i = 0; i < a.size(); ++i) { - if (a[i] != b[i]) { - return false; - } - } - return true; -} - -namespace keymaster { -namespace V3_0 { - -bool operator==(const KeyParameter& a, const KeyParameter& b) { - if (a.tag != b.tag) { - return false; - } - - switch (a.tag) { - - /* Boolean tags */ - case Tag::INVALID: - case Tag::CALLER_NONCE: - case Tag::INCLUDE_UNIQUE_ID: - case Tag::ECIES_SINGLE_HASH_MODE: - case Tag::BOOTLOADER_ONLY: - case Tag::NO_AUTH_REQUIRED: - case Tag::ALLOW_WHILE_ON_BODY: - case Tag::EXPORTABLE: - case Tag::ALL_APPLICATIONS: - case Tag::ROLLBACK_RESISTANT: - case Tag::RESET_SINCE_ID_ROTATION: - return true; - - /* Integer tags */ - case Tag::KEY_SIZE: - case Tag::MIN_MAC_LENGTH: - case Tag::MIN_SECONDS_BETWEEN_OPS: - case Tag::MAX_USES_PER_BOOT: - case Tag::ALL_USERS: - case Tag::USER_ID: - case Tag::OS_VERSION: - case Tag::OS_PATCHLEVEL: - case Tag::MAC_LENGTH: - case Tag::AUTH_TIMEOUT: - return a.f.integer == b.f.integer; - - /* Long integer tags */ - case Tag::RSA_PUBLIC_EXPONENT: - case Tag::USER_SECURE_ID: - return a.f.longInteger == b.f.longInteger; - - /* Date-time tags */ - case Tag::ACTIVE_DATETIME: - case Tag::ORIGINATION_EXPIRE_DATETIME: - case Tag::USAGE_EXPIRE_DATETIME: - case Tag::CREATION_DATETIME: - return a.f.dateTime == b.f.dateTime; - - /* Bytes tags */ - case Tag::APPLICATION_ID: - case Tag::APPLICATION_DATA: - case Tag::ROOT_OF_TRUST: - case Tag::UNIQUE_ID: - case Tag::ATTESTATION_CHALLENGE: - case Tag::ATTESTATION_APPLICATION_ID: - case Tag::ATTESTATION_ID_BRAND: - case Tag::ATTESTATION_ID_DEVICE: - case Tag::ATTESTATION_ID_PRODUCT: - case Tag::ATTESTATION_ID_SERIAL: - case Tag::ATTESTATION_ID_IMEI: - case Tag::ATTESTATION_ID_MEID: - case Tag::ATTESTATION_ID_MANUFACTURER: - case Tag::ATTESTATION_ID_MODEL: - case Tag::ASSOCIATED_DATA: - case Tag::NONCE: - case Tag::AUTH_TOKEN: - return a.blob == b.blob; - - /* Enum tags */ - case Tag::PURPOSE: - return a.f.purpose == b.f.purpose; - case Tag::ALGORITHM: - return a.f.algorithm == b.f.algorithm; - case Tag::BLOCK_MODE: - return a.f.blockMode == b.f.blockMode; - case Tag::DIGEST: - return a.f.digest == b.f.digest; - case Tag::PADDING: - return a.f.paddingMode == b.f.paddingMode; - case Tag::EC_CURVE: - return a.f.ecCurve == b.f.ecCurve; - case Tag::BLOB_USAGE_REQUIREMENTS: - return a.f.keyBlobUsageRequirements == b.f.keyBlobUsageRequirements; - case Tag::USER_AUTH_TYPE: - return a.f.integer == b.f.integer; - case Tag::ORIGIN: - return a.f.origin == b.f.origin; - - /* Unsupported tags */ - case Tag::KDF: - return false; - } -} - -bool operator==(const AuthorizationSet& a, const AuthorizationSet& b) { - return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin()); -} - -bool operator==(const KeyCharacteristics& a, const KeyCharacteristics& b) { - // This isn't very efficient. Oh, well. - AuthorizationSet a_sw(a.softwareEnforced); - AuthorizationSet b_sw(b.softwareEnforced); - AuthorizationSet a_tee(b.teeEnforced); - AuthorizationSet b_tee(b.teeEnforced); - - a_sw.Sort(); - b_sw.Sort(); - a_tee.Sort(); - b_tee.Sort(); - - return a_sw == b_sw && a_tee == b_sw; -} - -::std::ostream& operator<<(::std::ostream& os, const AuthorizationSet& set) { - if (set.size() == 0) - os << "(Empty)" << ::std::endl; - else { - os << "\n"; - for (size_t i = 0; i < set.size(); ++i) - os << set[i] << ::std::endl; - } - return os; -} - -namespace test { -namespace { - -template -bool contains(hidl_vec& set, TypedTag ttag, ValueT expected_value) { - size_t count = std::count_if(set.begin(), set.end(), [&](const KeyParameter& param) { - return param.tag == tag && accessTagValue(ttag, param) == expected_value; - }); - return count == 1; -} - -template -bool contains(hidl_vec& set, TypedTag) { - size_t count = std::count_if(set.begin(), set.end(), - [&](const KeyParameter& param) { return param.tag == tag; }); - return count > 0; -} - -constexpr char hex_value[256] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, // '0'..'9' - 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 'A'..'F' - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 'a'..'f' - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -string hex2str(string a) { - string b; - size_t num = a.size() / 2; - b.resize(num); - for (size_t i = 0; i < num; i++) { - b[i] = (hex_value[a[i * 2] & 0xFF] << 4) + (hex_value[a[i * 2 + 1] & 0xFF]); - } - return b; -} - -string rsa_key = hex2str("30820275020100300d06092a864886f70d01010105000482025f3082025b" - "02010002818100c6095409047d8634812d5a218176e45c41d60a75b13901" - "f234226cffe776521c5a77b9e389417b71c0b6a44d13afe4e4a2805d46c9" - "da2935adb1ff0c1f24ea06e62b20d776430a4d435157233c6f916783c30e" - "310fcbd89b85c2d56771169785ac12bca244abda72bfb19fc44d27c81e1d" - "92de284f4061edfd99280745ea6d2502030100010281801be0f04d9cae37" - "18691f035338308e91564b55899ffb5084d2460e6630257e05b3ceab0297" - "2dfabcd6ce5f6ee2589eb67911ed0fac16e43a444b8c861e544a05933657" - "72f8baf6b22fc9e3c5f1024b063ac080a7b2234cf8aee8f6c47bbf4fd3ac" - "e7240290bef16c0b3f7f3cdd64ce3ab5912cf6e32f39ab188358afcccd80" - "81024100e4b49ef50f765d3b24dde01aceaaf130f2c76670a91a61ae08af" - "497b4a82be6dee8fcdd5e3f7ba1cfb1f0c926b88f88c92bfab137fba2285" - "227b83c342ff7c55024100ddabb5839c4c7f6bf3d4183231f005b31aa58a" - "ffdda5c79e4cce217f6bc930dbe563d480706c24e9ebfcab28a6cdefd324" - "b77e1bf7251b709092c24ff501fd91024023d4340eda3445d8cd26c14411" - "da6fdca63c1ccd4b80a98ad52b78cc8ad8beb2842c1d280405bc2f6c1bea" - "214a1d742ab996b35b63a82a5e470fa88dbf823cdd02401b7b57449ad30d" - "1518249a5f56bb98294d4b6ac12ffc86940497a5a5837a6cf946262b4945" - "26d328c11e1126380fde04c24f916dec250892db09a6d77cdba351024077" - "62cd8f4d050da56bd591adb515d24d7ccd32cca0d05f866d583514bd7324" - "d5f33645e8ed8b4a1cb3cc4a1d67987399f2a09f5b3fb68c88d5e5d90ac3" - "3492d6"); - -string ec_key = hex2str("308187020100301306072a8648ce3d020106082a8648ce3d030107046d30" - "6b0201010420737c2ecd7b8d1940bf2930aa9b4ed3ff941eed09366bc032" - "99986481f3a4d859a14403420004bf85d7720d07c25461683bc648b4778a" - "9a14dd8a024e3bdd8c7ddd9ab2b528bbc7aa1b51f14ebbbb0bd0ce21bcc4" - "1c6eb00083cf3376d11fd44949e0b2183bfe"); - -struct RSA_Delete { - void operator()(RSA* p) { RSA_free(p); } -}; - -X509* parse_cert_blob(const hidl_vec& blob) { - const uint8_t* p = blob.data(); - return d2i_X509(nullptr, &p, blob.size()); -} - -bool verify_chain(const hidl_vec>& chain) { - for (size_t i = 0; i < chain.size() - 1; ++i) { - auto& key_cert_blob = chain[i]; - auto& signing_cert_blob = chain[i + 1]; - - X509_Ptr key_cert(parse_cert_blob(key_cert_blob)); - X509_Ptr signing_cert(parse_cert_blob(signing_cert_blob)); - EXPECT_TRUE(!!key_cert.get() && !!signing_cert.get()); - if (!key_cert.get() || !signing_cert.get()) return false; - - EVP_PKEY_Ptr signing_pubkey(X509_get_pubkey(signing_cert.get())); - EXPECT_TRUE(!!signing_pubkey.get()); - if (!signing_pubkey.get()) return false; - - EXPECT_EQ(1, X509_verify(key_cert.get(), signing_pubkey.get())) - << "Verification of certificate " << i << " failed"; - } - - return true; -} - -// Extract attestation record from cert. Returned object is still part of cert; don't free it -// separately. -ASN1_OCTET_STRING* get_attestation_record(X509* certificate) { - ASN1_OBJECT_Ptr oid(OBJ_txt2obj(kAttestionRecordOid, 1 /* dotted string format */)); - EXPECT_TRUE(!!oid.get()); - if (!oid.get()) return nullptr; - - int location = X509_get_ext_by_OBJ(certificate, oid.get(), -1 /* search from beginning */); - EXPECT_NE(-1, location); - if (location == -1) return nullptr; - - X509_EXTENSION* attest_rec_ext = X509_get_ext(certificate, location); - EXPECT_TRUE(!!attest_rec_ext); - if (!attest_rec_ext) return nullptr; - - ASN1_OCTET_STRING* attest_rec = X509_EXTENSION_get_data(attest_rec_ext); - EXPECT_TRUE(!!attest_rec); - return attest_rec; -} - -bool tag_in_list(const KeyParameter& entry) { - // Attestations don't contain everything in key authorization lists, so we need to filter - // the key lists to produce the lists that we expect to match the attestations. - auto tag_list = { - Tag::USER_ID, Tag::INCLUDE_UNIQUE_ID, Tag::BLOB_USAGE_REQUIREMENTS, - Tag::EC_CURVE /* Tag::EC_CURVE will be included by KM2 implementations */, - }; - return std::find(tag_list.begin(), tag_list.end(), entry.tag) != tag_list.end(); -} - -AuthorizationSet filter_tags(const AuthorizationSet& set) { - AuthorizationSet filtered; - std::remove_copy_if(set.begin(), set.end(), std::back_inserter(filtered), tag_in_list); - return filtered; -} - -std::string make_string(const uint8_t* data, size_t length) { - return std::string(reinterpret_cast(data), length); -} - -template std::string make_string(const uint8_t (&a)[N]) { - return make_string(a, N); -} - -class HidlBuf : public hidl_vec { - typedef hidl_vec super; - - public: - HidlBuf() {} - HidlBuf(const super& other) : super(other) {} - HidlBuf(super&& other) : super(std::move(other)) {} - explicit HidlBuf(const std::string& other) : HidlBuf() { *this = other; } - - HidlBuf& operator=(const super& other) { - super::operator=(other); - return *this; - } - - HidlBuf& operator=(super&& other) { - super::operator=(std::move(other)); - return *this; - } - - HidlBuf& operator=(const string& other) { - resize(other.size()); - for (size_t i = 0; i < other.size(); ++i) { - (*this)[i] = static_cast(other[i]); - } - return *this; - } - - string to_string() const { return string(reinterpret_cast(data()), size()); } -}; - -constexpr uint64_t kOpHandleSentinel = 0xFFFFFFFFFFFFFFFF; - -} // namespace - -class KeymasterHidlTest : public ::testing::VtsHalHidlTargetTestBase { - public: - void TearDown() override { - if (key_blob_.size()) { - EXPECT_EQ(ErrorCode::OK, DeleteKey()); - } - AbortIfNeeded(); - } - - // SetUpTestCase runs only once per test case, not once per test. - static void SetUpTestCase() { - keymaster_ = IKeymasterDevice::getService(service_name); - ASSERT_NE(keymaster_, nullptr); - - ASSERT_TRUE( - keymaster_ - ->getHardwareFeatures([&](bool isSecure, bool supportsEc, bool supportsSymmetric, - bool supportsAttestation, bool supportsAllDigests, - const hidl_string& name, const hidl_string& author) { - is_secure_ = isSecure; - supports_ec_ = supportsEc; - supports_symmetric_ = supportsSymmetric; - supports_attestation_ = supportsAttestation; - supports_all_digests_ = supportsAllDigests; - name_ = name; - author_ = author; - }) - .isOk()); - - os_version_ = ::keymaster::GetOsVersion(); - os_patch_level_ = ::keymaster::GetOsPatchlevel(); - } - - static void TearDownTestCase() { keymaster_.clear(); } - - static IKeymasterDevice& keymaster() { return *keymaster_; } - static uint32_t os_version() { return os_version_; } - static uint32_t os_patch_level() { return os_patch_level_; } - - AuthorizationSet UserAuths() { return AuthorizationSetBuilder().Authorization(TAG_USER_ID, 7); } - - ErrorCode GenerateKey(const AuthorizationSet& key_desc, HidlBuf* key_blob, - KeyCharacteristics* key_characteristics) { - EXPECT_NE(key_blob, nullptr); - EXPECT_NE(key_characteristics, nullptr); - EXPECT_EQ(0U, key_blob->size()); - - ErrorCode error; - EXPECT_TRUE(keymaster_ - ->generateKey(key_desc.hidl_data(), - [&](ErrorCode hidl_error, const HidlBuf& hidl_key_blob, - const KeyCharacteristics& hidl_key_characteristics) { - error = hidl_error; - *key_blob = hidl_key_blob; - *key_characteristics = hidl_key_characteristics; - }) - .isOk()); - // On error, blob & characteristics should be empty. - if (error != ErrorCode::OK) { - EXPECT_EQ(0U, key_blob->size()); - EXPECT_EQ(0U, (key_characteristics->softwareEnforced.size() + - key_characteristics->teeEnforced.size())); - } - return error; - } - - ErrorCode GenerateKey(const AuthorizationSet& key_desc) { - return GenerateKey(key_desc, &key_blob_, &key_characteristics_); - } - - ErrorCode ImportKey(const AuthorizationSet& key_desc, KeyFormat format, - const string& key_material, HidlBuf* key_blob, - KeyCharacteristics* key_characteristics) { - ErrorCode error; - EXPECT_TRUE(keymaster_ - ->importKey(key_desc.hidl_data(), format, HidlBuf(key_material), - [&](ErrorCode hidl_error, const HidlBuf& hidl_key_blob, - const KeyCharacteristics& hidl_key_characteristics) { - error = hidl_error; - *key_blob = hidl_key_blob; - *key_characteristics = hidl_key_characteristics; - }) - .isOk()); - // On error, blob & characteristics should be empty. - if (error != ErrorCode::OK) { - EXPECT_EQ(0U, key_blob->size()); - EXPECT_EQ(0U, (key_characteristics->softwareEnforced.size() + - key_characteristics->teeEnforced.size())); - } - return error; - } - - ErrorCode ImportKey(const AuthorizationSet& key_desc, KeyFormat format, - const string& key_material) { - return ImportKey(key_desc, format, key_material, &key_blob_, &key_characteristics_); - } - - ErrorCode ExportKey(KeyFormat format, const HidlBuf& key_blob, const HidlBuf& client_id, - const HidlBuf& app_data, HidlBuf* key_material) { - ErrorCode error; - EXPECT_TRUE( - keymaster_ - ->exportKey(format, key_blob, client_id, app_data, - [&](ErrorCode hidl_error_code, const HidlBuf& hidl_key_material) { - error = hidl_error_code; - *key_material = hidl_key_material; - }) - .isOk()); - // On error, blob should be empty. - if (error != ErrorCode::OK) { - EXPECT_EQ(0U, key_material->size()); - } - return error; - } - - ErrorCode ExportKey(KeyFormat format, HidlBuf* key_material) { - HidlBuf client_id, app_data; - return ExportKey(format, key_blob_, client_id, app_data, key_material); - } - - ErrorCode DeleteKey(HidlBuf* key_blob) { - ErrorCode error = keymaster_->deleteKey(*key_blob); - *key_blob = HidlBuf(); - return error; - } - - ErrorCode DeleteKey() { return DeleteKey(&key_blob_); } - - ErrorCode GetCharacteristics(const HidlBuf& key_blob, const HidlBuf& client_id, - const HidlBuf& app_data, KeyCharacteristics* key_characteristics) { - ErrorCode error; - keymaster_->getKeyCharacteristics( - key_blob, client_id, app_data, - [&](ErrorCode hidl_error, const KeyCharacteristics& hidl_key_characteristics) { - error = hidl_error, *key_characteristics = hidl_key_characteristics; - }); - return error; - } - - ErrorCode GetCharacteristics(const HidlBuf& key_blob, KeyCharacteristics* key_characteristics) { - HidlBuf client_id, app_data; - return GetCharacteristics(key_blob, client_id, app_data, key_characteristics); - } - - ErrorCode Begin(KeyPurpose purpose, const HidlBuf& key_blob, const AuthorizationSet& in_params, - AuthorizationSet* out_params, OperationHandle* op_handle) { - SCOPED_TRACE("Begin"); - ErrorCode error; - OperationHandle saved_handle = *op_handle; - EXPECT_TRUE( - keymaster_ - ->begin(purpose, key_blob, in_params.hidl_data(), - [&](ErrorCode hidl_error, const hidl_vec& hidl_out_params, - uint64_t hidl_op_handle) { - error = hidl_error; - *out_params = hidl_out_params; - *op_handle = hidl_op_handle; - }) - .isOk()); - if (error != ErrorCode::OK) { - // Some implementations may modify *op_handle on error. - *op_handle = saved_handle; - } - return error; - } - - ErrorCode Begin(KeyPurpose purpose, const AuthorizationSet& in_params, - AuthorizationSet* out_params) { - SCOPED_TRACE("Begin"); - EXPECT_EQ(kOpHandleSentinel, op_handle_); - return Begin(purpose, key_blob_, in_params, out_params, &op_handle_); - } - - ErrorCode Begin(KeyPurpose purpose, const AuthorizationSet& in_params) { - SCOPED_TRACE("Begin"); - AuthorizationSet out_params; - ErrorCode error = Begin(purpose, in_params, &out_params); - EXPECT_TRUE(out_params.empty()); - return error; - } - - ErrorCode Update(OperationHandle op_handle, const AuthorizationSet& in_params, - const string& input, AuthorizationSet* out_params, string* output, - size_t* input_consumed) { - SCOPED_TRACE("Update"); - ErrorCode error; - EXPECT_TRUE(keymaster_ - ->update(op_handle, in_params.hidl_data(), HidlBuf(input), - [&](ErrorCode hidl_error, uint32_t hidl_input_consumed, - const hidl_vec& hidl_out_params, - const HidlBuf& hidl_output) { - error = hidl_error; - out_params->push_back(AuthorizationSet(hidl_out_params)); - output->append(hidl_output.to_string()); - *input_consumed = hidl_input_consumed; - }) - .isOk()); - return error; - } - - ErrorCode Update(const string& input, string* out, size_t* input_consumed) { - SCOPED_TRACE("Update"); - AuthorizationSet out_params; - ErrorCode error = Update(op_handle_, AuthorizationSet() /* in_params */, input, &out_params, - out, input_consumed); - EXPECT_TRUE(out_params.empty()); - return error; - } - - ErrorCode Finish(OperationHandle op_handle, const AuthorizationSet& in_params, - const string& input, const string& signature, AuthorizationSet* out_params, - string* output) { - SCOPED_TRACE("Finish"); - ErrorCode error; - EXPECT_TRUE( - keymaster_ - ->finish(op_handle, in_params.hidl_data(), HidlBuf(input), HidlBuf(signature), - [&](ErrorCode hidl_error, const hidl_vec& hidl_out_params, - const HidlBuf& hidl_output) { - error = hidl_error; - *out_params = hidl_out_params; - output->append(hidl_output.to_string()); - }) - .isOk()); - op_handle_ = kOpHandleSentinel; // So dtor doesn't Abort(). - return error; - } - - ErrorCode Finish(const string& message, string* output) { - SCOPED_TRACE("Finish"); - AuthorizationSet out_params; - string finish_output; - ErrorCode error = Finish(op_handle_, AuthorizationSet() /* in_params */, message, - "" /* signature */, &out_params, output); - if (error != ErrorCode::OK) { - return error; - } - EXPECT_EQ(0U, out_params.size()); - return error; - } - - ErrorCode Finish(const string& message, const string& signature, string* output) { - SCOPED_TRACE("Finish"); - AuthorizationSet out_params; - ErrorCode error = Finish(op_handle_, AuthorizationSet() /* in_params */, message, signature, - &out_params, output); - op_handle_ = kOpHandleSentinel; // So dtor doesn't Abort(). - if (error != ErrorCode::OK) { - return error; - } - EXPECT_EQ(0U, out_params.size()); - return error; - } - - ErrorCode Abort(OperationHandle op_handle) { - SCOPED_TRACE("Abort"); - auto retval = keymaster_->abort(op_handle); - EXPECT_TRUE(retval.isOk()); - return retval; - } - - void AbortIfNeeded() { - SCOPED_TRACE("AbortIfNeeded"); - if (op_handle_ != kOpHandleSentinel) { - EXPECT_EQ(ErrorCode::OK, Abort(op_handle_)); - op_handle_ = kOpHandleSentinel; - } - } - - ErrorCode AttestKey(const HidlBuf& key_blob, const AuthorizationSet& attest_params, - hidl_vec>* cert_chain) { - SCOPED_TRACE("AttestKey"); - ErrorCode error; - keymaster_->attestKey( - key_blob, attest_params.hidl_data(), - [&](ErrorCode hidl_error, const hidl_vec>& hidl_cert_chain) { - error = hidl_error; - *cert_chain = hidl_cert_chain; - }); - return error; - } - - ErrorCode AttestKey(const AuthorizationSet& attest_params, - hidl_vec>* cert_chain) { - SCOPED_TRACE("AttestKey"); - return AttestKey(key_blob_, attest_params, cert_chain); - } - - string ProcessMessage(const HidlBuf& key_blob, KeyPurpose operation, const string& message, - const AuthorizationSet& in_params, AuthorizationSet* out_params) { - SCOPED_TRACE("ProcessMessage"); - AuthorizationSet begin_out_params; - EXPECT_EQ(ErrorCode::OK, - Begin(operation, key_blob, in_params, &begin_out_params, &op_handle_)); - - string unused; - AuthorizationSet finish_params; - AuthorizationSet finish_out_params; - string output; - EXPECT_EQ(ErrorCode::OK, - Finish(op_handle_, finish_params, message, unused, &finish_out_params, &output)); - op_handle_ = kOpHandleSentinel; - - out_params->push_back(begin_out_params); - out_params->push_back(finish_out_params); - return output; - } - - string SignMessage(const HidlBuf& key_blob, const string& message, - const AuthorizationSet& params) { - SCOPED_TRACE("SignMessage"); - AuthorizationSet out_params; - string signature = ProcessMessage(key_blob, KeyPurpose::SIGN, message, params, &out_params); - EXPECT_TRUE(out_params.empty()); - return signature; - } - - string SignMessage(const string& message, const AuthorizationSet& params) { - SCOPED_TRACE("SignMessage"); - return SignMessage(key_blob_, message, params); - } - - string MacMessage(const string& message, Digest digest, size_t mac_length) { - SCOPED_TRACE("MacMessage"); - return SignMessage( - key_blob_, message, - AuthorizationSetBuilder().Digest(digest).Authorization(TAG_MAC_LENGTH, mac_length)); - } - - void CheckHmacTestVector(const string& key, const string& message, Digest digest, - const string& expected_mac) { - SCOPED_TRACE("CheckHmacTestVector"); - ASSERT_EQ(ErrorCode::OK, - ImportKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .HmacKey(key.size() * 8) - .Authorization(TAG_MIN_MAC_LENGTH, expected_mac.size() * 8) - .Digest(digest), - KeyFormat::RAW, key)); - string signature = MacMessage(message, digest, expected_mac.size() * 8); - EXPECT_EQ(expected_mac, signature) << "Test vector didn't match for digest " << (int)digest; - DeleteKey(); - } - - void CheckAesCtrTestVector(const string& key, const string& nonce, const string& message, - const string& expected_ciphertext) { - SCOPED_TRACE("CheckAesCtrTestVector"); - ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(key.size() * 8) - .BlockMode(BlockMode::CTR) - .Authorization(TAG_CALLER_NONCE) - .Padding(PaddingMode::NONE), - KeyFormat::RAW, key)); - - auto params = AuthorizationSetBuilder() - .Authorization(TAG_NONCE, nonce.data(), nonce.size()) - .BlockMode(BlockMode::CTR) - .Padding(PaddingMode::NONE); - AuthorizationSet out_params; - string ciphertext = EncryptMessage(key_blob_, message, params, &out_params); - EXPECT_EQ(expected_ciphertext, ciphertext); - } - - void VerifyMessage(const HidlBuf& key_blob, const string& message, const string& signature, - const AuthorizationSet& params) { - SCOPED_TRACE("VerifyMessage"); - AuthorizationSet begin_out_params; - ASSERT_EQ(ErrorCode::OK, - Begin(KeyPurpose::VERIFY, key_blob, params, &begin_out_params, &op_handle_)); - - string unused; - AuthorizationSet finish_params; - AuthorizationSet finish_out_params; - string output; - EXPECT_EQ(ErrorCode::OK, Finish(op_handle_, finish_params, message, signature, - &finish_out_params, &output)); - op_handle_ = kOpHandleSentinel; - EXPECT_TRUE(output.empty()); - } - - void VerifyMessage(const string& message, const string& signature, - const AuthorizationSet& params) { - SCOPED_TRACE("VerifyMessage"); - VerifyMessage(key_blob_, message, signature, params); - } - - string EncryptMessage(const HidlBuf& key_blob, const string& message, - const AuthorizationSet& in_params, AuthorizationSet* out_params) { - SCOPED_TRACE("EncryptMessage"); - return ProcessMessage(key_blob, KeyPurpose::ENCRYPT, message, in_params, out_params); - } - - string EncryptMessage(const string& message, const AuthorizationSet& params, - AuthorizationSet* out_params) { - SCOPED_TRACE("EncryptMessage"); - return EncryptMessage(key_blob_, message, params, out_params); - } - - string EncryptMessage(const string& message, const AuthorizationSet& params) { - SCOPED_TRACE("EncryptMessage"); - AuthorizationSet out_params; - string ciphertext = EncryptMessage(message, params, &out_params); - EXPECT_TRUE(out_params.empty()) - << "Output params should be empty. Contained: " << out_params; - return ciphertext; - } - - string DecryptMessage(const HidlBuf& key_blob, const string& ciphertext, - const AuthorizationSet& params) { - SCOPED_TRACE("DecryptMessage"); - AuthorizationSet out_params; - string plaintext = - ProcessMessage(key_blob, KeyPurpose::DECRYPT, ciphertext, params, &out_params); - EXPECT_TRUE(out_params.empty()); - return plaintext; - } - - string DecryptMessage(const string& ciphertext, const AuthorizationSet& params) { - SCOPED_TRACE("DecryptMessage"); - return DecryptMessage(key_blob_, ciphertext, params); - } - - template - void CheckKm0CryptoParam(TypedTag ttag, ValueT expected) { - SCOPED_TRACE("CheckKm0CryptoParam"); - if (is_secure_) { - EXPECT_TRUE(contains(key_characteristics_.teeEnforced, ttag, expected)); - EXPECT_FALSE(contains(key_characteristics_.softwareEnforced, ttag)); - } else { - EXPECT_TRUE(contains(key_characteristics_.softwareEnforced, ttag, expected)); - EXPECT_FALSE(contains(key_characteristics_.teeEnforced, ttag)); - } - } - - template - void CheckKm1CryptoParam(TypedTag ttag, ValueT expected) { - SCOPED_TRACE("CheckKm1CryptoParam"); - if (is_secure_ && supports_symmetric_) { - EXPECT_TRUE(contains(key_characteristics_.teeEnforced, ttag, expected)); - EXPECT_FALSE(contains(key_characteristics_.softwareEnforced, ttag)); - } else { - EXPECT_TRUE(contains(key_characteristics_.softwareEnforced, ttag, expected)); - EXPECT_FALSE(contains(key_characteristics_.teeEnforced, ttag)); - } - } - - template - void CheckKm2CryptoParam(TypedTag ttag, ValueT expected) { - SCOPED_TRACE("CheckKm2CryptoParam"); - if (supports_attestation_) { - EXPECT_TRUE(contains(key_characteristics_.teeEnforced, ttag, expected)); - EXPECT_FALSE(contains(key_characteristics_.softwareEnforced, ttag)); - } else if (!supports_symmetric_ /* KM version < 1 or SW */) { - EXPECT_TRUE(contains(key_characteristics_.softwareEnforced, ttag, expected)); - EXPECT_FALSE(contains(key_characteristics_.teeEnforced, ttag)); - } - } - - void CheckOrigin() { - SCOPED_TRACE("CheckOrigin"); - if (is_secure_ && supports_symmetric_) { - EXPECT_TRUE( - contains(key_characteristics_.teeEnforced, TAG_ORIGIN, KeyOrigin::IMPORTED)); - } else if (is_secure_) { - EXPECT_TRUE(contains(key_characteristics_.teeEnforced, TAG_ORIGIN, KeyOrigin::UNKNOWN)); - } else { - EXPECT_TRUE( - contains(key_characteristics_.softwareEnforced, TAG_ORIGIN, KeyOrigin::IMPORTED)); - } - } - - static bool IsSecure() { return is_secure_; } - static bool SupportsEc() { return supports_ec_; } - static bool SupportsSymmetric() { return supports_symmetric_; } - static bool SupportsAllDigests() { return supports_all_digests_; } - static bool SupportsAttestation() { return supports_attestation_; } - - static bool Km2Profile() { - return SupportsAttestation() && SupportsAllDigests() && SupportsSymmetric() && - SupportsEc() && IsSecure(); - } - - static bool Km1Profile() { - return !SupportsAttestation() && SupportsSymmetric() && SupportsEc() && IsSecure(); - } - - static bool Km0Profile() { - return !SupportsAttestation() && !SupportsAllDigests() && !SupportsSymmetric() && - IsSecure(); - } - - static bool SwOnlyProfile() { - return !SupportsAttestation() && !SupportsAllDigests() && !SupportsSymmetric() && - !SupportsEc() && !IsSecure(); - } - - HidlBuf key_blob_; - KeyCharacteristics key_characteristics_; - OperationHandle op_handle_ = kOpHandleSentinel; - - private: - static sp keymaster_; - static uint32_t os_version_; - static uint32_t os_patch_level_; - - static bool is_secure_; - static bool supports_ec_; - static bool supports_symmetric_; - static bool supports_attestation_; - static bool supports_all_digests_; - static hidl_string name_; - static hidl_string author_; -}; - -uint32_t expected_keymaster_version() { - if (!KeymasterHidlTest::IsSecure()) return 2; // SW is KM2 - - uint32_t keymaster_version = 0; - if (KeymasterHidlTest::SupportsSymmetric()) keymaster_version = 1; - if (KeymasterHidlTest::SupportsAttestation()) keymaster_version = 2; - return keymaster_version; -} - -bool verify_attestation_record(const string& challenge, AuthorizationSet expected_sw_enforced, - AuthorizationSet expected_tee_enforced, - const hidl_vec& attestation_cert) { - - X509_Ptr cert(parse_cert_blob(attestation_cert)); - EXPECT_TRUE(!!cert.get()); - if (!cert.get()) return false; - - ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get()); - EXPECT_TRUE(!!attest_rec); - if (!attest_rec) return false; - - AuthorizationSet att_sw_enforced; - AuthorizationSet att_tee_enforced; - uint32_t att_attestation_version; - uint32_t att_keymaster_version; - SecurityLevel att_attestation_security_level; - SecurityLevel att_keymaster_security_level; - HidlBuf att_challenge; - HidlBuf att_unique_id; - EXPECT_EQ(ErrorCode::OK, - parse_attestation_record(attest_rec->data, // - attest_rec->length, // - &att_attestation_version, // - &att_attestation_security_level, // - &att_keymaster_version, // - &att_keymaster_security_level, // - &att_challenge, // - &att_sw_enforced, // - &att_tee_enforced, // - &att_unique_id)); - - EXPECT_EQ(1U, att_attestation_version); - EXPECT_EQ(expected_keymaster_version(), att_keymaster_version); - EXPECT_EQ(KeymasterHidlTest::IsSecure() ? SecurityLevel::TRUSTED_ENVIRONMENT - : SecurityLevel::SOFTWARE, - att_keymaster_security_level); - EXPECT_EQ(KeymasterHidlTest::SupportsAttestation() ? SecurityLevel::TRUSTED_ENVIRONMENT - : SecurityLevel::SOFTWARE, - att_attestation_security_level); - - EXPECT_EQ(challenge.length(), att_challenge.size()); - EXPECT_EQ(0, memcmp(challenge.data(), att_challenge.data(), challenge.length())); - - att_sw_enforced.Sort(); - expected_sw_enforced.Sort(); - EXPECT_EQ(filter_tags(expected_sw_enforced), filter_tags(att_sw_enforced)); - - att_tee_enforced.Sort(); - expected_tee_enforced.Sort(); - EXPECT_EQ(filter_tags(expected_tee_enforced), filter_tags(att_tee_enforced)); - - return true; -} - -sp KeymasterHidlTest::keymaster_; -uint32_t KeymasterHidlTest::os_version_; -uint32_t KeymasterHidlTest::os_patch_level_; -bool KeymasterHidlTest::is_secure_; -bool KeymasterHidlTest::supports_ec_; -bool KeymasterHidlTest::supports_symmetric_; -bool KeymasterHidlTest::supports_all_digests_; -bool KeymasterHidlTest::supports_attestation_; -hidl_string KeymasterHidlTest::name_; -hidl_string KeymasterHidlTest::author_; - -typedef KeymasterHidlTest KeymasterVersionTest; - -/* - * KeymasterVersionTest.SensibleFeatures: - * - * Queries keymaster to find the set of features it supports. Fails if the combination doesn't - * correspond to any well-defined keymaster version. - */ -TEST_F(KeymasterVersionTest, SensibleFeatures) { - EXPECT_TRUE(Km2Profile() || Km1Profile() || Km0Profile() || SwOnlyProfile()) - << "Keymaster feature set doesn't fit any reasonable profile. Reported features:" - << "SupportsAttestation [" << SupportsAttestation() << "], " - << "SupportsSymmetric [" << SupportsSymmetric() << "], " - << "SupportsAllDigests [" << SupportsAllDigests() << "], " - << "SupportsEc [" << SupportsEc() << "], " - << "IsSecure [" << IsSecure() << "]"; -} - -class NewKeyGenerationTest : public KeymasterHidlTest { - protected: - void CheckBaseParams(const KeyCharacteristics& keyCharacteristics) { - // TODO(swillden): Distinguish which params should be in which auth list. - - AuthorizationSet auths(keyCharacteristics.teeEnforced); - auths.push_back(AuthorizationSet(keyCharacteristics.softwareEnforced)); - - EXPECT_TRUE(auths.Contains(TAG_ORIGIN, KeyOrigin::GENERATED)); - - EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::SIGN)); - EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::VERIFY)); - EXPECT_TRUE(auths.Contains(TAG_USER_ID, 7)) - << "User ID should be 7, was " << auths.GetTagValue(TAG_USER_ID); - - // Verify that App ID, App data and ROT are NOT included. - EXPECT_FALSE(auths.Contains(TAG_ROOT_OF_TRUST)); - EXPECT_FALSE(auths.Contains(TAG_APPLICATION_ID)); - EXPECT_FALSE(auths.Contains(TAG_APPLICATION_DATA)); - - // Check that some unexpected tags/values are NOT present. - EXPECT_FALSE(auths.Contains(TAG_PURPOSE, KeyPurpose::ENCRYPT)); - EXPECT_FALSE(auths.Contains(TAG_PURPOSE, KeyPurpose::DECRYPT)); - EXPECT_FALSE(auths.Contains(TAG_AUTH_TIMEOUT, 301)); - - // Now check that unspecified, defaulted tags are correct. - EXPECT_TRUE(auths.Contains(TAG_CREATION_DATETIME)); - - if (SupportsAttestation()) { - EXPECT_TRUE(auths.Contains(TAG_OS_VERSION, os_version())) - << "OS version is " << os_version() << " key reported " - << auths.GetTagValue(TAG_OS_VERSION); - EXPECT_TRUE(auths.Contains(TAG_OS_PATCHLEVEL, os_patch_level())) - << "OS patch level is " << os_patch_level() << " key reported " - << auths.GetTagValue(TAG_OS_PATCHLEVEL); - } - } -}; - -/* - * NewKeyGenerationTest.Rsa - * - * Verifies that keymaster can generate all required RSA key sizes, and that the resulting keys have - * correct characteristics. - */ -TEST_F(NewKeyGenerationTest, Rsa) { - for (auto key_size : {1024, 2048, 3072, 4096}) { - HidlBuf key_blob; - KeyCharacteristics key_characteristics; - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .RsaSigningKey(key_size, 3) - .Digest(Digest::NONE) - .Padding(PaddingMode::NONE) - .Authorizations(UserAuths()), - &key_blob, &key_characteristics)); - - ASSERT_GT(key_blob.size(), 0U); - CheckBaseParams(key_characteristics); - - AuthorizationSet crypto_params; - if (IsSecure()) { - crypto_params = key_characteristics.teeEnforced; - } else { - crypto_params = key_characteristics.softwareEnforced; - } - - EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, KM_ALGORITHM_RSA)); - EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)); - EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 3)); - - EXPECT_EQ(ErrorCode::OK, DeleteKey(&key_blob)); - } -} - -/* - * NewKeyGenerationTest.RsaNoDefaultSize - * - * Verifies that failing to specify a key size for RSA key generation returns UNSUPPORTED_KEY_SIZE. - */ -TEST_F(NewKeyGenerationTest, RsaNoDefaultSize) { - ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE, - GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_ALGORITHM, Algorithm::RSA) - .Authorization(TAG_RSA_PUBLIC_EXPONENT, 3) - .SigningKey())); -} - -/* - * NewKeyGenerationTest.Ecdsa - * - * Verifies that keymaster can generate all required EC key sizes, and that the resulting keys have - * correct characteristics. - */ -TEST_F(NewKeyGenerationTest, Ecdsa) { - for (auto key_size : {224, 256, 384, 521}) { - HidlBuf key_blob; - KeyCharacteristics key_characteristics; - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(key_size) - .Digest(Digest::NONE) - .Authorizations(UserAuths()), - &key_blob, &key_characteristics)); - ASSERT_GT(key_blob.size(), 0U); - CheckBaseParams(key_characteristics); - - AuthorizationSet crypto_params; - if (IsSecure()) { - crypto_params = key_characteristics.teeEnforced; - } else { - crypto_params = key_characteristics.softwareEnforced; - } - - EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC)); - EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)); - - EXPECT_EQ(ErrorCode::OK, DeleteKey(&key_blob)); - } -} - -/* - * NewKeyGenerationTest.EcdsaDefaultSize - * - * Verifies that failing to specify a key size for EC key generation returns UNSUPPORTED_KEY_SIZE. - */ -TEST_F(NewKeyGenerationTest, EcdsaDefaultSize) { - ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE, - GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_ALGORITHM, Algorithm::EC) - .SigningKey() - .Digest(Digest::NONE))); -} - -/* - * NewKeyGenerationTest.EcdsaInvalidSize - * - * Verifies that failing to specify an invalid key size for EC key generation returns - * UNSUPPORTED_KEY_SIZE. - */ -TEST_F(NewKeyGenerationTest, EcdsaInvalidSize) { - ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE, - GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(190).Digest(Digest::NONE))); -} - -/* - * NewKeyGenerationTest.EcdsaMismatchKeySize - * - * Verifies that specifying mismatched key size and curve for EC key generation returns - * INVALID_ARGUMENT. - */ -TEST_F(NewKeyGenerationTest, EcdsaMismatchKeySize) { - ASSERT_EQ(ErrorCode::INVALID_ARGUMENT, - GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(224) - .Authorization(TAG_EC_CURVE, EcCurve::P_256) - .Digest(Digest::NONE))) - << "(Possibly b/36233343)"; -} - -TEST_F(NewKeyGenerationTest, EcdsaAllValidSizes) { - size_t valid_sizes[] = {224, 256, 384, 521}; - for (size_t size : valid_sizes) { - EXPECT_EQ(ErrorCode::OK, - GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(size).Digest(Digest::NONE))) - << "Failed to generate size: " << size; - DeleteKey(); - } -} - -/* - * NewKeyGenerationTest.EcdsaAllValidCurves - * - * Verifies that keymaster supports all required EC curves. - */ -TEST_F(NewKeyGenerationTest, EcdsaAllValidCurves) { - EcCurve curves[] = {EcCurve::P_224, EcCurve::P_256, EcCurve::P_384, EcCurve::P_521}; - for (auto curve : curves) { - EXPECT_EQ( - ErrorCode::OK, - GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(curve).Digest(Digest::SHA_2_512))) - << "Failed to generate key on curve: " << curve; - DeleteKey(); - } -} - -/* - * NewKeyGenerationTest.Hmac - * - * Verifies that keymaster supports all required digests, and that the resulting keys have correct - * characteristics. - */ -TEST_F(NewKeyGenerationTest, Hmac) { - for (auto digest : {Digest::MD5, Digest::SHA1, Digest::SHA_2_224, Digest::SHA_2_256, - Digest::SHA_2_384, Digest::SHA_2_512}) { - HidlBuf key_blob; - KeyCharacteristics key_characteristics; - constexpr size_t key_size = 128; - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .HmacKey(key_size) - .Digest(digest) - .Authorization(TAG_MIN_MAC_LENGTH, 128) - .Authorizations(UserAuths()), - &key_blob, &key_characteristics)); - - ASSERT_GT(key_blob.size(), 0U); - CheckBaseParams(key_characteristics); - - AuthorizationSet teeEnforced = key_characteristics.teeEnforced; - AuthorizationSet softwareEnforced = key_characteristics.softwareEnforced; - if (SupportsAttestation() || SupportsAllDigests()) { - // Either KM2, which must support all, or KM1 that claims full support - EXPECT_TRUE(teeEnforced.Contains(TAG_ALGORITHM, Algorithm::HMAC)); - EXPECT_TRUE(teeEnforced.Contains(TAG_KEY_SIZE, key_size)); - } else if (SupportsSymmetric()) { - if (digest == Digest::SHA1 || digest == Digest::SHA_2_256) { - // KM1 must support SHA1 and SHA256 in hardware - EXPECT_TRUE(teeEnforced.Contains(TAG_ALGORITHM, Algorithm::HMAC)); - EXPECT_TRUE(teeEnforced.Contains(TAG_KEY_SIZE, key_size)); - } else { - // Othere digests may or may not be supported - EXPECT_TRUE(teeEnforced.Contains(TAG_ALGORITHM, Algorithm::HMAC) || - softwareEnforced.Contains(TAG_ALGORITHM, Algorithm::HMAC)); - EXPECT_TRUE(teeEnforced.Contains(TAG_KEY_SIZE, key_size) || - softwareEnforced.Contains(TAG_KEY_SIZE, key_size)); - } - } else { - // KM0 and SW KM do all digests in SW. - EXPECT_TRUE(softwareEnforced.Contains(TAG_ALGORITHM, Algorithm::HMAC)); - EXPECT_TRUE(softwareEnforced.Contains(TAG_KEY_SIZE, key_size)); - } - - EXPECT_EQ(ErrorCode::OK, DeleteKey(&key_blob)); - } -} - -/* - * NewKeyGenerationTest.HmacCheckKeySizes - * - * Verifies that keymaster supports all key sizes, and rejects all invalid key sizes. - */ -TEST_F(NewKeyGenerationTest, HmacCheckKeySizes) { - for (size_t key_size = 0; key_size <= 512; ++key_size) { - if (key_size < 64 || key_size % 8 != 0) { - // To keep this test from being very slow, we only test a random fraction of non-byte - // key sizes. We test only ~10% of such cases. Since there are 392 of them, we expect - // to run ~40 of them in each run. - if (key_size % 8 == 0 || random() % 10 == 0) { - EXPECT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE, - GenerateKey(AuthorizationSetBuilder() - .HmacKey(key_size) - .Digest(Digest::SHA_2_256) - .Authorization(TAG_MIN_MAC_LENGTH, 256))) - << "HMAC key size " << key_size << " invalid (Possibly b/33462346)"; - } - } else { - EXPECT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .HmacKey(key_size) - .Digest(Digest::SHA_2_256) - .Authorization(TAG_MIN_MAC_LENGTH, 256))); - DeleteKey(); - } - } -} - -/* - * NewKeyGenerationTest.HmacCheckMinMacLengths - * - * Verifies that keymaster supports all required MAC lengths and rejects all invalid lengths. This - * test is probabilistic in order to keep the runtime down, but any failure prints out the specific - * MAC length that failed, so reproducing a failed run will be easy. - */ -TEST_F(NewKeyGenerationTest, HmacCheckMinMacLengths) { - for (size_t min_mac_length = 0; min_mac_length <= 256; ++min_mac_length) { - if (min_mac_length < 64 || min_mac_length % 8 != 0) { - // To keep this test from being very long, we only test a random fraction of non-byte - // lengths. We test only ~10% of such cases. Since there are 172 of them, we expect to - // run ~17 of them in each run. - if (min_mac_length % 8 == 0 || random() % 10 == 0) { - EXPECT_EQ(ErrorCode::UNSUPPORTED_MIN_MAC_LENGTH, - GenerateKey(AuthorizationSetBuilder() - .HmacKey(128) - .Digest(Digest::SHA_2_256) - .Authorization(TAG_MIN_MAC_LENGTH, min_mac_length))) - << "HMAC min mac length " << min_mac_length << " invalid."; - } - } else { - EXPECT_EQ(ErrorCode::OK, - GenerateKey(AuthorizationSetBuilder() - .HmacKey(128) - .Digest(Digest::SHA_2_256) - .Authorization(TAG_MIN_MAC_LENGTH, min_mac_length))); - DeleteKey(); - } - } -} - -/* - * NewKeyGenerationTest.HmacMultipleDigests - * - * Verifies that keymaster rejects HMAC key generation with multiple specified digest algorithms. - */ -TEST_F(NewKeyGenerationTest, HmacMultipleDigests) { - ASSERT_EQ(ErrorCode::UNSUPPORTED_DIGEST, - GenerateKey(AuthorizationSetBuilder() - .HmacKey(128) - .Digest(Digest::SHA1) - .Digest(Digest::SHA_2_256) - .Authorization(TAG_MIN_MAC_LENGTH, 128))); -} - -/* - * NewKeyGenerationTest.HmacDigestNone - * - * Verifies that keymaster rejects HMAC key generation with no digest or Digest::NONE - */ -TEST_F(NewKeyGenerationTest, HmacDigestNone) { - ASSERT_EQ( - ErrorCode::UNSUPPORTED_DIGEST, - GenerateKey(AuthorizationSetBuilder().HmacKey(128).Authorization(TAG_MIN_MAC_LENGTH, 128))); - - ASSERT_EQ(ErrorCode::UNSUPPORTED_DIGEST, - GenerateKey(AuthorizationSetBuilder() - .HmacKey(128) - .Digest(Digest::NONE) - .Authorization(TAG_MIN_MAC_LENGTH, 128))); -} - -typedef KeymasterHidlTest GetKeyCharacteristicsTest; - -/* - * GetKeyCharacteristicsTest.HmacDigestNone - * - * Verifies that getKeyCharacteristics functions, and that generated and retrieved key - * characteristics match. - */ -TEST_F(GetKeyCharacteristicsTest, SimpleRsa) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .RsaSigningKey(256, 3) - .Digest(Digest::NONE) - .Padding(PaddingMode::NONE))); - - KeyCharacteristics retrieved_chars; - ASSERT_EQ(ErrorCode::OK, GetCharacteristics(key_blob_, &retrieved_chars)); - - AuthorizationSet gen_sw = key_characteristics_.softwareEnforced; - AuthorizationSet gen_tee = key_characteristics_.teeEnforced; - AuthorizationSet retrieved_sw = retrieved_chars.softwareEnforced; - AuthorizationSet retrieved_tee = retrieved_chars.teeEnforced; - - EXPECT_EQ(gen_sw, retrieved_sw); - EXPECT_EQ(gen_tee, retrieved_tee); -} - -typedef KeymasterHidlTest SigningOperationsTest; - -/* - * SigningOperationsTest.RsaSuccess - * - * Verifies that raw RSA signature operations succeed. - */ -TEST_F(SigningOperationsTest, RsaSuccess) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .RsaSigningKey(1024, 3) - .Digest(Digest::NONE) - .Padding(PaddingMode::NONE) - .Authorization(TAG_NO_AUTH_REQUIRED))); - string message = "12345678901234567890123456789012"; - string signature = SignMessage( - message, AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE)); -} - -/* - * SigningOperationsTest.RsaPssSha256Success - * - * Verifies that RSA-PSS signature operations succeed. - */ -TEST_F(SigningOperationsTest, RsaPssSha256Success) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .RsaSigningKey(1024, 3) - .Digest(Digest::SHA_2_256) - .Padding(PaddingMode::RSA_PSS) - .Authorization(TAG_NO_AUTH_REQUIRED))); - // Use large message, which won't work without digesting. - string message(1024, 'a'); - string signature = SignMessage( - message, AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Padding(PaddingMode::RSA_PSS)); -} - -/* - * SigningOperationsTest.RsaPaddingNoneDoesNotAllowOther - * - * Verifies that keymaster rejects signature operations that specify a padding mode when the key - * supports only unpadded operations. - */ -TEST_F(SigningOperationsTest, RsaPaddingNoneDoesNotAllowOther) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .RsaSigningKey(1024, 3) - .Digest(Digest::NONE) - .Authorization(TAG_NO_AUTH_REQUIRED) - .Padding(PaddingMode::NONE))); - string message = "12345678901234567890123456789012"; - string signature; - - EXPECT_EQ(ErrorCode::INCOMPATIBLE_PADDING_MODE, - Begin(KeyPurpose::SIGN, AuthorizationSetBuilder() - .Digest(Digest::NONE) - .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN))); -} - -/* - * SigningOperationsTest.RsaPkcs1Sha256Success - * - * Verifies that digested RSA-PKCS1 signature operations succeed. - */ -TEST_F(SigningOperationsTest, RsaPkcs1Sha256Success) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .RsaSigningKey(1024, 3) - .Digest(Digest::SHA_2_256) - .Authorization(TAG_NO_AUTH_REQUIRED) - .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN))); - string message(1024, 'a'); - string signature = SignMessage(message, AuthorizationSetBuilder() - .Digest(Digest::SHA_2_256) - .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)); -} - -/* - * SigningOperationsTest.RsaPkcs1NoDigestSuccess - * - * Verifies that undigested RSA-PKCS1 signature operations succeed. - */ -TEST_F(SigningOperationsTest, RsaPkcs1NoDigestSuccess) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .RsaSigningKey(1024, 3) - .Digest(Digest::NONE) - .Authorization(TAG_NO_AUTH_REQUIRED) - .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN))); - string message(53, 'a'); - string signature = SignMessage( - message, - AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)); -} - -/* - * SigningOperationsTest.RsaPkcs1NoDigestTooLarge - * - * Verifies that undigested RSA-PKCS1 signature operations fail with the correct error code when - * given a too-long message. - */ -TEST_F(SigningOperationsTest, RsaPkcs1NoDigestTooLong) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .RsaSigningKey(1024, 3) - .Digest(Digest::NONE) - .Authorization(TAG_NO_AUTH_REQUIRED) - .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN))); - string message(129, 'a'); - - EXPECT_EQ(ErrorCode::OK, - Begin(KeyPurpose::SIGN, AuthorizationSetBuilder() - .Digest(Digest::NONE) - .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN))); - string signature; - EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, Finish(message, &signature)); -} - -/* - * SigningOperationsTest.RsaPssSha512TooSmallKey - * - * Verifies that undigested RSA-PSS signature operations fail with the correct error code when - * used with a key that is too small for the message. - * - * A PSS-padded message is of length salt_size + digest_size + 16 (sizes in bits), and the keymaster - * specification requires that salt_size == digest_size, so the message will be digest_size * 2 + - * 16. Such a message can only be signed by a given key if the key is at least that size. This test - * uses SHA512, which has a digest_size == 512, so the message size is 1040 bits, too large for a - * 1024-bit key. - */ -TEST_F(SigningOperationsTest, RsaPssSha512TooSmallKey) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .RsaSigningKey(1024, 3) - .Digest(Digest::SHA_2_512) - .Authorization(TAG_NO_AUTH_REQUIRED) - .Padding(PaddingMode::RSA_PSS))); - EXPECT_EQ( - ErrorCode::INCOMPATIBLE_DIGEST, - Begin(KeyPurpose::SIGN, - AuthorizationSetBuilder().Digest(Digest::SHA_2_512).Padding(PaddingMode::RSA_PSS))) - << "(Possibly b/33346750)"; -} - -/* - * SigningOperationsTest.RsaNoPaddingTooLong - * - * Verifies that raw RSA signature operations fail with the correct error code when - * given a too-long message. - */ -TEST_F(SigningOperationsTest, RsaNoPaddingTooLong) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .RsaSigningKey(1024, 3) - .Digest(Digest::NONE) - .Authorization(TAG_NO_AUTH_REQUIRED) - .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN))); - // One byte too long - string message(1024 / 8 + 1, 'a'); - ASSERT_EQ(ErrorCode::OK, - Begin(KeyPurpose::SIGN, AuthorizationSetBuilder() - .Digest(Digest::NONE) - .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN))); - string result; - EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, Finish(message, &result)); - - // Very large message that should exceed the transfer buffer size of any reasonable TEE. - message = string(128 * 1024, 'a'); - ASSERT_EQ(ErrorCode::OK, - Begin(KeyPurpose::SIGN, AuthorizationSetBuilder() - .Digest(Digest::NONE) - .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN))); - EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, Finish(message, &result)); -} - -/* - * SigningOperationsTest.RsaAbort - * - * Verifies that operations can be aborted correctly. Uses an RSA signing operation for the test, - * but the behavior should be algorithm and purpose-independent. - */ -TEST_F(SigningOperationsTest, RsaAbort) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .RsaSigningKey(1024, 3) - .Digest(Digest::NONE) - .Authorization(TAG_NO_AUTH_REQUIRED) - .Padding(PaddingMode::NONE))); - - ASSERT_EQ(ErrorCode::OK, - Begin(KeyPurpose::SIGN, - AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE))); - EXPECT_EQ(ErrorCode::OK, Abort(op_handle_)); - - // Another abort should fail - EXPECT_EQ(ErrorCode::INVALID_OPERATION_HANDLE, Abort(op_handle_)); - - // Set to sentinel, so TearDown() doesn't try to abort again. - op_handle_ = kOpHandleSentinel; -} - -/* - * SigningOperationsTest.RsaUnsupportedPadding - * - * Verifies that RSA operations fail with the correct error (but key gen succeeds) when used with a - * padding mode inappropriate for RSA. - */ -TEST_F(SigningOperationsTest, RsaUnsupportedPadding) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .RsaSigningKey(1024, 3) - .Authorization(TAG_NO_AUTH_REQUIRED) - .Digest(Digest::SHA_2_256 /* supported digest */) - .Padding(PaddingMode::PKCS7))); - ASSERT_EQ( - ErrorCode::UNSUPPORTED_PADDING_MODE, - Begin(KeyPurpose::SIGN, - AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Padding(PaddingMode::PKCS7))); -} - -/* - * SigningOperationsTest.RsaPssNoDigest - * - * Verifies that RSA PSS operations fail when no digest is used. PSS requires a digest. - */ -TEST_F(SigningOperationsTest, RsaNoDigest) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .RsaSigningKey(1024, 3) - .Authorization(TAG_NO_AUTH_REQUIRED) - .Digest(Digest::NONE) - .Padding(PaddingMode::RSA_PSS))); - ASSERT_EQ(ErrorCode::INCOMPATIBLE_DIGEST, - Begin(KeyPurpose::SIGN, - AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::RSA_PSS))); - - ASSERT_EQ(ErrorCode::UNSUPPORTED_DIGEST, - Begin(KeyPurpose::SIGN, AuthorizationSetBuilder().Padding(PaddingMode::RSA_PSS))); -} - -/* - * SigningOperationsTest.RsaPssNoDigest - * - * Verifies that RSA operations fail when no padding mode is specified. PaddingMode::NONE is - * supported in some cases (as validated in other tests), but a mode must be specified. - */ -TEST_F(SigningOperationsTest, RsaNoPadding) { - // Padding must be specified - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .RsaKey(1024, 3) - .Authorization(TAG_NO_AUTH_REQUIRED) - .SigningKey() - .Digest(Digest::NONE))); - ASSERT_EQ(ErrorCode::UNSUPPORTED_PADDING_MODE, - Begin(KeyPurpose::SIGN, AuthorizationSetBuilder().Digest(Digest::NONE))); -} - -/* - * SigningOperationsTest.RsaShortMessage - * - * Verifies that raw RSA signatures succeed with a message shorter than the key size. - */ -TEST_F(SigningOperationsTest, RsaTooShortMessage) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaSigningKey(1024, 3) - .Digest(Digest::NONE) - .Padding(PaddingMode::NONE))); - - // Barely shorter - string message(1024 / 8 - 1, 'a'); - SignMessage(message, AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE)); - - // Much shorter - message = "a"; - SignMessage(message, AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE)); -} - -/* - * SigningOperationsTest.RsaSignWithEncryptionKey - * - * Verifies that RSA encryption keys cannot be used to sign. - */ -TEST_F(SigningOperationsTest, RsaSignWithEncryptionKey) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaEncryptionKey(1024, 3) - .Digest(Digest::NONE) - .Padding(PaddingMode::NONE))); - ASSERT_EQ(ErrorCode::INCOMPATIBLE_PURPOSE, - Begin(KeyPurpose::SIGN, - AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE))); -} - -/* - * SigningOperationsTest.RsaSignTooLargeMessage - * - * Verifies that attempting a raw signature of a message which is the same length as the key, but - * numerically larger than the public modulus, fails with the correct error. - */ -TEST_F(SigningOperationsTest, RsaSignTooLargeMessage) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaSigningKey(1024, 3) - .Digest(Digest::NONE) - .Padding(PaddingMode::NONE))); - - // Largest possible message will always be larger than the public modulus. - string message(1024 / 8, static_cast(0xff)); - ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .Digest(Digest::NONE) - .Padding(PaddingMode::NONE))); - string signature; - ASSERT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(message, &signature)); -} - -/* - * SigningOperationsTest.EcdsaAllSizesAndHashes - * - * Verifies that ECDSA operations succeed with all possible key sizes and hashes. - */ -TEST_F(SigningOperationsTest, EcdsaAllSizesAndHashes) { - for (auto key_size : {224, 256, 384, 521}) { - for (auto digest : { - Digest::SHA1, Digest::SHA_2_224, Digest::SHA_2_256, Digest::SHA_2_384, - Digest::SHA_2_512, - }) { - ErrorCode error = GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(key_size) - .Digest(digest)); - EXPECT_EQ(ErrorCode::OK, error) << "Failed to generate ECDSA key with size " << key_size - << " and digest " << digest; - if (error != ErrorCode::OK) continue; - - string message(1024, 'a'); - if (digest == Digest::NONE) message.resize(key_size / 8); - SignMessage(message, AuthorizationSetBuilder().Digest(digest)); - DeleteKey(); - } - } -} - -/* - * SigningOperationsTest.EcdsaAllCurves - * - * Verifies that ECDSA operations succeed with all possible curves. - */ -TEST_F(SigningOperationsTest, EcdsaAllCurves) { - for (auto curve : {EcCurve::P_224, EcCurve::P_256, EcCurve::P_384, EcCurve::P_521}) { - ErrorCode error = GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(curve) - .Digest(Digest::SHA_2_256)); - EXPECT_EQ(ErrorCode::OK, error) << "Failed to generate ECDSA key with curve " << curve; - if (error != ErrorCode::OK) continue; - - string message(1024, 'a'); - SignMessage(message, AuthorizationSetBuilder().Digest(Digest::SHA_2_256)); - DeleteKey(); - } -} - -/* - * SigningOperationsTest.EcdsaNoDigestHugeData - * - * Verifies that ECDSA operations support very large messages, even without digesting. This should - * work because ECDSA actually only signs the leftmost L_n bits of the message, however large it may - * be. Not using digesting is a bad idea, but in some cases digesting is done by the framework. - */ -TEST_F(SigningOperationsTest, EcdsaNoDigestHugeData) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(224) - .Digest(Digest::NONE))); - string message(64 * 1024, 'a'); - SignMessage(message, AuthorizationSetBuilder().Digest(Digest::NONE)); -} - -/* - * SigningOperationsTest.AesEcbSign - * - * Verifies that attempts to use AES keys to sign fail in the correct way. - */ -TEST_F(SigningOperationsTest, AesEcbSign) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .SigningKey() - .AesEncryptionKey(128) - .Authorization(TAG_BLOCK_MODE, BlockMode::ECB))) - << "(Possibly b/36252957)"; - - AuthorizationSet out_params; - EXPECT_EQ(ErrorCode::UNSUPPORTED_PURPOSE, - Begin(KeyPurpose::SIGN, AuthorizationSet() /* in_params */, &out_params)) - << "(Possibly b/36233187)"; - - EXPECT_EQ(ErrorCode::UNSUPPORTED_PURPOSE, - Begin(KeyPurpose::VERIFY, AuthorizationSet() /* in_params */, &out_params)) - << "(Possibly b/36233187)"; -} - -/* - * SigningOperationsTest.HmacAllDigests - * - * Verifies that HMAC works with all digests. - */ -TEST_F(SigningOperationsTest, HmacAllDigests) { - for (auto digest : {Digest::SHA1, Digest::SHA_2_224, Digest::SHA_2_256, Digest::SHA_2_384, - Digest::SHA_2_512}) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .HmacKey(128) - .Digest(digest) - .Authorization(TAG_MIN_MAC_LENGTH, 160))) - << "Failed to create HMAC key with digest " << digest; - string message = "12345678901234567890123456789012"; - string signature = MacMessage(message, digest, 160); - EXPECT_EQ(160U / 8U, signature.size()) - << "Failed to sign with HMAC key with digest " << digest; - DeleteKey(); - } -} - -/* - * SigningOperationsTest.HmacSha256TooLargeMacLength - * - * Verifies that HMAC fails in the correct way when asked to generate a MAC larger than the digest - * size. - */ -TEST_F(SigningOperationsTest, HmacSha256TooLargeMacLength) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .HmacKey(128) - .Digest(Digest::SHA_2_256) - .Authorization(TAG_MIN_MAC_LENGTH, 256))); - AuthorizationSet output_params; - EXPECT_EQ( - ErrorCode::UNSUPPORTED_MAC_LENGTH, - Begin( - KeyPurpose::SIGN, key_blob_, - AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Authorization(TAG_MAC_LENGTH, 264), - &output_params, &op_handle_)); -} - -/* - * SigningOperationsTest.HmacSha256TooSmallMacLength - * - * Verifies that HMAC fails in the correct way when asked to generate a MAC smaller than the - * specified minimum MAC length. - */ -TEST_F(SigningOperationsTest, HmacSha256TooSmallMacLength) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .HmacKey(128) - .Digest(Digest::SHA_2_256) - .Authorization(TAG_MIN_MAC_LENGTH, 128))); - AuthorizationSet output_params; - EXPECT_EQ( - ErrorCode::INVALID_MAC_LENGTH, - Begin( - KeyPurpose::SIGN, key_blob_, - AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Authorization(TAG_MAC_LENGTH, 120), - &output_params, &op_handle_)); -} - -/* - * SigningOperationsTest.HmacRfc4231TestCase3 - * - * Validates against the test vectors from RFC 4231 test case 3. - */ -TEST_F(SigningOperationsTest, HmacRfc4231TestCase3) { - string key(20, 0xaa); - string message(50, 0xdd); - uint8_t sha_224_expected[] = { - 0x7f, 0xb3, 0xcb, 0x35, 0x88, 0xc6, 0xc1, 0xf6, 0xff, 0xa9, 0x69, 0x4d, 0x7d, 0x6a, - 0xd2, 0x64, 0x93, 0x65, 0xb0, 0xc1, 0xf6, 0x5d, 0x69, 0xd1, 0xec, 0x83, 0x33, 0xea, - }; - uint8_t sha_256_expected[] = { - 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46, 0x85, 0x4d, 0xb8, - 0xeb, 0xd0, 0x91, 0x81, 0xa7, 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, - 0xc1, 0x22, 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe, - }; - uint8_t sha_384_expected[] = { - 0x88, 0x06, 0x26, 0x08, 0xd3, 0xe6, 0xad, 0x8a, 0x0a, 0xa2, 0xac, 0xe0, - 0x14, 0xc8, 0xa8, 0x6f, 0x0a, 0xa6, 0x35, 0xd9, 0x47, 0xac, 0x9f, 0xeb, - 0xe8, 0x3e, 0xf4, 0xe5, 0x59, 0x66, 0x14, 0x4b, 0x2a, 0x5a, 0xb3, 0x9d, - 0xc1, 0x38, 0x14, 0xb9, 0x4e, 0x3a, 0xb6, 0xe1, 0x01, 0xa3, 0x4f, 0x27, - }; - uint8_t sha_512_expected[] = { - 0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84, 0xef, 0xb0, 0xf0, 0x75, 0x6c, - 0x89, 0x0b, 0xe9, 0xb1, 0xb5, 0xdb, 0xdd, 0x8e, 0xe8, 0x1a, 0x36, 0x55, 0xf8, - 0x3e, 0x33, 0xb2, 0x27, 0x9d, 0x39, 0xbf, 0x3e, 0x84, 0x82, 0x79, 0xa7, 0x22, - 0xc8, 0x06, 0xb4, 0x85, 0xa4, 0x7e, 0x67, 0xc8, 0x07, 0xb9, 0x46, 0xa3, 0x37, - 0xbe, 0xe8, 0x94, 0x26, 0x74, 0x27, 0x88, 0x59, 0xe1, 0x32, 0x92, 0xfb, - }; - - CheckHmacTestVector(key, message, Digest::SHA_2_224, make_string(sha_224_expected)); - CheckHmacTestVector(key, message, Digest::SHA_2_256, make_string(sha_256_expected)); - CheckHmacTestVector(key, message, Digest::SHA_2_384, make_string(sha_384_expected)); - CheckHmacTestVector(key, message, Digest::SHA_2_512, make_string(sha_512_expected)); -} - -/* - * SigningOperationsTest.HmacRfc4231TestCase5 - * - * Validates against the test vectors from RFC 4231 test case 5. - */ -TEST_F(SigningOperationsTest, HmacRfc4231TestCase5) { - string key(20, 0x0c); - string message = "Test With Truncation"; - - uint8_t sha_224_expected[] = { - 0x0e, 0x2a, 0xea, 0x68, 0xa9, 0x0c, 0x8d, 0x37, - 0xc9, 0x88, 0xbc, 0xdb, 0x9f, 0xca, 0x6f, 0xa8, - }; - uint8_t sha_256_expected[] = { - 0xa3, 0xb6, 0x16, 0x74, 0x73, 0x10, 0x0e, 0xe0, - 0x6e, 0x0c, 0x79, 0x6c, 0x29, 0x55, 0x55, 0x2b, - }; - uint8_t sha_384_expected[] = { - 0x3a, 0xbf, 0x34, 0xc3, 0x50, 0x3b, 0x2a, 0x23, - 0xa4, 0x6e, 0xfc, 0x61, 0x9b, 0xae, 0xf8, 0x97, - }; - uint8_t sha_512_expected[] = { - 0x41, 0x5f, 0xad, 0x62, 0x71, 0x58, 0x0a, 0x53, - 0x1d, 0x41, 0x79, 0xbc, 0x89, 0x1d, 0x87, 0xa6, - }; - - CheckHmacTestVector(key, message, Digest::SHA_2_224, make_string(sha_224_expected)); - CheckHmacTestVector(key, message, Digest::SHA_2_256, make_string(sha_256_expected)); - CheckHmacTestVector(key, message, Digest::SHA_2_384, make_string(sha_384_expected)); - CheckHmacTestVector(key, message, Digest::SHA_2_512, make_string(sha_512_expected)); -} - -/* - * SigningOperationsTest.HmacRfc4231TestCase6 - * - * Validates against the test vectors from RFC 4231 test case 6. - */ -TEST_F(SigningOperationsTest, HmacRfc4231TestCase6) { - string key(131, 0xaa); - string message = "Test Using Larger Than Block-Size Key - Hash Key First"; - - uint8_t sha_224_expected[] = { - 0x95, 0xe9, 0xa0, 0xdb, 0x96, 0x20, 0x95, 0xad, 0xae, 0xbe, 0x9b, 0x2d, 0x6f, 0x0d, - 0xbc, 0xe2, 0xd4, 0x99, 0xf1, 0x12, 0xf2, 0xd2, 0xb7, 0x27, 0x3f, 0xa6, 0x87, 0x0e, - }; - uint8_t sha_256_expected[] = { - 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, 0x0d, 0x8a, 0x26, - 0xaa, 0xcb, 0xf5, 0xb7, 0x7f, 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, - 0xc5, 0x14, 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54, - }; - uint8_t sha_384_expected[] = { - 0x4e, 0xce, 0x08, 0x44, 0x85, 0x81, 0x3e, 0x90, 0x88, 0xd2, 0xc6, 0x3a, - 0x04, 0x1b, 0xc5, 0xb4, 0x4f, 0x9e, 0xf1, 0x01, 0x2a, 0x2b, 0x58, 0x8f, - 0x3c, 0xd1, 0x1f, 0x05, 0x03, 0x3a, 0xc4, 0xc6, 0x0c, 0x2e, 0xf6, 0xab, - 0x40, 0x30, 0xfe, 0x82, 0x96, 0x24, 0x8d, 0xf1, 0x63, 0xf4, 0x49, 0x52, - }; - uint8_t sha_512_expected[] = { - 0x80, 0xb2, 0x42, 0x63, 0xc7, 0xc1, 0xa3, 0xeb, 0xb7, 0x14, 0x93, 0xc1, 0xdd, - 0x7b, 0xe8, 0xb4, 0x9b, 0x46, 0xd1, 0xf4, 0x1b, 0x4a, 0xee, 0xc1, 0x12, 0x1b, - 0x01, 0x37, 0x83, 0xf8, 0xf3, 0x52, 0x6b, 0x56, 0xd0, 0x37, 0xe0, 0x5f, 0x25, - 0x98, 0xbd, 0x0f, 0xd2, 0x21, 0x5d, 0x6a, 0x1e, 0x52, 0x95, 0xe6, 0x4f, 0x73, - 0xf6, 0x3f, 0x0a, 0xec, 0x8b, 0x91, 0x5a, 0x98, 0x5d, 0x78, 0x65, 0x98, - }; - - CheckHmacTestVector(key, message, Digest::SHA_2_224, make_string(sha_224_expected)); - CheckHmacTestVector(key, message, Digest::SHA_2_256, make_string(sha_256_expected)); - CheckHmacTestVector(key, message, Digest::SHA_2_384, make_string(sha_384_expected)); - CheckHmacTestVector(key, message, Digest::SHA_2_512, make_string(sha_512_expected)); -} - -/* - * SigningOperationsTest.HmacRfc4231TestCase7 - * - * Validates against the test vectors from RFC 4231 test case 7. - */ -TEST_F(SigningOperationsTest, HmacRfc4231TestCase7) { - string key(131, 0xaa); - string message = "This is a test using a larger than block-size key and a larger than " - "block-size data. The key needs to be hashed before being used by the HMAC " - "algorithm."; - - uint8_t sha_224_expected[] = { - 0x3a, 0x85, 0x41, 0x66, 0xac, 0x5d, 0x9f, 0x02, 0x3f, 0x54, 0xd5, 0x17, 0xd0, 0xb3, - 0x9d, 0xbd, 0x94, 0x67, 0x70, 0xdb, 0x9c, 0x2b, 0x95, 0xc9, 0xf6, 0xf5, 0x65, 0xd1, - }; - uint8_t sha_256_expected[] = { - 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb, 0x27, 0x63, 0x5f, - 0xbc, 0xd5, 0xb0, 0xe9, 0x44, 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, - 0x13, 0x93, 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2, - }; - uint8_t sha_384_expected[] = { - 0x66, 0x17, 0x17, 0x8e, 0x94, 0x1f, 0x02, 0x0d, 0x35, 0x1e, 0x2f, 0x25, - 0x4e, 0x8f, 0xd3, 0x2c, 0x60, 0x24, 0x20, 0xfe, 0xb0, 0xb8, 0xfb, 0x9a, - 0xdc, 0xce, 0xbb, 0x82, 0x46, 0x1e, 0x99, 0xc5, 0xa6, 0x78, 0xcc, 0x31, - 0xe7, 0x99, 0x17, 0x6d, 0x38, 0x60, 0xe6, 0x11, 0x0c, 0x46, 0x52, 0x3e, - }; - uint8_t sha_512_expected[] = { - 0xe3, 0x7b, 0x6a, 0x77, 0x5d, 0xc8, 0x7d, 0xba, 0xa4, 0xdf, 0xa9, 0xf9, 0x6e, - 0x5e, 0x3f, 0xfd, 0xde, 0xbd, 0x71, 0xf8, 0x86, 0x72, 0x89, 0x86, 0x5d, 0xf5, - 0xa3, 0x2d, 0x20, 0xcd, 0xc9, 0x44, 0xb6, 0x02, 0x2c, 0xac, 0x3c, 0x49, 0x82, - 0xb1, 0x0d, 0x5e, 0xeb, 0x55, 0xc3, 0xe4, 0xde, 0x15, 0x13, 0x46, 0x76, 0xfb, - 0x6d, 0xe0, 0x44, 0x60, 0x65, 0xc9, 0x74, 0x40, 0xfa, 0x8c, 0x6a, 0x58, - }; - - CheckHmacTestVector(key, message, Digest::SHA_2_224, make_string(sha_224_expected)); - CheckHmacTestVector(key, message, Digest::SHA_2_256, make_string(sha_256_expected)); - CheckHmacTestVector(key, message, Digest::SHA_2_384, make_string(sha_384_expected)); - CheckHmacTestVector(key, message, Digest::SHA_2_512, make_string(sha_512_expected)); -} - -typedef KeymasterHidlTest VerificationOperationsTest; - -/* - * VerificationOperationsTest.RsaSuccess - * - * Verifies that a simple RSA signature/verification sequence succeeds. - */ -TEST_F(VerificationOperationsTest, RsaSuccess) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaSigningKey(1024, 3) - .Digest(Digest::NONE) - .Padding(PaddingMode::NONE))); - string message = "12345678901234567890123456789012"; - string signature = SignMessage( - message, AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE)); - VerifyMessage(message, signature, - AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE)); -} - -/* - * VerificationOperationsTest.RsaSuccess - * - * Verifies RSA signature/verification for all padding modes and digests. - */ -TEST_F(VerificationOperationsTest, RsaAllPaddingsAndDigests) { - Digest digest = Digest::SHA_2_256; - ASSERT_EQ(ErrorCode::OK, - GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaSigningKey(2048, 3) - .Digest(Digest::NONE, Digest::MD5, Digest::SHA1, Digest::SHA_2_224, - Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512) - .Padding(PaddingMode::NONE) - .Padding(PaddingMode::RSA_PSS) - .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN))); - - string message(128, 'a'); - string corrupt_message(message); - ++corrupt_message[corrupt_message.size() / 2]; - - for (auto padding : - {PaddingMode::NONE, PaddingMode::RSA_PSS, PaddingMode::RSA_PKCS1_1_5_SIGN}) { - - for (auto digest : {Digest::NONE, Digest::MD5, Digest::SHA1, Digest::SHA_2_224, - Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512}) { - if (padding == PaddingMode::NONE && digest != Digest::NONE) { - // Digesting only makes sense with padding. - continue; - } - - if (padding == PaddingMode::RSA_PSS && digest == Digest::NONE) { - // PSS requires digesting. - continue; - } - - string signature = - SignMessage(message, AuthorizationSetBuilder().Digest(digest).Padding(padding)); - VerifyMessage(message, signature, - AuthorizationSetBuilder().Digest(digest).Padding(padding)); - - if (digest != Digest::NONE) { - // Verify with OpenSSL. - HidlBuf pubkey; - ASSERT_EQ(ErrorCode::OK, ExportKey(KeyFormat::X509, &pubkey)); - - const uint8_t* p = pubkey.data(); - EVP_PKEY_Ptr pkey(d2i_PUBKEY(nullptr /* alloc new */, &p, pubkey.size())); - ASSERT_TRUE(pkey.get()); - - EVP_MD_CTX digest_ctx; - EVP_MD_CTX_init(&digest_ctx); - EVP_PKEY_CTX* pkey_ctx; - const EVP_MD* md = openssl_digest(digest); - ASSERT_NE(md, nullptr); - EXPECT_EQ(1, EVP_DigestVerifyInit(&digest_ctx, &pkey_ctx, md, nullptr /* engine */, - pkey.get())); - - switch (padding) { - case PaddingMode::RSA_PSS: - EXPECT_GT(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING), 0); - EXPECT_GT(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, EVP_MD_size(md)), 0); - break; - case PaddingMode::RSA_PKCS1_1_5_SIGN: - // PKCS1 is the default; don't need to set anything. - break; - default: - FAIL(); - break; - } - - EXPECT_EQ(1, EVP_DigestVerifyUpdate(&digest_ctx, message.data(), message.size())); - EXPECT_EQ(1, EVP_DigestVerifyFinal( - &digest_ctx, reinterpret_cast(signature.data()), - signature.size())); - EVP_MD_CTX_cleanup(&digest_ctx); - } - - // Corrupt signature shouldn't verify. - string corrupt_signature(signature); - ++corrupt_signature[corrupt_signature.size() / 2]; - - EXPECT_EQ(ErrorCode::OK, - Begin(KeyPurpose::VERIFY, - AuthorizationSetBuilder().Digest(digest).Padding(padding))); - string result; - EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(message, corrupt_signature, &result)); - - // Corrupt message shouldn't verify - EXPECT_EQ(ErrorCode::OK, - Begin(KeyPurpose::VERIFY, - AuthorizationSetBuilder().Digest(digest).Padding(padding))); - EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(corrupt_message, signature, &result)); - } - } -} - -/* - * VerificationOperationsTest.RsaSuccess - * - * Verifies ECDSA signature/verification for all digests and curves. - */ -TEST_F(VerificationOperationsTest, EcdsaAllDigestsAndCurves) { - auto digests = { - Digest::NONE, Digest::SHA1, Digest::SHA_2_224, - Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512, - }; - - string message = "1234567890"; - string corrupt_message = "2234567890"; - for (auto curve : {EcCurve::P_224, EcCurve::P_256, EcCurve::P_384, EcCurve::P_521}) { - ErrorCode error = GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(curve) - .Digest(digests)); - EXPECT_EQ(ErrorCode::OK, error) << "Failed to generate key for EC curve " << curve; - if (error != ErrorCode::OK) { - continue; - } - - for (auto digest : digests) { - string signature = SignMessage(message, AuthorizationSetBuilder().Digest(digest)); - VerifyMessage(message, signature, AuthorizationSetBuilder().Digest(digest)); - - // Verify with OpenSSL - if (digest != Digest::NONE) { - HidlBuf pubkey; - ASSERT_EQ(ErrorCode::OK, ExportKey(KeyFormat::X509, &pubkey)) - << curve << ' ' << digest; - - const uint8_t* p = pubkey.data(); - EVP_PKEY_Ptr pkey(d2i_PUBKEY(nullptr /* alloc new */, &p, pubkey.size())); - ASSERT_TRUE(pkey.get()); - - EVP_MD_CTX digest_ctx; - EVP_MD_CTX_init(&digest_ctx); - EVP_PKEY_CTX* pkey_ctx; - const EVP_MD* md = openssl_digest(digest); - - EXPECT_EQ(1, EVP_DigestVerifyInit(&digest_ctx, &pkey_ctx, md, nullptr /* engine */, - pkey.get())) - << curve << ' ' << digest; - - EXPECT_EQ(1, EVP_DigestVerifyUpdate(&digest_ctx, message.data(), message.size())) - << curve << ' ' << digest; - - EXPECT_EQ(1, EVP_DigestVerifyFinal( - &digest_ctx, reinterpret_cast(signature.data()), - signature.size())) - << curve << ' ' << digest; - - EVP_MD_CTX_cleanup(&digest_ctx); - } - - // Corrupt signature shouldn't verify. - string corrupt_signature(signature); - ++corrupt_signature[corrupt_signature.size() / 2]; - - EXPECT_EQ(ErrorCode::OK, - Begin(KeyPurpose::VERIFY, AuthorizationSetBuilder().Digest(digest))) - << curve << ' ' << digest; - - string result; - EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(message, corrupt_signature, &result)) - << curve << ' ' << digest; - - // Corrupt message shouldn't verify - EXPECT_EQ(ErrorCode::OK, - Begin(KeyPurpose::VERIFY, AuthorizationSetBuilder().Digest(digest))) - << curve << ' ' << digest; - - EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(corrupt_message, signature, &result)) - << curve << ' ' << digest; - } - - ASSERT_EQ(ErrorCode::OK, DeleteKey()); - } -} - -/* - * VerificationOperationsTest.HmacSigningKeyCannotVerify - * - * Verifies HMAC signing and verification, but that a signing key cannot be used to verify. - */ -TEST_F(VerificationOperationsTest, HmacSigningKeyCannotVerify) { - string key_material = "HelloThisIsAKey"; - - HidlBuf signing_key, verification_key; - KeyCharacteristics signing_key_chars, verification_key_chars; - EXPECT_EQ(ErrorCode::OK, - ImportKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .Authorization(TAG_ALGORITHM, Algorithm::HMAC) - .Authorization(TAG_PURPOSE, KeyPurpose::SIGN) - .Digest(Digest::SHA1) - .Authorization(TAG_MIN_MAC_LENGTH, 160), - KeyFormat::RAW, key_material, &signing_key, &signing_key_chars)); - EXPECT_EQ(ErrorCode::OK, - ImportKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .Authorization(TAG_ALGORITHM, Algorithm::HMAC) - .Authorization(TAG_PURPOSE, KeyPurpose::VERIFY) - .Digest(Digest::SHA1) - .Authorization(TAG_MIN_MAC_LENGTH, 160), - KeyFormat::RAW, key_material, &verification_key, &verification_key_chars)); - - string message = "This is a message."; - string signature = SignMessage( - signing_key, message, - AuthorizationSetBuilder().Digest(Digest::SHA1).Authorization(TAG_MAC_LENGTH, 160)); - - // Signing key should not work. - AuthorizationSet out_params; - EXPECT_EQ(ErrorCode::INCOMPATIBLE_PURPOSE, - Begin(KeyPurpose::VERIFY, signing_key, AuthorizationSetBuilder().Digest(Digest::SHA1), - &out_params, &op_handle_)); - - // Verification key should work. - VerifyMessage(verification_key, message, signature, - AuthorizationSetBuilder().Digest(Digest::SHA1)); - - EXPECT_EQ(ErrorCode::OK, DeleteKey(&signing_key)); - EXPECT_EQ(ErrorCode::OK, DeleteKey(&verification_key)); -} - -typedef KeymasterHidlTest ExportKeyTest; - -/* - * ExportKeyTest.RsaUnsupportedKeyFormat - * - * Verifies that attempting to export RSA keys in PKCS#8 format fails with the correct error. - */ -TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .RsaSigningKey(256, 3) - .Digest(Digest::NONE) - .Padding(PaddingMode::NONE))); - HidlBuf export_data; - ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_FORMAT, ExportKey(KeyFormat::PKCS8, &export_data)); -} - -/* - * ExportKeyTest.RsaCorruptedKeyBlob - * - * Verifies that attempting to export RSA keys from corrupted key blobs fails. This is essentially - * a poor-man's key blob fuzzer. - */ -// Disabled due to b/33385206 -TEST_F(ExportKeyTest, DISABLED_RsaCorruptedKeyBlob) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaSigningKey(256, 3) - .Digest(Digest::NONE) - .Padding(PaddingMode::NONE))); - for (size_t i = 0; i < key_blob_.size(); ++i) { - HidlBuf corrupted(key_blob_); - ++corrupted[i]; - - HidlBuf export_data; - EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, - ExportKey(KeyFormat::X509, corrupted, HidlBuf(), HidlBuf(), &export_data)) - << "Blob corrupted at offset " << i << " erroneously accepted as valid"; - } -} - -/* - * ExportKeyTest.RsaCorruptedKeyBlob - * - * Verifies that attempting to export ECDSA keys from corrupted key blobs fails. This is - * essentially a poor-man's key blob fuzzer. - */ -// Disabled due to b/33385206 -TEST_F(ExportKeyTest, DISABLED_EcCorruptedKeyBlob) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(EcCurve::P_256) - .Digest(Digest::NONE))); - for (size_t i = 0; i < key_blob_.size(); ++i) { - HidlBuf corrupted(key_blob_); - ++corrupted[i]; - - HidlBuf export_data; - EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, - ExportKey(KeyFormat::X509, corrupted, HidlBuf(), HidlBuf(), &export_data)) - << "Blob corrupted at offset " << i << " erroneously accepted as valid"; - } -} - -/* - * ExportKeyTest.AesKeyUnexportable - * - * Verifies that attempting to export AES keys fails in the expected way. - */ -TEST_F(ExportKeyTest, AesKeyUnexportable) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .EcbMode() - .Padding(PaddingMode::NONE))); - - HidlBuf export_data; - EXPECT_EQ(ErrorCode::UNSUPPORTED_KEY_FORMAT, ExportKey(KeyFormat::X509, &export_data)); - EXPECT_EQ(ErrorCode::UNSUPPORTED_KEY_FORMAT, ExportKey(KeyFormat::PKCS8, &export_data)); - EXPECT_EQ(ErrorCode::UNSUPPORTED_KEY_FORMAT, ExportKey(KeyFormat::RAW, &export_data)); -} -typedef KeymasterHidlTest ImportKeyTest; - -/* - * ImportKeyTest.RsaSuccess - * - * Verifies that importing and using an RSA key pair works correctly. - */ -TEST_F(ImportKeyTest, RsaSuccess) { - ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaSigningKey(1024, 65537) - .Digest(Digest::SHA_2_256) - .Padding(PaddingMode::RSA_PSS), - KeyFormat::PKCS8, rsa_key)); - - CheckKm0CryptoParam(TAG_ALGORITHM, Algorithm::RSA); - CheckKm0CryptoParam(TAG_KEY_SIZE, 1024U); - CheckKm0CryptoParam(TAG_RSA_PUBLIC_EXPONENT, 65537U); - CheckKm1CryptoParam(TAG_DIGEST, Digest::SHA_2_256); - CheckKm1CryptoParam(TAG_PADDING, PaddingMode::RSA_PSS); - CheckOrigin(); - - string message(1024 / 8, 'a'); - auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Padding(PaddingMode::RSA_PSS); - string signature = SignMessage(message, params); - VerifyMessage(message, signature, params); -} - -/* - * ImportKeyTest.RsaKeySizeMismatch - * - * Verifies that importing an RSA key pair with a size that doesn't match the key fails in the - * correct way. - */ -TEST_F(ImportKeyTest, RsaKeySizeMismatch) { - ASSERT_EQ(ErrorCode::IMPORT_PARAMETER_MISMATCH, - ImportKey(AuthorizationSetBuilder() - .RsaSigningKey(2048 /* Doesn't match key */, 65537) - .Digest(Digest::NONE) - .Padding(PaddingMode::NONE), - KeyFormat::PKCS8, rsa_key)); -} - -/* - * ImportKeyTest.RsaPublicExponentMismatch - * - * Verifies that importing an RSA key pair with a public exponent that doesn't match the key fails - * in the correct way. - */ -TEST_F(ImportKeyTest, RsaPublicExponentMismatch) { - ASSERT_EQ(ErrorCode::IMPORT_PARAMETER_MISMATCH, - ImportKey(AuthorizationSetBuilder() - .RsaSigningKey(1024, 3 /* Doesn't match key */) - .Digest(Digest::NONE) - .Padding(PaddingMode::NONE), - KeyFormat::PKCS8, rsa_key)); -} - -/* - * ImportKeyTest.EcdsaSuccess - * - * Verifies that importing and using an ECDSA key pair works correctly. - */ -TEST_F(ImportKeyTest, EcdsaSuccess) { - ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(256) - .Digest(Digest::SHA_2_256), - KeyFormat::PKCS8, ec_key)) - << "(Possibly b/33945114)"; - - CheckKm0CryptoParam(TAG_ALGORITHM, Algorithm::EC); - CheckKm0CryptoParam(TAG_KEY_SIZE, 256U); - CheckKm1CryptoParam(TAG_DIGEST, Digest::SHA_2_256); - CheckKm2CryptoParam(TAG_EC_CURVE, EcCurve::P_256); - - CheckOrigin(); - - string message(32, 'a'); - auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256); - string signature = SignMessage(message, params); - VerifyMessage(message, signature, params); -} - -/* - * ImportKeyTest.EcdsaSizeMismatch - * - * Verifies that importing an ECDSA key pair with a size that doesn't match the key fails in the - * correct way. - */ -TEST_F(ImportKeyTest, EcdsaSizeMismatch) { - ASSERT_EQ(ErrorCode::IMPORT_PARAMETER_MISMATCH, - ImportKey(AuthorizationSetBuilder() - .EcdsaSigningKey(224 /* Doesn't match key */) - .Digest(Digest::NONE), - KeyFormat::PKCS8, ec_key)); -} - -/* - * ImportKeyTest.EcdsaCurveMismatch - * - * Verifies that importing an ECDSA key pair with a curve that doesn't match the key fails in the - * correct way. - */ -TEST_F(ImportKeyTest, EcdsaCurveMismatch) { - if (SupportsSymmetric() && !SupportsAttestation()) { - // KM1 hardware doesn't know about curves - return; - } - - ASSERT_EQ(ErrorCode::IMPORT_PARAMETER_MISMATCH, - ImportKey(AuthorizationSetBuilder() - .EcdsaSigningKey(EcCurve::P_224 /* Doesn't match key */) - .Digest(Digest::NONE), - KeyFormat::PKCS8, ec_key)) - << "(Possibly b/36233241)"; -} - -/* - * ImportKeyTest.AesSuccess - * - * Verifies that importing and using an AES key works. - */ -TEST_F(ImportKeyTest, AesSuccess) { - string key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(key.size() * 8) - .EcbMode() - .Padding(PaddingMode::PKCS7), - KeyFormat::RAW, key)); - - CheckKm1CryptoParam(TAG_ALGORITHM, Algorithm::AES); - CheckKm1CryptoParam(TAG_KEY_SIZE, 128U); - CheckKm1CryptoParam(TAG_PADDING, PaddingMode::PKCS7); - CheckKm1CryptoParam(TAG_BLOCK_MODE, BlockMode::ECB); - CheckOrigin(); - - string message = "Hello World!"; - auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7); - string ciphertext = EncryptMessage(message, params); - string plaintext = DecryptMessage(ciphertext, params); - EXPECT_EQ(message, plaintext); -} - -/* - * ImportKeyTest.AesSuccess - * - * Verifies that importing and using an HMAC key works. - */ -TEST_F(ImportKeyTest, HmacKeySuccess) { - string key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .HmacKey(key.size() * 8) - .Digest(Digest::SHA_2_256) - .Authorization(TAG_MIN_MAC_LENGTH, 256), - KeyFormat::RAW, key)); - - CheckKm1CryptoParam(TAG_ALGORITHM, Algorithm::HMAC); - CheckKm1CryptoParam(TAG_KEY_SIZE, 128U); - CheckKm1CryptoParam(TAG_DIGEST, Digest::SHA_2_256); - CheckOrigin(); - - string message = "Hello World!"; - string signature = MacMessage(message, Digest::SHA_2_256, 256); - VerifyMessage(message, signature, AuthorizationSetBuilder().Digest(Digest::SHA_2_256)); -} - -typedef KeymasterHidlTest EncryptionOperationsTest; - -/* - * EncryptionOperationsTest.RsaNoPaddingSuccess - * - * Verifies that raw RSA encryption works. - */ -TEST_F(EncryptionOperationsTest, RsaNoPaddingSuccess) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaEncryptionKey(1024, 3) - .Padding(PaddingMode::NONE))); - - string message = string(1024 / 8, 'a'); - auto params = AuthorizationSetBuilder().Padding(PaddingMode::NONE); - string ciphertext1 = EncryptMessage(message, params); - EXPECT_EQ(1024U / 8, ciphertext1.size()); - - string ciphertext2 = EncryptMessage(message, params); - EXPECT_EQ(1024U / 8, ciphertext2.size()); - - // Unpadded RSA is deterministic - EXPECT_EQ(ciphertext1, ciphertext2); -} - -/* - * EncryptionOperationsTest.RsaNoPaddingShortMessage - * - * Verifies that raw RSA encryption of short messages works. - */ -TEST_F(EncryptionOperationsTest, RsaNoPaddingShortMessage) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaEncryptionKey(1024, 3) - .Padding(PaddingMode::NONE))); - - string message = "1"; - auto params = AuthorizationSetBuilder().Padding(PaddingMode::NONE); - - string ciphertext = EncryptMessage(message, params); - EXPECT_EQ(1024U / 8, ciphertext.size()); - - string expected_plaintext = string(1024 / 8 - 1, 0) + message; - string plaintext = DecryptMessage(ciphertext, params); - - EXPECT_EQ(expected_plaintext, plaintext); - - // Degenerate case, encrypting a numeric 1 yields 0x00..01 as the ciphertext. - message = static_cast(1); - ciphertext = EncryptMessage(message, params); - EXPECT_EQ(1024U / 8, ciphertext.size()); - EXPECT_EQ(ciphertext, string(1024 / 8 - 1, 0) + message); -} - -/* - * EncryptionOperationsTest.RsaNoPaddingTooLong - * - * Verifies that raw RSA encryption of too-long messages fails in the expected way. - */ -TEST_F(EncryptionOperationsTest, RsaNoPaddingTooLong) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaEncryptionKey(1024, 3) - .Padding(PaddingMode::NONE))); - - string message(1024 / 8 + 1, 'a'); - - auto params = AuthorizationSetBuilder().Padding(PaddingMode::NONE); - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params)); - - string result; - EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, Finish(message, &result)); -} - -/* - * EncryptionOperationsTest.RsaNoPaddingTooLong - * - * Verifies that raw RSA encryption of too-large (numerically) messages fails in the expected way. - */ -TEST_F(EncryptionOperationsTest, RsaNoPaddingTooLarge) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaEncryptionKey(1024, 3) - .Padding(PaddingMode::NONE))); - - HidlBuf exported; - ASSERT_EQ(ErrorCode::OK, ExportKey(KeyFormat::X509, &exported)); - - const uint8_t* p = exported.data(); - EVP_PKEY_Ptr pkey(d2i_PUBKEY(nullptr /* alloc new */, &p, exported.size())); - RSA_Ptr rsa(EVP_PKEY_get1_RSA(pkey.get())); - - size_t modulus_len = BN_num_bytes(rsa->n); - ASSERT_EQ(1024U / 8, modulus_len); - std::unique_ptr modulus_buf(new uint8_t[modulus_len]); - BN_bn2bin(rsa->n, modulus_buf.get()); - - // The modulus is too big to encrypt. - string message(reinterpret_cast(modulus_buf.get()), modulus_len); - - auto params = AuthorizationSetBuilder().Padding(PaddingMode::NONE); - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params)); - - string result; - EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(message, &result)); - - // One smaller than the modulus is okay. - BN_sub(rsa->n, rsa->n, BN_value_one()); - modulus_len = BN_num_bytes(rsa->n); - ASSERT_EQ(1024U / 8, modulus_len); - BN_bn2bin(rsa->n, modulus_buf.get()); - message = string(reinterpret_cast(modulus_buf.get()), modulus_len); - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params)); - EXPECT_EQ(ErrorCode::OK, Finish(message, &result)); -} - -/* - * EncryptionOperationsTest.RsaOaepSuccess - * - * Verifies that RSA-OAEP encryption operations work, with all digests. - */ -TEST_F(EncryptionOperationsTest, RsaOaepSuccess) { - auto digests = {Digest::MD5, Digest::SHA1, Digest::SHA_2_224, - Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512}; - - size_t key_size = 2048; // Need largish key for SHA-512 test. - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaEncryptionKey(key_size, 3) - .Padding(PaddingMode::RSA_OAEP) - .Digest(digests))); - - string message = "Hello"; - - for (auto digest : digests) { - auto params = AuthorizationSetBuilder().Digest(digest).Padding(PaddingMode::RSA_OAEP); - string ciphertext1 = EncryptMessage(message, params); - if (HasNonfatalFailure()) std::cout << "-->" << digest << std::endl; - EXPECT_EQ(key_size / 8, ciphertext1.size()); - - string ciphertext2 = EncryptMessage(message, params); - EXPECT_EQ(key_size / 8, ciphertext2.size()); - - // OAEP randomizes padding so every result should be different (with astronomically high - // probability). - EXPECT_NE(ciphertext1, ciphertext2); - - string plaintext1 = DecryptMessage(ciphertext1, params); - EXPECT_EQ(message, plaintext1) << "RSA-OAEP failed with digest " << digest; - string plaintext2 = DecryptMessage(ciphertext2, params); - EXPECT_EQ(message, plaintext2) << "RSA-OAEP failed with digest " << digest; - - // Decrypting corrupted ciphertext should fail. - size_t offset_to_corrupt = random() % ciphertext1.size(); - char corrupt_byte; - do { - corrupt_byte = static_cast(random() % 256); - } while (corrupt_byte == ciphertext1[offset_to_corrupt]); - ciphertext1[offset_to_corrupt] = corrupt_byte; - - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params)); - string result; - EXPECT_EQ(ErrorCode::UNKNOWN_ERROR, Finish(ciphertext1, &result)); - EXPECT_EQ(0U, result.size()); - } -} - -/* - * EncryptionOperationsTest.RsaOaepInvalidDigest - * - * Verifies that RSA-OAEP encryption operations fail in the correct way when asked to operate - * without a digest. - */ -TEST_F(EncryptionOperationsTest, RsaOaepInvalidDigest) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaEncryptionKey(1024, 3) - .Padding(PaddingMode::RSA_OAEP) - .Digest(Digest::NONE))); - string message = "Hello World!"; - - auto params = AuthorizationSetBuilder().Padding(PaddingMode::RSA_OAEP).Digest(Digest::NONE); - EXPECT_EQ(ErrorCode::INCOMPATIBLE_DIGEST, Begin(KeyPurpose::ENCRYPT, params)); -} - -/* - * EncryptionOperationsTest.RsaOaepInvalidDigest - * - * Verifies that RSA-OAEP encryption operations fail in the correct way when asked to decrypt with a - * different digest than was used to encrypt. - */ -TEST_F(EncryptionOperationsTest, RsaOaepDecryptWithWrongDigest) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaEncryptionKey(1024, 3) - .Padding(PaddingMode::RSA_OAEP) - .Digest(Digest::SHA_2_256, Digest::SHA_2_224))); - string message = "Hello World!"; - string ciphertext = EncryptMessage( - message, - AuthorizationSetBuilder().Digest(Digest::SHA_2_224).Padding(PaddingMode::RSA_OAEP)); - - EXPECT_EQ( - ErrorCode::OK, - Begin(KeyPurpose::DECRYPT, - AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Padding(PaddingMode::RSA_OAEP))); - string result; - EXPECT_EQ(ErrorCode::UNKNOWN_ERROR, Finish(ciphertext, &result)); - EXPECT_EQ(0U, result.size()); -} - -/* - * EncryptionOperationsTest.RsaOaepTooLarge - * - * Verifies that RSA-OAEP encryption operations fail in the correct way when asked to encrypt a - * too-large message. - */ -TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaEncryptionKey(1024, 3) - .Padding(PaddingMode::RSA_OAEP) - .Digest(Digest::SHA1))); - constexpr size_t digest_size = 160 /* SHA1 */ / 8; - constexpr size_t oaep_overhead = 2 * digest_size + 2; - string message(1024 / 8 - oaep_overhead + 1, 'a'); - EXPECT_EQ(ErrorCode::OK, - Begin(KeyPurpose::ENCRYPT, - AuthorizationSetBuilder().Padding(PaddingMode::RSA_OAEP).Digest(Digest::SHA1))); - string result; - EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, Finish(message, &result)); - EXPECT_EQ(0U, result.size()); -} - -/* - * EncryptionOperationsTest.RsaPkcs1Success - * - * Verifies that RSA PKCS encryption/decrypts works. - */ -TEST_F(EncryptionOperationsTest, RsaPkcs1Success) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaEncryptionKey(1024, 3) - .Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT))); - - string message = "Hello World!"; - auto params = AuthorizationSetBuilder().Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT); - string ciphertext1 = EncryptMessage(message, params); - EXPECT_EQ(1024U / 8, ciphertext1.size()); - - string ciphertext2 = EncryptMessage(message, params); - EXPECT_EQ(1024U / 8, ciphertext2.size()); - - // PKCS1 v1.5 randomizes padding so every result should be different. - EXPECT_NE(ciphertext1, ciphertext2); - - string plaintext = DecryptMessage(ciphertext1, params); - EXPECT_EQ(message, plaintext); - - // Decrypting corrupted ciphertext should fail. - size_t offset_to_corrupt = random() % ciphertext1.size(); - char corrupt_byte; - do { - corrupt_byte = static_cast(random() % 256); - } while (corrupt_byte == ciphertext1[offset_to_corrupt]); - ciphertext1[offset_to_corrupt] = corrupt_byte; - - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params)); - string result; - EXPECT_EQ(ErrorCode::UNKNOWN_ERROR, Finish(ciphertext1, &result)); - EXPECT_EQ(0U, result.size()); -} - -/* - * EncryptionOperationsTest.RsaPkcs1TooLarge - * - * Verifies that RSA PKCS encryption fails in the correct way when the mssage is too large. - */ -TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaEncryptionKey(1024, 3) - .Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT))); - string message(1024 / 8 - 10, 'a'); - - auto params = AuthorizationSetBuilder().Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT); - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params)); - string result; - EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, Finish(message, &result)); - EXPECT_EQ(0U, result.size()); -} - -/* - * EncryptionOperationsTest.EcdsaEncrypt - * - * Verifies that attempting to use ECDSA keys to encrypt fails in the correct way. - */ -TEST_F(EncryptionOperationsTest, EcdsaEncrypt) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(224) - .Digest(Digest::NONE))); - auto params = AuthorizationSetBuilder().Digest(Digest::NONE); - ASSERT_EQ(ErrorCode::UNSUPPORTED_PURPOSE, Begin(KeyPurpose::ENCRYPT, params)) - << "(Possibly b/33543625)"; - ASSERT_EQ(ErrorCode::UNSUPPORTED_PURPOSE, Begin(KeyPurpose::DECRYPT, params)) - << "(Possibly b/33543625)"; -} - -/* - * EncryptionOperationsTest.HmacEncrypt - * - * Verifies that attempting to use HMAC keys to encrypt fails in the correct way. - */ -TEST_F(EncryptionOperationsTest, HmacEncrypt) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .HmacKey(128) - .Digest(Digest::SHA_2_256) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MIN_MAC_LENGTH, 128))); - auto params = AuthorizationSetBuilder() - .Digest(Digest::SHA_2_256) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MAC_LENGTH, 128); - ASSERT_EQ(ErrorCode::UNSUPPORTED_PURPOSE, Begin(KeyPurpose::ENCRYPT, params)) - << "(Possibly b/33543625)"; - ASSERT_EQ(ErrorCode::UNSUPPORTED_PURPOSE, Begin(KeyPurpose::DECRYPT, params)) - << "(Possibly b/33543625)"; -} - -/* - * EncryptionOperationsTest.AesEcbRoundTripSuccess - * - * Verifies that AES ECB mode works. - */ -TEST_F(EncryptionOperationsTest, AesEcbRoundTripSuccess) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .Authorization(TAG_BLOCK_MODE, BlockMode::ECB) - .Padding(PaddingMode::NONE))); - - auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::NONE); - - // Two-block message. - string message = "12345678901234567890123456789012"; - string ciphertext1 = EncryptMessage(message, params); - EXPECT_EQ(message.size(), ciphertext1.size()); - - string ciphertext2 = EncryptMessage(string(message), params); - EXPECT_EQ(message.size(), ciphertext2.size()); - - // ECB is deterministic. - EXPECT_EQ(ciphertext1, ciphertext2); - - string plaintext = DecryptMessage(ciphertext1, params); - EXPECT_EQ(message, plaintext); -} - -/* - * EncryptionOperationsTest.AesEcbRoundTripSuccess - * - * Verifies that AES encryption fails in the correct way when an unauthorized mode is specified. - */ -TEST_F(EncryptionOperationsTest, AesWrongMode) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .Authorization(TAG_BLOCK_MODE, BlockMode::CBC) - .Padding(PaddingMode::NONE))); - // Two-block message. - string message = "12345678901234567890123456789012"; - EXPECT_EQ( - ErrorCode::INCOMPATIBLE_BLOCK_MODE, - Begin(KeyPurpose::ENCRYPT, - AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::NONE))); -} - -/* - * EncryptionOperationsTest.AesEcbNoPaddingWrongInputSize - * - * Verifies that AES encryption fails in the correct way when provided an input that is not a - * multiple of the block size and no padding is specified. - */ -TEST_F(EncryptionOperationsTest, AesEcbNoPaddingWrongInputSize) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .Authorization(TAG_BLOCK_MODE, BlockMode::ECB) - .Padding(PaddingMode::NONE))); - // Message is slightly shorter than two blocks. - string message(16 * 2 - 1, 'a'); - - auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::NONE); - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params)); - string ciphertext; - EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, Finish(message, &ciphertext)); - EXPECT_EQ(0U, ciphertext.size()); -} - -/* - * EncryptionOperationsTest.AesEcbPkcs7Padding - * - * Verifies that AES PKCS7 padding works for any message length. - */ -TEST_F(EncryptionOperationsTest, AesEcbPkcs7Padding) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .Authorization(TAG_BLOCK_MODE, BlockMode::ECB) - .Padding(PaddingMode::PKCS7))); - - auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7); - - // Try various message lengths; all should work. - for (size_t i = 0; i < 32; ++i) { - string message(i, 'a'); - string ciphertext = EncryptMessage(message, params); - EXPECT_EQ(i + 16 - (i % 16), ciphertext.size()); - string plaintext = DecryptMessage(ciphertext, params); - EXPECT_EQ(message, plaintext); - } -} - -/* - * EncryptionOperationsTest.AesEcbWrongPadding - * - * Verifies that AES enryption fails in the correct way when an unauthorized padding mode is - * specified. - */ -TEST_F(EncryptionOperationsTest, AesEcbWrongPadding) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .Authorization(TAG_BLOCK_MODE, BlockMode::ECB) - .Padding(PaddingMode::NONE))); - - auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7); - - // Try various message lengths; all should fail - for (size_t i = 0; i < 32; ++i) { - string message(i, 'a'); - EXPECT_EQ(ErrorCode::INCOMPATIBLE_PADDING_MODE, Begin(KeyPurpose::ENCRYPT, params)); - } -} - -/* - * EncryptionOperationsTest.AesEcbPkcs7PaddingCorrupted - * - * Verifies that AES decryption fails in the correct way when the padding is corrupted. - */ -TEST_F(EncryptionOperationsTest, AesEcbPkcs7PaddingCorrupted) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .Authorization(TAG_BLOCK_MODE, BlockMode::ECB) - .Padding(PaddingMode::PKCS7))); - - auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7); - - string message = "a"; - string ciphertext = EncryptMessage(message, params); - EXPECT_EQ(16U, ciphertext.size()); - EXPECT_NE(ciphertext, message); - ++ciphertext[ciphertext.size() / 2]; - - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params)); - string plaintext; - EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, Finish(message, &plaintext)); -} - -HidlBuf CopyIv(const AuthorizationSet& set) { - auto iv = set.GetTagValue(TAG_NONCE); - EXPECT_TRUE(iv.isOk()); - return iv.value(); -} - -/* - * EncryptionOperationsTest.AesCtrRoundTripSuccess - * - * Verifies that AES CTR mode works. - */ -TEST_F(EncryptionOperationsTest, AesCtrRoundTripSuccess) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .Authorization(TAG_BLOCK_MODE, BlockMode::CTR) - .Padding(PaddingMode::NONE))); - - auto params = AuthorizationSetBuilder().BlockMode(BlockMode::CTR).Padding(PaddingMode::NONE); - - string message = "123"; - AuthorizationSet out_params; - string ciphertext1 = EncryptMessage(message, params, &out_params); - HidlBuf iv1 = CopyIv(out_params); - EXPECT_EQ(16U, iv1.size()); - - EXPECT_EQ(message.size(), ciphertext1.size()); - - out_params.Clear(); - string ciphertext2 = EncryptMessage(message, params, &out_params); - HidlBuf iv2 = CopyIv(out_params); - EXPECT_EQ(16U, iv2.size()); - - // IVs should be random, so ciphertexts should differ. - EXPECT_NE(ciphertext1, ciphertext2); - - auto params_iv1 = - AuthorizationSetBuilder().Authorizations(params).Authorization(TAG_NONCE, iv1); - auto params_iv2 = - AuthorizationSetBuilder().Authorizations(params).Authorization(TAG_NONCE, iv2); - - string plaintext = DecryptMessage(ciphertext1, params_iv1); - EXPECT_EQ(message, plaintext); - plaintext = DecryptMessage(ciphertext2, params_iv2); - EXPECT_EQ(message, plaintext); - - // Using the wrong IV will result in a "valid" decryption, but the data will be garbage. - plaintext = DecryptMessage(ciphertext1, params_iv2); - EXPECT_NE(message, plaintext); - plaintext = DecryptMessage(ciphertext2, params_iv1); - EXPECT_NE(message, plaintext); -} - -/* - * EncryptionOperationsTest.AesIncremental - * - * Verifies that AES works, all modes, when provided data in various size increments. - */ -TEST_F(EncryptionOperationsTest, AesIncremental) { - auto block_modes = { - BlockMode::ECB, BlockMode::CBC, BlockMode::CTR, BlockMode::GCM, - }; - - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .BlockMode(block_modes) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MIN_MAC_LENGTH, 128))); - - for (int increment = 1; increment <= 240; ++increment) { - for (auto block_mode : block_modes) { - string message(240, 'a'); - auto params = AuthorizationSetBuilder() - .BlockMode(block_mode) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MAC_LENGTH, 128) /* for GCM */; - - AuthorizationSet output_params; - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &output_params)); - - string ciphertext; - size_t input_consumed; - string to_send; - for (size_t i = 0; i < message.size(); i += increment) { - to_send.append(message.substr(i, increment)); - EXPECT_EQ(ErrorCode::OK, Update(to_send, &ciphertext, &input_consumed)); - to_send = to_send.substr(input_consumed); - - switch (block_mode) { - case BlockMode::ECB: - case BlockMode::CBC: - // Implementations must take as many blocks as possible, leaving less than - // a block. - EXPECT_LE(to_send.length(), 16U); - break; - case BlockMode::GCM: - case BlockMode::CTR: - // Implementations must always take all the data. - EXPECT_EQ(0U, to_send.length()); - break; - } - } - EXPECT_EQ(ErrorCode::OK, Finish(to_send, &ciphertext)) << "Error sending " << to_send; - - switch (block_mode) { - case BlockMode::GCM: - EXPECT_EQ(message.size() + 16, ciphertext.size()); - break; - case BlockMode::CTR: - EXPECT_EQ(message.size(), ciphertext.size()); - break; - case BlockMode::CBC: - case BlockMode::ECB: - EXPECT_EQ(message.size() + message.size() % 16, ciphertext.size()); - break; - } - - auto iv = output_params.GetTagValue(TAG_NONCE); - switch (block_mode) { - case BlockMode::CBC: - case BlockMode::GCM: - case BlockMode::CTR: - ASSERT_TRUE(iv.isOk()) << "No IV for block mode " << block_mode; - EXPECT_EQ(block_mode == BlockMode::GCM ? 12U : 16U, iv.value().size()); - params.push_back(TAG_NONCE, iv.value()); - break; - - case BlockMode::ECB: - EXPECT_FALSE(iv.isOk()) << "ECB mode should not generate IV"; - break; - } - - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params)) - << "Decrypt begin() failed for block mode " << block_mode; - - string plaintext; - for (size_t i = 0; i < ciphertext.size(); i += increment) { - to_send.append(ciphertext.substr(i, increment)); - EXPECT_EQ(ErrorCode::OK, Update(to_send, &plaintext, &input_consumed)); - to_send = to_send.substr(input_consumed); - } - ErrorCode error = Finish(to_send, &plaintext); - ASSERT_EQ(ErrorCode::OK, error) - << "Decryption failed for block mode " << block_mode << " and increment " - << increment << " (Possibly b/33584622)"; - if (error == ErrorCode::OK) { - ASSERT_EQ(message, plaintext) << "Decryption didn't match for block mode " - << block_mode << " and increment " << increment; - } - } - } -} - -struct AesCtrSp80038aTestVector { - const char* key; - const char* nonce; - const char* plaintext; - const char* ciphertext; -}; - -// These test vectors are taken from -// http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf, section F.5. -static const AesCtrSp80038aTestVector kAesCtrSp80038aTestVectors[] = { - // AES-128 - { - "2b7e151628aed2a6abf7158809cf4f3c", "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", - "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51" - "30c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710", - "874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff" - "5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee", - }, - // AES-192 - { - "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", - "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51" - "30c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710", - "1abc932417521ca24f2b0459fe7e6e0b090339ec0aa6faefd5ccc2c6f4ce8e94" - "1e36b26bd1ebc670d1bd1d665620abf74f78a7f6d29809585a97daec58c6b050", - }, - // AES-256 - { - "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", - "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", - "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51" - "30c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710", - "601ec313775789a5b7a7f504bbf3d228f443e3ca4d62b59aca84e990cacaf5c5" - "2b0930daa23de94ce87017ba2d84988ddfc9c58db67aada613c2dd08457941a6", - }, -}; - -/* - * EncryptionOperationsTest.AesCtrSp80038aTestVector - * - * Verifies AES CTR implementation against SP800-38A test vectors. - */ -TEST_F(EncryptionOperationsTest, AesCtrSp80038aTestVector) { - for (size_t i = 0; i < 3; i++) { - const AesCtrSp80038aTestVector& test(kAesCtrSp80038aTestVectors[i]); - const string key = hex2str(test.key); - const string nonce = hex2str(test.nonce); - const string plaintext = hex2str(test.plaintext); - const string ciphertext = hex2str(test.ciphertext); - CheckAesCtrTestVector(key, nonce, plaintext, ciphertext); - } -} - -/* - * EncryptionOperationsTest.AesCtrIncompatiblePaddingMode - * - * Verifies that keymaster rejects use of CTR mode with PKCS7 padding in the correct way. - */ -TEST_F(EncryptionOperationsTest, AesCtrIncompatiblePaddingMode) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .Authorization(TAG_BLOCK_MODE, BlockMode::CTR) - .Padding(PaddingMode::PKCS7))); - auto params = AuthorizationSetBuilder().BlockMode(BlockMode::CTR).Padding(PaddingMode::NONE); - EXPECT_EQ(ErrorCode::INCOMPATIBLE_PADDING_MODE, Begin(KeyPurpose::ENCRYPT, params)); -} - -/* - * EncryptionOperationsTest.AesCtrInvalidCallerNonce - * - * Verifies that keymaster fails correctly when the user supplies an incorrect-size nonce. - */ -TEST_F(EncryptionOperationsTest, AesCtrInvalidCallerNonce) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .Authorization(TAG_BLOCK_MODE, BlockMode::CTR) - .Authorization(TAG_CALLER_NONCE) - .Padding(PaddingMode::NONE))); - - auto params = AuthorizationSetBuilder() - .BlockMode(BlockMode::CTR) - .Padding(PaddingMode::NONE) - .Authorization(TAG_NONCE, HidlBuf(string(1, 'a'))); - EXPECT_EQ(ErrorCode::INVALID_NONCE, Begin(KeyPurpose::ENCRYPT, params)); - - params = AuthorizationSetBuilder() - .BlockMode(BlockMode::CTR) - .Padding(PaddingMode::NONE) - .Authorization(TAG_NONCE, HidlBuf(string(15, 'a'))); - EXPECT_EQ(ErrorCode::INVALID_NONCE, Begin(KeyPurpose::ENCRYPT, params)); - - params = AuthorizationSetBuilder() - .BlockMode(BlockMode::CTR) - .Padding(PaddingMode::NONE) - .Authorization(TAG_NONCE, HidlBuf(string(17, 'a'))); - EXPECT_EQ(ErrorCode::INVALID_NONCE, Begin(KeyPurpose::ENCRYPT, params)); -} - -/* - * EncryptionOperationsTest.AesCtrInvalidCallerNonce - * - * Verifies that keymaster fails correctly when the user supplies an incorrect-size nonce. - */ -TEST_F(EncryptionOperationsTest, AesCbcRoundTripSuccess) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .Authorization(TAG_BLOCK_MODE, BlockMode::CBC) - .Padding(PaddingMode::NONE))); - // Two-block message. - string message = "12345678901234567890123456789012"; - auto params = AuthorizationSetBuilder().BlockMode(BlockMode::CBC).Padding(PaddingMode::NONE); - AuthorizationSet out_params; - string ciphertext1 = EncryptMessage(message, params, &out_params); - HidlBuf iv1 = CopyIv(out_params); - EXPECT_EQ(message.size(), ciphertext1.size()); - - out_params.Clear(); - - string ciphertext2 = EncryptMessage(message, params, &out_params); - HidlBuf iv2 = CopyIv(out_params); - EXPECT_EQ(message.size(), ciphertext2.size()); - - // IVs should be random, so ciphertexts should differ. - EXPECT_NE(ciphertext1, ciphertext2); - - params.push_back(TAG_NONCE, iv1); - string plaintext = DecryptMessage(ciphertext1, params); - EXPECT_EQ(message, plaintext); -} - -/* - * EncryptionOperationsTest.AesCallerNonce - * - * Verifies that AES caller-provided nonces work correctly. - */ -TEST_F(EncryptionOperationsTest, AesCallerNonce) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .Authorization(TAG_BLOCK_MODE, BlockMode::CBC) - .Authorization(TAG_CALLER_NONCE) - .Padding(PaddingMode::NONE))); - - string message = "12345678901234567890123456789012"; - - // Don't specify nonce, should get a random one. - AuthorizationSetBuilder params = - AuthorizationSetBuilder().BlockMode(BlockMode::CBC).Padding(PaddingMode::NONE); - AuthorizationSet out_params; - string ciphertext = EncryptMessage(message, params, &out_params); - EXPECT_EQ(message.size(), ciphertext.size()); - EXPECT_EQ(16U, out_params.GetTagValue(TAG_NONCE).value().size()); - - params.push_back(TAG_NONCE, out_params.GetTagValue(TAG_NONCE).value()); - string plaintext = DecryptMessage(ciphertext, params); - EXPECT_EQ(message, plaintext); - - // Now specify a nonce, should also work. - params = AuthorizationSetBuilder() - .BlockMode(BlockMode::CBC) - .Padding(PaddingMode::NONE) - .Authorization(TAG_NONCE, HidlBuf("abcdefghijklmnop")); - out_params.Clear(); - ciphertext = EncryptMessage(message, params, &out_params); - - // Decrypt with correct nonce. - plaintext = DecryptMessage(ciphertext, params); - EXPECT_EQ(message, plaintext); - - // Try with wrong nonce. - params = AuthorizationSetBuilder() - .BlockMode(BlockMode::CBC) - .Padding(PaddingMode::NONE) - .Authorization(TAG_NONCE, HidlBuf("aaaaaaaaaaaaaaaa")); - plaintext = DecryptMessage(ciphertext, params); - EXPECT_NE(message, plaintext); -} - -/* - * EncryptionOperationsTest.AesCallerNonceProhibited - * - * Verifies that caller-provided nonces are not permitted when not specified in the key - * authorizations. - */ -TEST_F(EncryptionOperationsTest, AesCallerNonceProhibited) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .Authorization(TAG_BLOCK_MODE, BlockMode::CBC) - .Padding(PaddingMode::NONE))); - - string message = "12345678901234567890123456789012"; - - // Don't specify nonce, should get a random one. - AuthorizationSetBuilder params = - AuthorizationSetBuilder().BlockMode(BlockMode::CBC).Padding(PaddingMode::NONE); - AuthorizationSet out_params; - string ciphertext = EncryptMessage(message, params, &out_params); - EXPECT_EQ(message.size(), ciphertext.size()); - EXPECT_EQ(16U, out_params.GetTagValue(TAG_NONCE).value().size()); - - params.push_back(TAG_NONCE, out_params.GetTagValue(TAG_NONCE).value()); - string plaintext = DecryptMessage(ciphertext, params); - EXPECT_EQ(message, plaintext); - - // Now specify a nonce, should fail - params = AuthorizationSetBuilder() - .BlockMode(BlockMode::CBC) - .Padding(PaddingMode::NONE) - .Authorization(TAG_NONCE, HidlBuf("abcdefghijklmnop")); - out_params.Clear(); - EXPECT_EQ(ErrorCode::CALLER_NONCE_PROHIBITED, Begin(KeyPurpose::ENCRYPT, params, &out_params)); -} - -/* - * EncryptionOperationsTest.AesGcmRoundTripSuccess - * - * Verifies that AES GCM mode works. - */ -TEST_F(EncryptionOperationsTest, AesGcmRoundTripSuccess) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .Authorization(TAG_BLOCK_MODE, BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MIN_MAC_LENGTH, 128))); - - string aad = "foobar"; - string message = "123456789012345678901234567890123456"; - - auto begin_params = AuthorizationSetBuilder() - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MAC_LENGTH, 128); - - auto update_params = - AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size()); - - // Encrypt - AuthorizationSet begin_out_params; - ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params)) - << "Begin encrypt"; - string ciphertext; - AuthorizationSet update_out_params; - ASSERT_EQ(ErrorCode::OK, - Finish(op_handle_, update_params, message, "", &update_out_params, &ciphertext)); - - // Grab nonce - begin_params.push_back(begin_out_params); - - // Decrypt. - ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params)) << "Begin decrypt"; - string plaintext; - size_t input_consumed; - ASSERT_EQ(ErrorCode::OK, Update(op_handle_, update_params, ciphertext, &update_out_params, - &plaintext, &input_consumed)); - EXPECT_EQ(ciphertext.size(), input_consumed); - EXPECT_EQ(ErrorCode::OK, Finish("", &plaintext)); - - EXPECT_EQ(message, plaintext); -} - -/* - * EncryptionOperationsTest.AesGcmTooShortTag - * - * Verifies that AES GCM mode fails correctly when a too-short tag length is specified. - */ -TEST_F(EncryptionOperationsTest, AesGcmTooShortTag) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MIN_MAC_LENGTH, 128))); - string message = "123456789012345678901234567890123456"; - auto params = AuthorizationSetBuilder() - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MAC_LENGTH, 96); - - EXPECT_EQ(ErrorCode::INVALID_MAC_LENGTH, Begin(KeyPurpose::ENCRYPT, params)); -} - -/* - * EncryptionOperationsTest.AesGcmTooShortTagOnDecrypt - * - * Verifies that AES GCM mode fails correctly when a too-short tag is provided to decryption. - */ -TEST_F(EncryptionOperationsTest, AesGcmTooShortTagOnDecrypt) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MIN_MAC_LENGTH, 128))); - string aad = "foobar"; - string message = "123456789012345678901234567890123456"; - auto params = AuthorizationSetBuilder() - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MAC_LENGTH, 128); - - auto finish_params = - AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size()); - - // Encrypt - AuthorizationSet begin_out_params; - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params)); - EXPECT_EQ(1U, begin_out_params.size()); - ASSERT_TRUE(begin_out_params.GetTagValue(TAG_NONCE).isOk()); - - AuthorizationSet finish_out_params; - string ciphertext; - EXPECT_EQ(ErrorCode::OK, Finish(op_handle_, finish_params, message, "" /* signature */, - &finish_out_params, &ciphertext)); - - params = AuthorizationSetBuilder() - .Authorizations(begin_out_params) - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MAC_LENGTH, 96); - - // Decrypt. - EXPECT_EQ(ErrorCode::INVALID_MAC_LENGTH, Begin(KeyPurpose::DECRYPT, params)); -} - -/* - * EncryptionOperationsTest.AesGcmCorruptKey - * - * Verifies that AES GCM mode fails correctly when the decryption key is incorrect. - */ -TEST_F(EncryptionOperationsTest, AesGcmCorruptKey) { - string nonce = { - 0xb7, 0x94, 0x37, 0xae, 0x08, 0xff, 0x35, 0x5d, 0x7d, 0x8a, 0x4d, 0x0f, - }; - string ciphertext = { - 0xb3, 0xf6, 0x79, 0x9e, 0x8f, 0x93, 0x26, 0xf2, 0xdf, 0x1e, 0x80, 0xfc, 0xd2, 0xcb, 0x16, - 0xd7, 0x8c, 0x9d, 0xc7, 0xcc, 0x14, 0xbb, 0x67, 0x78, 0x62, 0xdc, 0x6c, 0x63, 0x9b, 0x3a, - 0x63, 0x38, 0xd2, 0x4b, 0x31, 0x2d, 0x39, 0x89, 0xe5, 0x92, 0x0b, 0x5d, 0xbf, 0xc9, 0x76, - 0x76, 0x5e, 0xfb, 0xfe, 0x57, 0xbb, 0x38, 0x59, 0x40, 0xa7, 0xa4, 0x3b, 0xdf, 0x05, 0xbd, - 0xda, 0xe3, 0xc9, 0xd6, 0xa2, 0xfb, 0xbd, 0xfc, 0xc0, 0xcb, 0xa0, - }; - - auto params = AuthorizationSetBuilder() - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MAC_LENGTH, 128) - .Authorization(TAG_NONCE, nonce.data(), nonce.size()); - - auto import_params = AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_CALLER_NONCE) - .Authorization(TAG_MIN_MAC_LENGTH, 128); - - // Import correct key and decrypt - string key = { - 0xba, 0x76, 0x35, 0x4f, 0x0a, 0xed, 0x6e, 0x8d, - 0x91, 0xf4, 0x5c, 0x4f, 0xf5, 0xa0, 0x62, 0xdb, - }; - ASSERT_EQ(ErrorCode::OK, ImportKey(import_params, KeyFormat::RAW, key)); - string plaintext = DecryptMessage(ciphertext, params); - EXPECT_EQ(ErrorCode::OK, DeleteKey()); - - // Corrupt key and attempt to decrypt - key[0] = 0; - ASSERT_EQ(ErrorCode::OK, ImportKey(import_params, KeyFormat::RAW, key)); - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params)); - EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(ciphertext, &plaintext)); - EXPECT_EQ(ErrorCode::OK, DeleteKey()); -} - -/* - * EncryptionOperationsTest.AesGcmAadNoData - * - * Verifies that AES GCM mode works when provided additional authenticated data, but no data to - * encrypt. - */ -TEST_F(EncryptionOperationsTest, AesGcmAadNoData) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MIN_MAC_LENGTH, 128))); - - string aad = "1234567890123456"; - auto params = AuthorizationSetBuilder() - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MAC_LENGTH, 128); - - auto finish_params = - AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size()); - - // Encrypt - AuthorizationSet begin_out_params; - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params)); - string ciphertext; - AuthorizationSet finish_out_params; - EXPECT_EQ(ErrorCode::OK, Finish(op_handle_, finish_params, "" /* input */, "" /* signature */, - &finish_out_params, &ciphertext)); - EXPECT_TRUE(finish_out_params.empty()); - - // Grab nonce - params.push_back(begin_out_params); - - // Decrypt. - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params)); - string plaintext; - EXPECT_EQ(ErrorCode::OK, Finish(op_handle_, finish_params, ciphertext, "" /* signature */, - &finish_out_params, &plaintext)) - << "(Possibly b/33615032)"; - - EXPECT_TRUE(finish_out_params.empty()); - - EXPECT_EQ("", plaintext); -} - -/* - * EncryptionOperationsTest.AesGcmMultiPartAad - * - * Verifies that AES GCM mode works when provided additional authenticated data in multiple chunks. - */ -TEST_F(EncryptionOperationsTest, AesGcmMultiPartAad) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MIN_MAC_LENGTH, 128))); - - string message = "123456789012345678901234567890123456"; - auto begin_params = AuthorizationSetBuilder() - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MAC_LENGTH, 128); - AuthorizationSet begin_out_params; - - auto update_params = - AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foo", (size_t)3); - - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params)); - - // No data, AAD only. - string ciphertext; - size_t input_consumed; - AuthorizationSet update_out_params; - EXPECT_EQ(ErrorCode::OK, Update(op_handle_, update_params, "" /* input */, &update_out_params, - &ciphertext, &input_consumed)); - EXPECT_EQ(0U, input_consumed); - EXPECT_EQ(0U, ciphertext.size()); - EXPECT_TRUE(update_out_params.empty()); - - // AAD and data. - EXPECT_EQ(ErrorCode::OK, Update(op_handle_, update_params, message, &update_out_params, - &ciphertext, &input_consumed)); - EXPECT_EQ(message.size(), input_consumed); - EXPECT_EQ(message.size(), ciphertext.size()); - EXPECT_TRUE(update_out_params.empty()); - - EXPECT_EQ(ErrorCode::OK, Finish("" /* input */, &ciphertext)); - - // Grab nonce. - begin_params.push_back(begin_out_params); - - // Decrypt - update_params = - AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foofoo", (size_t)6); - - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params)); - string plaintext; - EXPECT_EQ(ErrorCode::OK, Finish(op_handle_, update_params, ciphertext, "" /* signature */, - &update_out_params, &plaintext)); - EXPECT_TRUE(update_out_params.empty()); - EXPECT_EQ(message, plaintext); -} - -/* - * EncryptionOperationsTest.AesGcmAadOutOfOrder - * - * Verifies that AES GCM mode fails correctly when given AAD after data to encipher. - */ -TEST_F(EncryptionOperationsTest, AesGcmAadOutOfOrder) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MIN_MAC_LENGTH, 128))); - - string message = "123456789012345678901234567890123456"; - auto begin_params = AuthorizationSetBuilder() - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MAC_LENGTH, 128); - AuthorizationSet begin_out_params; - - auto update_params = - AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foo", (size_t)3); - - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params)); - - // No data, AAD only. - string ciphertext; - size_t input_consumed; - AuthorizationSet update_out_params; - EXPECT_EQ(ErrorCode::OK, Update(op_handle_, update_params, "" /* input */, &update_out_params, - &ciphertext, &input_consumed)); - EXPECT_EQ(0U, input_consumed); - EXPECT_EQ(0U, ciphertext.size()); - EXPECT_TRUE(update_out_params.empty()); - - // AAD and data. - EXPECT_EQ(ErrorCode::OK, Update(op_handle_, update_params, message, &update_out_params, - &ciphertext, &input_consumed)); - EXPECT_EQ(message.size(), input_consumed); - EXPECT_EQ(message.size(), ciphertext.size()); - EXPECT_TRUE(update_out_params.empty()); - - // More AAD - EXPECT_EQ(ErrorCode::INVALID_TAG, Update(op_handle_, update_params, "", &update_out_params, - &ciphertext, &input_consumed)); - - op_handle_ = kOpHandleSentinel; -} - -/* - * EncryptionOperationsTest.AesGcmBadAad - * - * Verifies that AES GCM decryption fails correctly when additional authenticated date is wrong. - */ -TEST_F(EncryptionOperationsTest, AesGcmBadAad) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MIN_MAC_LENGTH, 128))); - - string message = "12345678901234567890123456789012"; - auto begin_params = AuthorizationSetBuilder() - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MAC_LENGTH, 128); - - auto finish_params = - AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foobar", (size_t)6); - - // Encrypt - AuthorizationSet begin_out_params; - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params)); - string ciphertext; - AuthorizationSet finish_out_params; - EXPECT_EQ(ErrorCode::OK, Finish(op_handle_, finish_params, message, "" /* signature */, - &finish_out_params, &ciphertext)); - - // Grab nonce - begin_params.push_back(begin_out_params); - - finish_params = AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, - "barfoo" /* Wrong AAD */, (size_t)6); - - // Decrypt. - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params, &begin_out_params)); - string plaintext; - EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, - Finish(op_handle_, finish_params, ciphertext, "" /* signature */, &finish_out_params, - &plaintext)); -} - -/* - * EncryptionOperationsTest.AesGcmWrongNonce - * - * Verifies that AES GCM decryption fails correctly when the nonce is incorrect. - */ -TEST_F(EncryptionOperationsTest, AesGcmWrongNonce) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MIN_MAC_LENGTH, 128))); - - string message = "12345678901234567890123456789012"; - auto begin_params = AuthorizationSetBuilder() - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MAC_LENGTH, 128); - - auto finish_params = - AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foobar", (size_t)6); - - // Encrypt - AuthorizationSet begin_out_params; - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params)); - string ciphertext; - AuthorizationSet finish_out_params; - EXPECT_EQ(ErrorCode::OK, Finish(op_handle_, finish_params, message, "" /* signature */, - &finish_out_params, &ciphertext)); - - // Wrong nonce - begin_params.push_back(TAG_NONCE, HidlBuf("123456789012")); - - // Decrypt. - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params, &begin_out_params)); - string plaintext; - EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, - Finish(op_handle_, finish_params, ciphertext, "" /* signature */, &finish_out_params, - &plaintext)); - - // With wrong nonce, should have gotten garbage plaintext (or none). - EXPECT_NE(message, plaintext); -} - -/* - * EncryptionOperationsTest.AesGcmCorruptTag - * - * Verifies that AES GCM decryption fails correctly when the tag is wrong. - */ -TEST_F(EncryptionOperationsTest, AesGcmCorruptTag) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MIN_MAC_LENGTH, 128))); - - string aad = "1234567890123456"; - string message = "123456789012345678901234567890123456"; - - auto params = AuthorizationSetBuilder() - .BlockMode(BlockMode::GCM) - .Padding(PaddingMode::NONE) - .Authorization(TAG_MAC_LENGTH, 128); - - auto finish_params = - AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size()); - - // Encrypt - AuthorizationSet begin_out_params; - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params)); - string ciphertext; - AuthorizationSet finish_out_params; - EXPECT_EQ(ErrorCode::OK, Finish(op_handle_, finish_params, message, "" /* signature */, - &finish_out_params, &ciphertext)); - EXPECT_TRUE(finish_out_params.empty()); - - // Corrupt tag - ++(*ciphertext.rbegin()); - - // Grab nonce - params.push_back(begin_out_params); - - // Decrypt. - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params)); - string plaintext; - EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, - Finish(op_handle_, finish_params, ciphertext, "" /* signature */, &finish_out_params, - &plaintext)); - EXPECT_TRUE(finish_out_params.empty()); -} - -typedef KeymasterHidlTest MaxOperationsTest; - -/* - * MaxOperationsTest.TestLimitAes - * - * Verifies that the max uses per boot tag works correctly with AES keys. - */ -TEST_F(MaxOperationsTest, TestLimitAes) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .EcbMode() - .Padding(PaddingMode::NONE) - .Authorization(TAG_MAX_USES_PER_BOOT, 3))); - - string message = "1234567890123456"; - - auto params = AuthorizationSetBuilder().EcbMode().Padding(PaddingMode::NONE); - - EncryptMessage(message, params); - EncryptMessage(message, params); - EncryptMessage(message, params); - - // Fourth time should fail. - EXPECT_EQ(ErrorCode::KEY_MAX_OPS_EXCEEDED, Begin(KeyPurpose::ENCRYPT, params)); -} - -/* - * MaxOperationsTest.TestLimitAes - * - * Verifies that the max uses per boot tag works correctly with RSA keys. - */ -TEST_F(MaxOperationsTest, TestLimitRsa) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaSigningKey(1024, 3) - .NoDigestOrPadding() - .Authorization(TAG_MAX_USES_PER_BOOT, 3))); - - string message = "1234567890123456"; - - auto params = AuthorizationSetBuilder().NoDigestOrPadding(); - - SignMessage(message, params); - SignMessage(message, params); - SignMessage(message, params); - - // Fourth time should fail. - EXPECT_EQ(ErrorCode::KEY_MAX_OPS_EXCEEDED, Begin(KeyPurpose::SIGN, params)); -} - -typedef KeymasterHidlTest AddEntropyTest; - -/* - * AddEntropyTest.AddEntropy - * - * Verifies that the addRngEntropy method doesn't blow up. There's no way to test that entropy is - * actually added. - */ -TEST_F(AddEntropyTest, AddEntropy) { - EXPECT_EQ(ErrorCode::OK, keymaster().addRngEntropy(HidlBuf("foo"))); -} - -/* - * AddEntropyTest.AddEmptyEntropy - * - * Verifies that the addRngEntropy method doesn't blow up when given an empty buffer. - */ -TEST_F(AddEntropyTest, AddEmptyEntropy) { - EXPECT_EQ(ErrorCode::OK, keymaster().addRngEntropy(HidlBuf())); -} - -/* - * AddEntropyTest.AddLargeEntropy - * - * Verifies that the addRngEntropy method doesn't blow up when given a largish amount of data. - */ -TEST_F(AddEntropyTest, AddLargeEntropy) { - EXPECT_EQ(ErrorCode::OK, keymaster().addRngEntropy(HidlBuf(string(16 * 1024, 'a')))); -} - -typedef KeymasterHidlTest AttestationTest; - -/* - * AttestationTest.RsaAttestation - * - * Verifies that attesting to RSA keys works and generates the expected output. - */ -TEST_F(AttestationTest, RsaAttestation) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaSigningKey(1024, 3) - .Digest(Digest::NONE) - .Padding(PaddingMode::NONE) - .Authorization(TAG_INCLUDE_UNIQUE_ID))); - - hidl_vec> cert_chain; - EXPECT_EQ(ErrorCode::OK, AttestKey(AuthorizationSetBuilder().Authorization( - TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge")), - &cert_chain)); - EXPECT_GE(cert_chain.size(), 2U); - EXPECT_TRUE(verify_chain(cert_chain)); - EXPECT_TRUE(verify_attestation_record("challenge", // - key_characteristics_.softwareEnforced, // - key_characteristics_.teeEnforced, // - cert_chain[0])); -} - -/* - * AttestationTest.EcAttestation - * - * Verifies that attesting to EC keys works and generates the expected output. - */ -TEST_F(AttestationTest, EcAttestation) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(EcCurve::P_256) - .Digest(Digest::SHA_2_256) - .Authorization(TAG_INCLUDE_UNIQUE_ID))); - - hidl_vec> cert_chain; - EXPECT_EQ(ErrorCode::OK, AttestKey(AuthorizationSetBuilder().Authorization( - TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge")), - &cert_chain)); - EXPECT_GE(cert_chain.size(), 2U); - EXPECT_TRUE(verify_chain(cert_chain)); - - EXPECT_TRUE(verify_attestation_record("challenge", // - key_characteristics_.softwareEnforced, // - key_characteristics_.teeEnforced, // - cert_chain[0])); -} - -/* - * AttestationTest.AesAttestation - * - * Verifies that attesting to AES keys fails in the expected way. - */ -TEST_F(AttestationTest, AesAttestation) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .AesEncryptionKey(128) - .EcbMode() - .Padding(PaddingMode::PKCS7))); - - hidl_vec> cert_chain; - EXPECT_EQ(ErrorCode::INCOMPATIBLE_ALGORITHM, - AttestKey(AuthorizationSetBuilder().Authorization(TAG_ATTESTATION_CHALLENGE, - HidlBuf("challenge")), - &cert_chain)); -} - -/* - * AttestationTest.HmacAttestation - * - * Verifies that attesting to HMAC keys fails in the expected way. - */ -TEST_F(AttestationTest, HmacAttestation) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .HmacKey(128) - .EcbMode() - .Digest(Digest::SHA_2_256) - .Authorization(TAG_MIN_MAC_LENGTH, 128))); - - hidl_vec> cert_chain; - EXPECT_EQ(ErrorCode::INCOMPATIBLE_ALGORITHM, - AttestKey(AuthorizationSetBuilder().Authorization(TAG_ATTESTATION_CHALLENGE, - HidlBuf("challenge")), - &cert_chain)); -} - -} // namespace test -} // namespace V3_0 -} // namespace keymaster -} // namespace hardware -} // namespace android - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - if (argc == 2) { - ALOGI("Running keymaster VTS against service \"%s\"", argv[1]); - service_name = argv[1]; - } - int status = RUN_ALL_TESTS(); - ALOGI("Test result = %d", status); - return status; -} diff --git a/keymaster/3.0/vts/functional/keymaster_tags.h b/keymaster/3.0/vts/functional/keymaster_tags.h deleted file mode 100644 index f241ef16..00000000 --- a/keymaster/3.0/vts/functional/keymaster_tags.h +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Copyright 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SYSTEM_SECURITY_KEYSTORE_KEYMASTER_TAGS_H_ -#define SYSTEM_SECURITY_KEYSTORE_KEYMASTER_TAGS_H_ - -/** - * This header contains various definitions that make working with keymaster tags safer and easier. - * - * It makes use of a fair amount of template metaprogramming. The metaprogramming serves the purpose - * of making it impossible to make certain classes of mistakes when operating on keymaster - * authorizations. For example, it's an error to create a KeyParameter with tag == Tag::PURPOSE - * and then to assign Algorithm::RSA to algorithm element of its union. But because the user - * must choose the union field, there could be a mismatch which the compiler has now way to - * diagnose. - * - * The machinery in this header solves these problems by describing which union field corresponds - * to which Tag. Central to this mechanism is the template TypedTag. It has zero size and binds a - * numeric Tag to a type that the compiler understands. By means of the macro DECLARE_TYPED_TAG, - * we declare types for each of the tags defined in hardware/interfaces/keymaster/2.0/types.hal. - * - * The macro DECLARE_TYPED_TAG(name) generates a typename TAG_name_t and a zero sized instance - * TAG_name. Once these typed tags have been declared we define metafunctions mapping the each tag - * to its value c++ type and the correct union element of KeyParameter. This is done by means of - * the macros MAKE_TAG_*VALUE_ACCESSOR, which generates TypedTag2ValueType, a metafunction mapping - * a typed tag to the corresponding c++ type, and access function, accessTagValue returning a - * reference to the correct element of KeyParameter. - * E.g.: - * given "KeyParameter param;" then "accessTagValue(TAG_PURPOSE, param)" - * yields a reference to param.f.purpose - * If used in an assignment the compiler can now check the compatibility of the assigned value. - * - * For convenience we also provide the constructor like function Authorization(). - * Authorization takes a typed tag and a value and checks at compile time whether the value given - * is suitable for the given tag. At runtime it creates a new KeyParameter initialized with the - * given tag and value and returns it by value. - * - * The second convenience function, authorizationValue, allows access to the KeyParameter value in - * a safe way. It takes a typed tag and a KeyParameter and returns a reference to the value wrapped - * by NullOr. NullOr has out-of-band information about whether it is save to access the wrapped - * reference. - * E.g.: - * auto param = Authorization(TAG_ALGORITM, Algorithm::RSA); - * auto value1 = authorizationValue(TAG_PURPOSE, param); - * auto value2 = authorizationValue(TAG_ALGORITM, param); - * value1.isOk() yields false, but value2.isOk() yields true, thus value2.value() is save to access. - */ - -#include -#include -#include - -namespace android { -namespace hardware { -namespace keymaster { -namespace V3_0 { - -// The following create the numeric values that KM_TAG_PADDING and KM_TAG_DIGEST used to have. We -// need these old values to be able to support old keys that use them. -static const int32_t KM_TAG_DIGEST_OLD = static_cast(TagType::ENUM) | 5; -static const int32_t KM_TAG_PADDING_OLD = static_cast(TagType::ENUM) | 7; - -constexpr TagType typeFromTag(Tag tag) { - return static_cast(static_cast(tag) & static_cast(0xf0000000)); -} - -/** - * TypedTag is a templatized version of Tag, which provides compile-time checking of keymaster tag - * types. Instances are convertible to Tag, so they can be used wherever Tag is expected, and - * because they encode the tag type it's possible to create function overloads that only operate on - * tags with a particular type. - */ -template struct TypedTag { - inline TypedTag() { - // Ensure that it's impossible to create a TypedTag instance whose 'tag' doesn't have type - // 'tag_type'. Attempting to instantiate a tag with the wrong type will result in a compile - // error (no match for template specialization StaticAssert), with no run-time cost. - static_assert(typeFromTag(tag) == tag_type, "mismatch between tag and tag_type"); - } - constexpr operator Tag() { return tag; } - constexpr long maskedTag() { - return static_cast(static_cast(tag) & static_cast(0x0fffffff)); - } -}; - -template struct Tag2TypedTag { typedef TypedTag type; }; - -template struct Tag2String; - -#define _TAGS_STRINGIFY(x) #x -#define TAGS_STRINGIFY(x) _TAGS_STRINGIFY(x) - -#define DECLARE_TYPED_TAG(name) \ - typedef typename Tag2TypedTag::type TAG_##name##_t; \ - extern TAG_##name##_t TAG_##name; \ - template <> struct Tag2String { \ - static const char* value() { return "Tag::" TAGS_STRINGIFY(name); } \ - } - -DECLARE_TYPED_TAG(INVALID); -DECLARE_TYPED_TAG(KEY_SIZE); -DECLARE_TYPED_TAG(MAC_LENGTH); -DECLARE_TYPED_TAG(CALLER_NONCE); -DECLARE_TYPED_TAG(MIN_MAC_LENGTH); -DECLARE_TYPED_TAG(RSA_PUBLIC_EXPONENT); -DECLARE_TYPED_TAG(ECIES_SINGLE_HASH_MODE); -DECLARE_TYPED_TAG(INCLUDE_UNIQUE_ID); -DECLARE_TYPED_TAG(ACTIVE_DATETIME); -DECLARE_TYPED_TAG(ORIGINATION_EXPIRE_DATETIME); -DECLARE_TYPED_TAG(USAGE_EXPIRE_DATETIME); -DECLARE_TYPED_TAG(MIN_SECONDS_BETWEEN_OPS); -DECLARE_TYPED_TAG(MAX_USES_PER_BOOT); -DECLARE_TYPED_TAG(ALL_USERS); -DECLARE_TYPED_TAG(USER_ID); -DECLARE_TYPED_TAG(USER_SECURE_ID); -DECLARE_TYPED_TAG(NO_AUTH_REQUIRED); -DECLARE_TYPED_TAG(AUTH_TIMEOUT); -DECLARE_TYPED_TAG(ALLOW_WHILE_ON_BODY); -DECLARE_TYPED_TAG(ALL_APPLICATIONS); -DECLARE_TYPED_TAG(APPLICATION_ID); -DECLARE_TYPED_TAG(APPLICATION_DATA); -DECLARE_TYPED_TAG(CREATION_DATETIME); -DECLARE_TYPED_TAG(ROLLBACK_RESISTANT); -DECLARE_TYPED_TAG(ROOT_OF_TRUST); -DECLARE_TYPED_TAG(ASSOCIATED_DATA); -DECLARE_TYPED_TAG(NONCE); -DECLARE_TYPED_TAG(AUTH_TOKEN); -DECLARE_TYPED_TAG(BOOTLOADER_ONLY); -DECLARE_TYPED_TAG(OS_VERSION); -DECLARE_TYPED_TAG(OS_PATCHLEVEL); -DECLARE_TYPED_TAG(UNIQUE_ID); -DECLARE_TYPED_TAG(ATTESTATION_CHALLENGE); -DECLARE_TYPED_TAG(ATTESTATION_APPLICATION_ID); -DECLARE_TYPED_TAG(RESET_SINCE_ID_ROTATION); - -DECLARE_TYPED_TAG(PURPOSE); -DECLARE_TYPED_TAG(ALGORITHM); -DECLARE_TYPED_TAG(BLOCK_MODE); -DECLARE_TYPED_TAG(DIGEST); -DECLARE_TYPED_TAG(PADDING); -DECLARE_TYPED_TAG(BLOB_USAGE_REQUIREMENTS); -DECLARE_TYPED_TAG(ORIGIN); -DECLARE_TYPED_TAG(USER_AUTH_TYPE); -DECLARE_TYPED_TAG(KDF); -DECLARE_TYPED_TAG(EC_CURVE); - -template struct MetaList {}; - -using all_tags_t = MetaList< - TAG_INVALID_t, TAG_KEY_SIZE_t, TAG_MAC_LENGTH_t, TAG_CALLER_NONCE_t, TAG_MIN_MAC_LENGTH_t, - TAG_RSA_PUBLIC_EXPONENT_t, TAG_ECIES_SINGLE_HASH_MODE_t, TAG_INCLUDE_UNIQUE_ID_t, - TAG_ACTIVE_DATETIME_t, TAG_ORIGINATION_EXPIRE_DATETIME_t, TAG_USAGE_EXPIRE_DATETIME_t, - TAG_MIN_SECONDS_BETWEEN_OPS_t, TAG_MAX_USES_PER_BOOT_t, TAG_ALL_USERS_t, TAG_USER_ID_t, - TAG_USER_SECURE_ID_t, TAG_NO_AUTH_REQUIRED_t, TAG_AUTH_TIMEOUT_t, TAG_ALLOW_WHILE_ON_BODY_t, - TAG_ALL_APPLICATIONS_t, TAG_APPLICATION_ID_t, TAG_APPLICATION_DATA_t, TAG_CREATION_DATETIME_t, - TAG_ROLLBACK_RESISTANT_t, TAG_ROOT_OF_TRUST_t, TAG_ASSOCIATED_DATA_t, TAG_NONCE_t, - TAG_AUTH_TOKEN_t, TAG_BOOTLOADER_ONLY_t, TAG_OS_VERSION_t, TAG_OS_PATCHLEVEL_t, TAG_UNIQUE_ID_t, - TAG_ATTESTATION_CHALLENGE_t, TAG_ATTESTATION_APPLICATION_ID_t, TAG_RESET_SINCE_ID_ROTATION_t, - TAG_PURPOSE_t, TAG_ALGORITHM_t, TAG_BLOCK_MODE_t, TAG_DIGEST_t, TAG_PADDING_t, - TAG_BLOB_USAGE_REQUIREMENTS_t, TAG_ORIGIN_t, TAG_USER_AUTH_TYPE_t, TAG_KDF_t, TAG_EC_CURVE_t>; - -/* implementation in keystore_utils.cpp */ -extern const char* stringifyTag(Tag tag); - -template struct TypedTag2ValueType; - -#define MAKE_TAG_VALUE_ACCESSOR(tag_type, field_name) \ - template struct TypedTag2ValueType> { \ - typedef decltype(static_cast(nullptr)->field_name) type; \ - }; \ - template \ - inline auto accessTagValue(TypedTag, const KeyParameter& param) \ - ->const decltype(param.field_name)& { \ - return param.field_name; \ - } \ - template \ - inline auto accessTagValue(TypedTag, KeyParameter& param) \ - ->decltype(param.field_name)& { \ - return param.field_name; \ - } - -MAKE_TAG_VALUE_ACCESSOR(TagType::ULONG, f.longInteger) -MAKE_TAG_VALUE_ACCESSOR(TagType::ULONG_REP, f.longInteger) -MAKE_TAG_VALUE_ACCESSOR(TagType::DATE, f.dateTime) -MAKE_TAG_VALUE_ACCESSOR(TagType::UINT, f.integer) -MAKE_TAG_VALUE_ACCESSOR(TagType::UINT_REP, f.integer) -MAKE_TAG_VALUE_ACCESSOR(TagType::BOOL, f.boolValue) -MAKE_TAG_VALUE_ACCESSOR(TagType::BYTES, blob) -MAKE_TAG_VALUE_ACCESSOR(TagType::BIGNUM, blob) - -#define MAKE_TAG_ENUM_VALUE_ACCESSOR(typed_tag, field_name) \ - template <> struct TypedTag2ValueType { \ - typedef decltype(static_cast(nullptr)->field_name) type; \ - }; \ - inline auto accessTagValue(decltype(typed_tag), const KeyParameter& param) \ - ->const decltype(param.field_name)& { \ - return param.field_name; \ - } \ - inline auto accessTagValue(decltype(typed_tag), KeyParameter& param) \ - ->decltype(param.field_name)& { \ - return param.field_name; \ - } - -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_ALGORITHM, f.algorithm) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_BLOB_USAGE_REQUIREMENTS, f.keyBlobUsageRequirements) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_BLOCK_MODE, f.blockMode) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_DIGEST, f.digest) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_EC_CURVE, f.ecCurve) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_KDF, f.keyDerivationFunction) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_ORIGIN, f.origin) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_PADDING, f.paddingMode) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_PURPOSE, f.purpose) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_USER_AUTH_TYPE, f.hardwareAuthenticatorType) - -template -inline KeyParameter makeKeyParameter(TypedTag ttag, ValueT&& value) { - KeyParameter param; - param.tag = tag; - param.f.longInteger = 0; - accessTagValue(ttag, param) = std::forward(value); - return param; -} - -// the boolean case -template inline KeyParameter makeKeyParameter(TypedTag) { - KeyParameter param; - param.tag = tag; - param.f.boolValue = true; - return param; -} - -template struct FirstOrNoneHelper; -template struct FirstOrNoneHelper { typedef First type; }; -template <> struct FirstOrNoneHelper<> { - struct type {}; -}; - -template using FirstOrNone = typename FirstOrNoneHelper::type; - -template -inline KeyParameter Authorization(TypedTag ttag, Args&&... args) { - static_assert(tag_type != TagType::BOOL || (sizeof...(args) == 0), - "TagType::BOOL Authorizations do not take parameters. Presence is truth."); - static_assert(tag_type == TagType::BOOL || (sizeof...(args) == 1), - "Authorization other then TagType::BOOL take exactly one parameter."); - static_assert( - tag_type == TagType::BOOL || - std::is_convertible>>, - typename TypedTag2ValueType>::type>::value, - "Invalid argument type for given tag."); - - return makeKeyParameter(ttag, std::forward(args)...); -} - -/** - * This class wraps a (mostly return) value and stores whether or not the wrapped value is valid out - * of band. Note that if the wrapped value is a reference it is unsafe to access the value if - * !isOk(). If the wrapped type is a pointer or value and !isOk(), it is still safe to access the - * wrapped value. In this case the pointer will be NULL though, and the value will be default - * constructed. - */ -template class NullOr { - template struct reference_initializer { - static T&& init() { return *static_cast*>(nullptr); } - }; - template struct pointer_initializer { - static T init() { return nullptr; } - }; - template struct value_initializer { - static T init() { return T(); } - }; - template - using initializer_t = - std::conditional_t::value, reference_initializer, - std::conditional_t::value, pointer_initializer, - value_initializer>>; - - public: - NullOr() : value_(initializer_t::init()), null_(true) {} - NullOr(ValueT&& value) : value_(std::forward(value)), null_(false) {} - - bool isOk() const { return !null_; } - - const ValueT& value() const & { return value_; } - ValueT& value() & { return value_; } - ValueT&& value() && { return std::move(value_); } - - private: - ValueT value_; - bool null_; -}; - -template std::remove_reference_t NullOrOr(NullOr&& v) { - if (v.isOk()) return v; - return {}; -} - -template -std::remove_reference_t NullOrOr(Head&& head, Tail&&... tail) { - if (head.isOk()) return head; - return NullOrOr(std::forward(tail)...); -} - -template -std::remove_reference_t defaultOr(NullOr&& optional, Default&& def) { - static_assert(std::is_convertible, - std::remove_reference_t>::value, - "Type of default value must match the type wrapped by NullOr"); - if (optional.isOk()) return optional.value(); - return def; -} - -template -inline NullOr>::type&> -authorizationValue(TypedTag ttag, const KeyParameter& param) { - if (tag != param.tag) return {}; - return accessTagValue(ttag, param); -} - -inline const char* stringify(Digest digest) { - switch (digest) { - case Digest::NONE: - return "None"; - case Digest::MD5: - return "Md5"; - case Digest::SHA1: - return "Sha1"; - case Digest::SHA_2_224: - return "Sha224"; - case Digest::SHA_2_256: - return "Sha256"; - case Digest::SHA_2_384: - return "Sha384"; - case Digest::SHA_2_512: - return "Sha512"; - } - return "UNKNOWN DIGEST!"; -} - -inline const char* stringify(Algorithm algorithm) { - switch (algorithm) { - case Algorithm::RSA: - return "Rsa"; - case Algorithm::EC: - return "Ec"; - case Algorithm::AES: - return "Aes"; - case Algorithm::HMAC: - return "Hmac"; - } - return "UNKNOWN ALGORITHM"; -} - -inline const char* stringify(BlockMode block_mode) { - switch (block_mode) { - case BlockMode::ECB: - return "Ecb"; - case BlockMode::CBC: - return "Cbc"; - case BlockMode::CTR: - return "Ctr"; - case BlockMode::GCM: - return "Gcm"; - } - return "UNKNOWN BLOCK MODE"; -} - -inline const char* stringify(PaddingMode padding) { - switch (padding) { - case PaddingMode::NONE: - return "None"; - case PaddingMode::RSA_OAEP: - return "RsaOaep"; - case PaddingMode::RSA_PSS: - return "RsaPss"; - case PaddingMode::RSA_PKCS1_1_5_ENCRYPT: - return "RsaPkcs115Encrypt"; - case PaddingMode::RSA_PKCS1_1_5_SIGN: - return "RsaPkcs115Sign"; - case PaddingMode::PKCS7: - return "Pkcs7"; - } - return "UNKNOWN PADDING MODE"; -} - -inline const char* stringify(KeyOrigin origin) { - switch (origin) { - case KeyOrigin::GENERATED: - return "Generated"; - case KeyOrigin::DERIVED: - return "Derived"; - case KeyOrigin::IMPORTED: - return "Imported"; - case KeyOrigin::UNKNOWN: - return "UNKNOWN (keymaster0 didn't record it)"; - } - return "UNKOWN KEY ORIGIN VALUE"; -} - -inline const char* stringify(KeyPurpose purpose) { - switch (purpose) { - case KeyPurpose::ENCRYPT: - return "Encrypt"; - case KeyPurpose::DECRYPT: - return "Decrypt"; - case KeyPurpose::SIGN: - return "Sign"; - case KeyPurpose::VERIFY: - return "Verify"; - case KeyPurpose::DERIVE_KEY: - return "DeriveKey"; - case KeyPurpose::WRAP_KEY: - return "WrapKey"; - }; - return "UNKNOWN KEY PURPOSE"; -} - -inline const char* stringify(EcCurve curve) { - switch (curve) { - case EcCurve::P_224: - return "P_224"; - case EcCurve::P_256: - return "P_256"; - case EcCurve::P_384: - return "P_384"; - case EcCurve::P_521: - return "P_521"; - } - return "UNKNOWN EC CURVE"; -} - -} // namespace V3_0 -} // namespace keymaster -} // namespace hardware -} // namespace android - -#endif // SYSTEM_SECURITY_KEYSTORE_KEYMASTER_TAGS_H_ diff --git a/keymaster/3.0/vts/functional/keystore_tags_utils.cpp b/keymaster/3.0/vts/functional/keystore_tags_utils.cpp deleted file mode 100644 index 8dd99dba..00000000 --- a/keymaster/3.0/vts/functional/keystore_tags_utils.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* -** -** Copyright 2016, 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_tags.h" - -namespace android { -namespace hardware { -namespace keymaster { -namespace V3_0 { - -template struct TagStringifier; - -template struct TagStringifier> { - template - static TypedTag chooseString(TypedTag ttag, Tag runtime_tag, - const char** result) { - if (tag == runtime_tag) { - *result = Tag2String::value(); - } - return ttag; - } - static const char* stringify(Tag tag) { - const char* result = "unknown tag"; - [](Tags&&...) {}(chooseString(Tags(), tag, &result)...); - return result; - } -}; - -const char* stringifyTag(Tag tag) { - return TagStringifier::stringify(tag); -} - -} // namespace V3_0 -} // namespace keymaster -} // namespace hardware -} // namespace android diff --git a/keymaster/3.0/vts/functional/openssl_utils.h b/keymaster/3.0/vts/functional/openssl_utils.h deleted file mode 100644 index 2eba9baa..00000000 --- a/keymaster/3.0/vts/functional/openssl_utils.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2016 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. - */ - -template struct UniquePtrDeleter { - void operator()(T* p) const { F(p); } -}; - -typedef UniquePtrDeleter EVP_PKEY_Delete; - -#define MAKE_OPENSSL_PTR_TYPE(type) \ - typedef std::unique_ptr> type##_Ptr; - -MAKE_OPENSSL_PTR_TYPE(ASN1_OBJECT) -MAKE_OPENSSL_PTR_TYPE(EVP_PKEY) -MAKE_OPENSSL_PTR_TYPE(RSA) -MAKE_OPENSSL_PTR_TYPE(X509) -MAKE_OPENSSL_PTR_TYPE(BN_CTX) - -typedef std::unique_ptr> BIGNUM_Ptr; - -inline const EVP_MD* openssl_digest(android::hardware::keymaster::V3_0::Digest digest) { - switch (digest) { - case android::hardware::keymaster::V3_0::Digest::NONE: - return nullptr; - case android::hardware::keymaster::V3_0::Digest::MD5: - return EVP_md5(); - case android::hardware::keymaster::V3_0::Digest::SHA1: - return EVP_sha1(); - case android::hardware::keymaster::V3_0::Digest::SHA_2_224: - return EVP_sha224(); - case android::hardware::keymaster::V3_0::Digest::SHA_2_256: - return EVP_sha256(); - case android::hardware::keymaster::V3_0::Digest::SHA_2_384: - return EVP_sha384(); - case android::hardware::keymaster::V3_0::Digest::SHA_2_512: - return EVP_sha512(); - } - return nullptr; -} -- 2.11.0