From 7ba3d68a6b023ae602a6dba268da23de9d3b6899 Mon Sep 17 00:00:00 2001 From: "Yan, Shaopu" Date: Thu, 13 Sep 2018 23:19:38 +0800 Subject: [PATCH] fix the Attestation related CTS failed issue the below cases previous failed is due to we didn't implemented the related API(GenerateAttestation), now we uncomment it due to the depends on the AOSP part has been updated. test: testEcAttestation testRsaAttestation Change-Id: If0b7776cdc330233520b9111f3c6e7f557ad7985 Signed-off-by: Yan, Shaopu --- override/hmac_operation.cpp | 198 ----------------------------------- override/hmac_operation.h | 76 -------------- rules.mk | 3 +- trusty_keymaster_context.cpp | 64 +++-------- trusty_keymaster_context.h | 9 +- 5 files changed, 20 insertions(+), 330 deletions(-) delete mode 100644 override/hmac_operation.cpp delete mode 100644 override/hmac_operation.h diff --git a/override/hmac_operation.cpp b/override/hmac_operation.cpp deleted file mode 100644 index 8160567..0000000 --- a/override/hmac_operation.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#include - -#include -#include - -#include -#include -#include -#include "hmac_operation.h" - -#if defined(OPENSSL_IS_BORINGSSL) -#include -typedef size_t openssl_size_t; -#else -typedef int openssl_size_t; -#endif - -namespace keymaster { - -OperationPtr HmacOperationFactory::CreateOperation(Key&& key, const AuthorizationSet& begin_params, - keymaster_error_t* error) { - uint32_t min_mac_length_bits; - if (!key.authorizations().GetTagValue(TAG_MIN_MAC_LENGTH, &min_mac_length_bits)) { - LOG_E("HMAC key must have KM_TAG_MIN_MAC_LENGTH", 0); - *error = KM_ERROR_INVALID_KEY_BLOB; - return nullptr; - } - - uint32_t mac_length_bits = UINT32_MAX; - if (begin_params.GetTagValue(TAG_MAC_LENGTH, &mac_length_bits)) { - if (purpose() == KM_PURPOSE_VERIFY) { - LOG_E("MAC length may not be specified for verify", 0); - *error = KM_ERROR_INVALID_ARGUMENT; - return nullptr; - } - } else { - if (purpose() == KM_PURPOSE_SIGN) { - *error = KM_ERROR_MISSING_MAC_LENGTH; - return nullptr; - } - } - - keymaster_digest_t digest; - if (!key.authorizations().GetTagValue(TAG_DIGEST, &digest)) { - LOG_E("%d digests found in HMAC key authorizations; must be exactly 1", - begin_params.GetTagCount(TAG_DIGEST)); - *error = KM_ERROR_INVALID_KEY_BLOB; - return nullptr; - } -#if 0 - UniquePtr op(new (std::nothrow) HmacOperation( - move(key), purpose(), digest, mac_length_bits / 8, min_mac_length_bits / 8)); - if (!op.get()) - *error = KM_ERROR_MEMORY_ALLOCATION_FAILED; - else - *error = op->error(); - - if (*error != KM_ERROR_OK) return nullptr; -#endif - auto op = OperationPtr(new (std::nothrow) HmacOperation( - move(key), purpose(), digest, mac_length_bits / 8, min_mac_length_bits / 8)); - if (!op) - *error = KM_ERROR_MEMORY_ALLOCATION_FAILED; - return op; -} - -static keymaster_digest_t supported_digests[] = {KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224, - KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, - KM_DIGEST_SHA_2_512}; -const keymaster_digest_t* HmacOperationFactory::SupportedDigests(size_t* digest_count) const { - *digest_count = array_length(supported_digests); - return supported_digests; -} - -HmacOperation::HmacOperation(Key&& key, keymaster_purpose_t purpose, keymaster_digest_t digest, - size_t mac_length, size_t min_mac_length) - : Operation(purpose, key.hw_enforced_move(), key.sw_enforced_move()), error_(KM_ERROR_OK), - mac_length_(mac_length), min_mac_length_(min_mac_length) { - // Initialize CTX first, so dtor won't crash even if we error out later. - HMAC_CTX_init(&ctx_); - - const EVP_MD* md = nullptr; - switch (digest) { - case KM_DIGEST_NONE: - case KM_DIGEST_MD5: - error_ = KM_ERROR_UNSUPPORTED_DIGEST; - break; - case KM_DIGEST_SHA1: - md = EVP_sha1(); - break; - case KM_DIGEST_SHA_2_224: - md = EVP_sha224(); - break; - case KM_DIGEST_SHA_2_256: - md = EVP_sha256(); - break; - case KM_DIGEST_SHA_2_384: - md = EVP_sha384(); - break; - case KM_DIGEST_SHA_2_512: - md = EVP_sha512(); - break; - } - - if (md == nullptr) { - error_ = KM_ERROR_UNSUPPORTED_DIGEST; - return; - } - - if (purpose == KM_PURPOSE_SIGN) { - if (mac_length > EVP_MD_size(md) || mac_length < kMinHmacLengthBits / 8) { - error_ = KM_ERROR_UNSUPPORTED_MAC_LENGTH; - return; - } - if (mac_length < min_mac_length) { - error_ = KM_ERROR_INVALID_MAC_LENGTH; - return; - } - } - - KeymasterKeyBlob blob = key.key_material_move(); - HMAC_Init_ex(&ctx_, blob.key_material, blob.key_material_size, md, NULL /* engine */); -} - -HmacOperation::~HmacOperation() { - HMAC_CTX_cleanup(&ctx_); -} - -keymaster_error_t HmacOperation::Begin(const AuthorizationSet& /* input_params */, - AuthorizationSet* /* output_params */) { - auto rc = GenerateRandom(reinterpret_cast(&operation_handle_), - (size_t)sizeof(operation_handle_)); - if (rc != KM_ERROR_OK) return rc; - - return error_; -} - -keymaster_error_t HmacOperation::Update(const AuthorizationSet& /* additional_params */, - const Buffer& input, AuthorizationSet* /* output_params */, - Buffer* /* output */, size_t* input_consumed) { - if (!HMAC_Update(&ctx_, input.peek_read(), input.available_read())) - return TranslateLastOpenSslError(); - *input_consumed = input.available_read(); - return KM_ERROR_OK; -} - -keymaster_error_t HmacOperation::Abort() { - return KM_ERROR_OK; -} - -keymaster_error_t HmacOperation::Finish(const AuthorizationSet& additional_params, - const Buffer& input, const Buffer& signature, - AuthorizationSet* /* output_params */, Buffer* output) { - keymaster_error_t error = UpdateForFinish(additional_params, input); - if (error != KM_ERROR_OK) return error; - - uint8_t digest[EVP_MAX_MD_SIZE]; - unsigned int digest_len; - if (!HMAC_Final(&ctx_, digest, &digest_len)) return TranslateLastOpenSslError(); - - switch (purpose()) { - case KM_PURPOSE_SIGN: - if (mac_length_ > digest_len) return KM_ERROR_UNSUPPORTED_MAC_LENGTH; - if (!output->reserve(mac_length_) || !output->write(digest, mac_length_)) - return KM_ERROR_MEMORY_ALLOCATION_FAILED; - return KM_ERROR_OK; - case KM_PURPOSE_VERIFY: { - size_t siglen = signature.available_read(); - if (siglen > digest_len || siglen < kMinHmacLengthBits / 8) - return KM_ERROR_UNSUPPORTED_MAC_LENGTH; - if (siglen < min_mac_length_) return KM_ERROR_INVALID_MAC_LENGTH; - if (CRYPTO_memcmp(signature.peek_read(), digest, siglen) != 0) - return KM_ERROR_VERIFICATION_FAILED; - return KM_ERROR_OK; - } - default: - return KM_ERROR_UNSUPPORTED_PURPOSE; - } -} - -} // namespace keymaster diff --git a/override/hmac_operation.h b/override/hmac_operation.h deleted file mode 100644 index e67af93..0000000 --- a/override/hmac_operation.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SYSTEM_KEYMASTER_HMAC_OPERATION_H_ -#define SYSTEM_KEYMASTER_HMAC_OPERATION_H_ - -#include -#include - -namespace keymaster { - -class HmacOperation : public Operation { - public: - HmacOperation(Key&& key, keymaster_purpose_t purpose, keymaster_digest_t digest, - size_t mac_length, size_t min_mac_length); - ~HmacOperation(); - - virtual keymaster_error_t Begin(const AuthorizationSet& input_params, - AuthorizationSet* output_params); - virtual keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input, - AuthorizationSet* output_params, Buffer* output, - size_t* input_consumed); - virtual keymaster_error_t Abort(); - virtual keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input, - const Buffer& signature, AuthorizationSet* output_params, - Buffer* output); - - keymaster_error_t error() { return error_; } - - private: - HMAC_CTX ctx_; - keymaster_error_t error_; - const size_t mac_length_; - const size_t min_mac_length_; -}; - -/** - * Abstract base for HMAC operation factories. This class does all of the work to create - * HMAC operations. - */ -class HmacOperationFactory : public OperationFactory { - public: - virtual KeyType registry_key() const { return KeyType(KM_ALGORITHM_HMAC, purpose()); } - - virtual OperationPtr CreateOperation(Key&& key, const AuthorizationSet& begin_params, - keymaster_error_t* error); - - virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const; - - virtual keymaster_purpose_t purpose() const = 0; -}; - -class HmacSignOperationFactory : public HmacOperationFactory { - keymaster_purpose_t purpose() const { return KM_PURPOSE_SIGN; } -}; - -class HmacVerifyOperationFactory : public HmacOperationFactory { - keymaster_purpose_t purpose() const { return KM_PURPOSE_VERIFY; } -}; - -} // namespace keymaster - -#endif // SYSTEM_KEYMASTER_HMAC_OPERATION_H_ diff --git a/rules.mk b/rules.mk index 54ef441..57a14f8 100644 --- a/rules.mk +++ b/rules.mk @@ -35,7 +35,8 @@ MODULE_SRCS += \ $(KEYMASTER_ROOT)/km_openssl/ec_key_factory.cpp \ $(KEYMASTER_ROOT)/km_openssl/ecdsa_operation.cpp \ $(KEYMASTER_ROOT)/km_openssl/hmac_key.cpp \ - $(LOCAL_DIR)/override/hmac_operation.cpp \ + $(KEYMASTER_ROOT)/km_openssl/attestation_utils.cpp \ + $(KEYMASTER_ROOT)/km_openssl/hmac_operation.cpp \ $(KEYMASTER_ROOT)/android_keymaster/keymaster_enforcement.cpp \ $(KEYMASTER_ROOT)/android_keymaster/logger.cpp \ $(KEYMASTER_ROOT)/key_blob_utils/ocb.c \ diff --git a/trusty_keymaster_context.cpp b/trusty_keymaster_context.cpp index 34bd4d5..2741349 100644 --- a/trusty_keymaster_context.cpp +++ b/trusty_keymaster_context.cpp @@ -522,60 +522,29 @@ TrustyKeymasterContext::GetVerifiedBootParams(keymaster_blob_t* verified_boot_ke return KM_ERROR_OK; } -const keymaster_key_blob_t* TrustyKeymasterContext::getAttestationKey(keymaster_algorithm_t algorithm, - keymaster_error_t* error) const{ +KeymasterKeyBlob getAttestationKey(keymaster_algorithm_t algorithm, + keymaster_error_t* error) { uint8_t* key = nullptr; uint32_t key_size = 0; - UniquePtr key_deleter; - -#if 0 - int evp_key_type; - switch (algorithm) { - case KM_ALGORITHM_RSA: - evp_key_type = EVP_PKEY_RSA; - break; - - case KM_ALGORITHM_EC: - evp_key_type = EVP_PKEY_EC; - break; - - default: - *error = KM_ERROR_UNSUPPORTED_ALGORITHM; - return nullptr; - } -#endif *error = ReadKeyFromStorage(algorithm, &key, &key_size); - if (*error == KM_ERROR_OK) { - key_deleter.reset(key); - } else { + if (*error != KM_ERROR_OK) { LOG_E("Failed to read attestation key from RPMB, falling back to test key", 0); *error = GetSoftwareAttestationKey(algorithm, &key, &key_size); + if (*error != KM_ERROR_OK) + return {}; } - - if (*error != KM_ERROR_OK) - return nullptr; -#if 0 - const uint8_t* const_key = key; - - EVP_PKEY* pkey = d2i_PrivateKey(evp_key_type, nullptr, &const_key, key_size); - if (!pkey) - *error = TranslateLastOpenSslError(); - - return pkey; -#endif - static const keymaster_key_blob_t AttestKeyBlob = { - (const uint8_t*)key, key_size - }; - - return &AttestKeyBlob; + auto result = KeymasterKeyBlob(key, key_size); + if (!result.key_material) + *error = KM_ERROR_MEMORY_ALLOCATION_FAILED; + return result; } -keymaster_cert_chain_t* TrustyKeymasterContext::getAttestationChain(keymaster_algorithm_t algorithm, - keymaster_error_t* error) const{ +CertChainPtr getAttestationChain(keymaster_algorithm_t algorithm, + keymaster_error_t* error) { - UniquePtr chain(new keymaster_cert_chain_t); + CertChainPtr chain(new keymaster_cert_chain_t); if (!chain.get()) { *error = KM_ERROR_MEMORY_ALLOCATION_FAILED; return nullptr; @@ -594,9 +563,9 @@ keymaster_cert_chain_t* TrustyKeymasterContext::getAttestationChain(keymaster_al if (*error != KM_ERROR_OK) return nullptr; - return chain.release(); + return chain; } -#if 0 + keymaster_error_t TrustyKeymasterContext::GenerateAttestation(const Key& key, const AuthorizationSet& attest_params, CertChainPtr* cert_chain) const { @@ -620,9 +589,10 @@ keymaster_error_t TrustyKeymasterContext::GenerateAttestation(const Key& key, if (error != KM_ERROR_OK) return error; return generate_attestation(asymmetric_key, attest_params, - *attestation_chain, *attestation_key, *this, cert_chain); + *attestation_chain, attestation_key, *this, + cert_chain); } -#endif + keymaster_error_t TrustyKeymasterContext::SetBootParams( uint32_t os_version, uint32_t os_patchlevel, const Buffer& verified_boot_key, keymaster_verified_boot_t verified_boot_state, bool device_locked) { diff --git a/trusty_keymaster_context.h b/trusty_keymaster_context.h index 7b4dc8b..af24a84 100644 --- a/trusty_keymaster_context.h +++ b/trusty_keymaster_context.h @@ -86,9 +86,7 @@ class TrustyKeymasterContext : public KeymasterContext, keymaster_error_t GenerateAttestation(const Key& key, const AuthorizationSet& attest_params, - CertChainPtr* cert_chain) const override { - return KM_ERROR_UNIMPLEMENTED; - } + CertChainPtr* cert_chain) const override; keymaster_error_t GenerateUniqueId(uint64_t creation_date_time, const keymaster_blob_t& application_id, @@ -145,11 +143,6 @@ class TrustyKeymasterContext : public KeymasterContext, keymaster_error_t ParseKeyboxToStorage(keymaster_algorithm_t algorithm, XMLElement* xml_root); - keymaster_cert_chain_t* getAttestationChain(keymaster_algorithm_t algorithm, - keymaster_error_t* error) const; - const keymaster_key_blob_t* getAttestationKey(keymaster_algorithm_t algorithm, - keymaster_error_t* error) const; - TrustyKeymasterEnforcement enforcement_policy_; UniquePtr aes_factory_;