diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-06-20 20:34:40 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-06-20 20:34:40 +0000 |
commit | f8bd6a844321fed24df9d2fc81803180072a96e6 (patch) | |
tree | aef41f00df31d1f410e7f550f12af27c824b32b3 | |
parent | 70423cc839a6a9211c69c07978e4059d2b39885f (diff) | |
parent | 55cf90f07311695353ac110c7428e1a6cca42644 (diff) | |
download | keymaster-android13-mainline-art-release.tar.gz |
Snap for 8746144 from 55cf90f07311695353ac110c7428e1a6cca42644 to mainline-art-releaseaml_art_331813100aml_art_331813010aml_art_331711080aml_art_331612010aml_art_331413030aml_art_331314010aml_art_331113000aml_art_331012050android13-mainline-art-release
Change-Id: I123ea2745e1723adc36de35e64273e6208998c77
29 files changed, 260 insertions, 82 deletions
diff --git a/android_keymaster/android_keymaster.cpp b/android_keymaster/android_keymaster.cpp index 30e5505..420bbf2 100644 --- a/android_keymaster/android_keymaster.cpp +++ b/android_keymaster/android_keymaster.cpp @@ -28,6 +28,7 @@ #include <keymaster/UniquePtr.h> #include <keymaster/android_keymaster_utils.h> +#include <keymaster/attestation_context.h> #include <keymaster/cppcose/cppcose.h> #include <keymaster/key.h> #include <keymaster/key_blob_utils/ae.h> @@ -128,7 +129,12 @@ cppcose::HmacSha256Function getMacFunction(bool test_mode, }; } +std::pair<const uint8_t*, size_t> blob2Pair(const keymaster_blob_t& blob) { + return {blob.data, blob.data_length}; +} + constexpr int kP256AffinePointSize = 32; +constexpr int kRoTVersion1 = 40001; } // anonymous namespace @@ -932,4 +938,64 @@ DeviceLockedResponse AndroidKeymaster::DeviceLocked(const DeviceLockedRequest& r return response; } +GetRootOfTrustResponse AndroidKeymaster::GetRootOfTrust(const GetRootOfTrustRequest& request) { + GetRootOfTrustResponse response(message_version()); + + if (!context_->attestation_context()) { + LOG_E("Have no attestation context, cannot get RootOfTrust", 0); + response.error = KM_ERROR_UNIMPLEMENTED; + return response; + } + + const AttestationContext::VerifiedBootParams* vbParams = + context_->attestation_context()->GetVerifiedBootParams(&response.error); + if (response.error != KM_ERROR_OK) { + LOG_E("Error retrieving verified boot params: %lu", response.error); + return response; + } + + auto boot_patch_level = context_->GetBootPatchlevel(); + if (!boot_patch_level) { + LOG_E("Error retrieving boot patch level: %lu", response.error); + response.error = KM_ERROR_UNIMPLEMENTED; + return response; + } + + if (!context_->enforcement_policy()) { + LOG_E("Have no enforcement policy, cannot get RootOfTrust", 0); + response.error = KM_ERROR_UNIMPLEMENTED; + return response; + } + + auto macFunction = + [&](const std::vector<uint8_t>& data) -> cppcose::ErrMsgOr<cppcose::HmacSha256> { + auto mac = context_->enforcement_policy()->ComputeHmac(data); + if (!mac) return "Failed to compute HMAC"; + return *std::move(mac); + }; + + auto maced_root_of_trust = cppcose::constructCoseMac0( + macFunction, // + request.challenge, + cppbor::SemanticTag(kRoTVersion1, cppbor::Array( // + blob2Pair(vbParams->verified_boot_key), // + vbParams->device_locked, // + vbParams->verified_boot_state, // + blob2Pair(vbParams->verified_boot_hash), // + *boot_patch_level)) + .encode()); + + if (!maced_root_of_trust) { + LOG_E("Error MACing RoT: %s", maced_root_of_trust.message().c_str()); + response.error = KM_ERROR_UNKNOWN_ERROR; + } else { + response.error = KM_ERROR_OK; + response.rootOfTrust = + cppbor::SemanticTag(cppcose::kCoseMac0SemanticTag, *std::move(maced_root_of_trust)) + .encode(); + } + + return response; +} + } // namespace keymaster diff --git a/contexts/keymaster1_passthrough_context.cpp b/contexts/keymaster1_passthrough_context.cpp index 5c82633..02c4623 100644 --- a/contexts/keymaster1_passthrough_context.cpp +++ b/contexts/keymaster1_passthrough_context.cpp @@ -38,7 +38,7 @@ Keymaster1PassthroughContext::Keymaster1PassthroughContext(KmVersion version, keymaster1_device_t* dev) : SoftAttestationContext(version), device_(dev), pt_engine_(KeymasterPassthroughEngine::createInstance(dev)), - km1_engine_(new Keymaster1Engine(dev)) {} + km1_engine_(new (std::nothrow) Keymaster1Engine(dev)) {} keymaster_error_t Keymaster1PassthroughContext::SetSystemVersion(uint32_t os_version, uint32_t os_patchlevel) { @@ -58,22 +58,22 @@ KeyFactory* Keymaster1PassthroughContext::GetKeyFactory(keymaster_algorithm_t al if (!result) { switch (algorithm) { case KM_ALGORITHM_RSA: - result.reset(new Keymaster1ArbitrationFactory<RsaKeymaster1KeyFactory>( + result.reset(new (std::nothrow) Keymaster1ArbitrationFactory<RsaKeymaster1KeyFactory>( pt_engine_.get(), KM_ALGORITHM_RSA, device_, *this /* blob_maker */, *this /* context */, km1_engine_.get())); break; case KM_ALGORITHM_EC: - result.reset(new Keymaster1ArbitrationFactory<EcdsaKeymaster1KeyFactory>( + result.reset(new (std::nothrow) Keymaster1ArbitrationFactory<EcdsaKeymaster1KeyFactory>( pt_engine_.get(), KM_ALGORITHM_EC, device_, *this /* blob_maker */, *this /* context */, km1_engine_.get())); break; case KM_ALGORITHM_AES: - result.reset(new Keymaster1ArbitrationFactory<AesKeyFactory>( + result.reset(new (std::nothrow) Keymaster1ArbitrationFactory<AesKeyFactory>( pt_engine_.get(), KM_ALGORITHM_AES, device_, *this /* blob_maker */, *this /* random_source */)); break; case KM_ALGORITHM_HMAC: - result.reset(new Keymaster1ArbitrationFactory<HmacKeyFactory>( + result.reset(new (std::nothrow) Keymaster1ArbitrationFactory<HmacKeyFactory>( pt_engine_.get(), KM_ALGORITHM_HMAC, device_, *this /* blob_maker */, *this /* random_source */)); break; @@ -152,7 +152,7 @@ Keymaster1PassthroughContext::ParseKeyBlob(const KeymasterKeyBlob& blob, BuildHiddenAuthorizations(additional_params, &hidden, softwareRootOfTrust); if (error != KM_ERROR_OK) return error; - // Assume it's an integrity-assured blob (new software-only blob + // Assume it's an integrity-assured blob (new software-only blob). error = DeserializeIntegrityAssuredBlob(blob, hidden, &key_material, &hw_enforced, &sw_enforced); if (error != KM_ERROR_INVALID_KEY_BLOB && error != KM_ERROR_OK) return error; diff --git a/contexts/keymaster2_passthrough_context.cpp b/contexts/keymaster2_passthrough_context.cpp index fe83de8..75ed9b6 100644 --- a/contexts/keymaster2_passthrough_context.cpp +++ b/contexts/keymaster2_passthrough_context.cpp @@ -42,7 +42,7 @@ void Keymaster2PassthroughContext::GetSystemVersion(uint32_t* os_version, KeyFactory* Keymaster2PassthroughContext::GetKeyFactory(keymaster_algorithm_t algorithm) const { auto& result = factories_[algorithm]; if (!result) { - result.reset(new KeymasterPassthroughKeyFactory(engine_.get(), algorithm)); + result.reset(new (std::nothrow) KeymasterPassthroughKeyFactory(engine_.get(), algorithm)); } return result.get(); } diff --git a/contexts/pure_soft_keymaster_context.cpp b/contexts/pure_soft_keymaster_context.cpp index e9d8245..937238b 100644 --- a/contexts/pure_soft_keymaster_context.cpp +++ b/contexts/pure_soft_keymaster_context.cpp @@ -54,11 +54,14 @@ PureSoftKeymasterContext::PureSoftKeymasterContext(KmVersion version, keymaster_security_level_t security_level) : SoftAttestationContext(version), - rsa_factory_(new RsaKeyFactory(*this /* blob_maker */, *this /* context */)), - ec_factory_(new EcKeyFactory(*this /* blob_maker */, *this /* context */)), - aes_factory_(new AesKeyFactory(*this /* blob_maker */, *this /* random_source */)), - tdes_factory_(new TripleDesKeyFactory(*this /* blob_maker */, *this /* random_source */)), - hmac_factory_(new HmacKeyFactory(*this /* blob_maker */, *this /* random_source */)), + rsa_factory_(new (std::nothrow) RsaKeyFactory(*this /* blob_maker */, *this /* context */)), + ec_factory_(new (std::nothrow) EcKeyFactory(*this /* blob_maker */, *this /* context */)), + aes_factory_(new (std::nothrow) + AesKeyFactory(*this /* blob_maker */, *this /* random_source */)), + tdes_factory_(new (std::nothrow) + TripleDesKeyFactory(*this /* blob_maker */, *this /* random_source */)), + hmac_factory_(new (std::nothrow) + HmacKeyFactory(*this /* blob_maker */, *this /* random_source */)), os_version_(0), os_patchlevel_(0), soft_keymaster_enforcement_(64, 64), security_level_(security_level) { // We're pretending to be some sort of secure hardware which supports secure key storage, diff --git a/contexts/soft_keymaster_context.cpp b/contexts/soft_keymaster_context.cpp index 86bdd3f..66c1a57 100644 --- a/contexts/soft_keymaster_context.cpp +++ b/contexts/soft_keymaster_context.cpp @@ -52,11 +52,14 @@ KeymasterBlob string2Blob(const std::string& str) { SoftKeymasterContext::SoftKeymasterContext(KmVersion version, const std::string& root_of_trust) : SoftAttestationContext(version), // - rsa_factory_(new RsaKeyFactory(*this /* blob_maker */, *this /* context */)), - ec_factory_(new EcKeyFactory(*this /* blob_maker */, *this /* context */)), - aes_factory_(new AesKeyFactory(*this /* blob_maker */, *this /* random_source */)), - tdes_factory_(new TripleDesKeyFactory(*this /* blob_maker */, *this /* random_source */)), - hmac_factory_(new HmacKeyFactory(*this /* blob_maker */, *this /* random_source */)), + rsa_factory_(new (std::nothrow) RsaKeyFactory(*this /* blob_maker */, *this /* context */)), + ec_factory_(new (std::nothrow) EcKeyFactory(*this /* blob_maker */, *this /* context */)), + aes_factory_(new (std::nothrow) + AesKeyFactory(*this /* blob_maker */, *this /* random_source */)), + tdes_factory_(new (std::nothrow) + TripleDesKeyFactory(*this /* blob_maker */, *this /* random_source */)), + hmac_factory_(new (std::nothrow) + HmacKeyFactory(*this /* blob_maker */, *this /* random_source */)), km1_dev_(nullptr), root_of_trust_(string2Blob(root_of_trust)), os_version_(0), os_patchlevel_(0) {} @@ -67,10 +70,10 @@ keymaster_error_t SoftKeymasterContext::SetHardwareDevice(keymaster1_device_t* k km1_dev_ = keymaster1_device; - km1_engine_.reset(new Keymaster1Engine(keymaster1_device)); - rsa_factory_.reset(new RsaKeymaster1KeyFactory( + km1_engine_.reset(new (std::nothrow) Keymaster1Engine(keymaster1_device)); + rsa_factory_.reset(new (std::nothrow) RsaKeymaster1KeyFactory( *this /* blob_maker */, *this /* attestation_context */, km1_engine_.get())); - ec_factory_.reset(new EcdsaKeymaster1KeyFactory( + ec_factory_.reset(new (std::nothrow) EcdsaKeymaster1KeyFactory( *this /* blob_maker */, *this /* attestation_context */, km1_engine_.get())); // Use default HMAC and AES key factories. Higher layers will pass HMAC/AES keys/ops that are diff --git a/contexts/soft_keymaster_device.cpp b/contexts/soft_keymaster_device.cpp index 71b0dd1..45c5b2a 100644 --- a/contexts/soft_keymaster_device.cpp +++ b/contexts/soft_keymaster_device.cpp @@ -158,8 +158,9 @@ static keymaster_error_t map_digests(keymaster1_device_t* dev, SoftKeymasterDevi } SoftKeymasterDevice::SoftKeymasterDevice(KmVersion version) - : wrapped_km1_device_(nullptr), context_(new SoftKeymasterContext(version)), - impl_(new AndroidKeymaster(context_, kOperationTableSize)), configured_(false) { + : wrapped_km1_device_(nullptr), context_(new (std::nothrow) SoftKeymasterContext(version)), + impl_(new (std::nothrow) AndroidKeymaster(context_, kOperationTableSize)), + configured_(false) { LOG_I("Creating device", 0); LOG_D("Device address: %p", this); @@ -169,7 +170,8 @@ SoftKeymasterDevice::SoftKeymasterDevice(KmVersion version) SoftKeymasterDevice::SoftKeymasterDevice(SoftKeymasterContext* context) : wrapped_km1_device_(nullptr), context_(context), - impl_(new AndroidKeymaster(context_, kOperationTableSize)), configured_(false) { + impl_(new (std::nothrow) AndroidKeymaster(context_, kOperationTableSize)), + configured_(false) { LOG_I("Creating test device", 0); LOG_D("Device address: %p", this); diff --git a/include/keymaster/android_keymaster.h b/include/keymaster/android_keymaster.h index d8033b4..6c3acc5 100644 --- a/include/keymaster/android_keymaster.h +++ b/include/keymaster/android_keymaster.h @@ -99,6 +99,7 @@ class AndroidKeymaster { ConfigureBootPatchlevel(const ConfigureBootPatchlevelRequest& request); ConfigureVerifiedBootInfoResponse ConfigureVerifiedBootInfo(const ConfigureVerifiedBootInfoRequest& request); + GetRootOfTrustResponse GetRootOfTrust(const GetRootOfTrustRequest& request); bool has_operation(keymaster_operation_handle_t op_handle) const; diff --git a/include/keymaster/android_keymaster_messages.h b/include/keymaster/android_keymaster_messages.h index 7d43043..6e38860 100644 --- a/include/keymaster/android_keymaster_messages.h +++ b/include/keymaster/android_keymaster_messages.h @@ -68,6 +68,7 @@ enum AndroidKeymasterCommand : uint32_t { CONFIGURE_VENDOR_PATCHLEVEL = 32, CONFIGURE_BOOT_PATCHLEVEL = 33, CONFIGURE_VERIFIED_BOOT_INFO = 34, + GET_ROOT_OF_TRUST = 35, }; /** @@ -838,7 +839,8 @@ struct ComputeSharedHmacRequest : public KeymasterMessage { struct ComputeSharedHmacResponse : public KeymasterResponse { explicit ComputeSharedHmacResponse(int32_t ver) : KeymasterResponse(ver) {} - ComputeSharedHmacResponse(ComputeSharedHmacResponse&& other) : KeymasterResponse(move(other)) { + ComputeSharedHmacResponse(ComputeSharedHmacResponse&& other) + : KeymasterResponse(other.message_version) { sharing_check = move(other.sharing_check); } @@ -1215,4 +1217,36 @@ struct ConfigureVerifiedBootInfoRequest : public KeymasterMessage { using ConfigureVerifiedBootInfoResponse = EmptyKeymasterResponse; +struct GetRootOfTrustRequest : public KeymasterMessage { + explicit GetRootOfTrustRequest(int32_t ver) : GetRootOfTrustRequest(ver, {}) {} + GetRootOfTrustRequest(int32_t ver, std::vector<uint8_t> challenge_param) + : KeymasterMessage(ver), challenge(std::move(challenge_param)){}; + + size_t SerializedSize() const override { return sizeof(uint32_t) + challenge.size(); } + uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override { + return append_collection_to_buf(buf, end, challenge); + } + bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override { + return copy_collection_from_buf(buf_ptr, end, &challenge); + } + + std::vector<uint8_t> challenge; +}; + +struct GetRootOfTrustResponse : public KeymasterResponse { + explicit GetRootOfTrustResponse(uint32_t ver) : GetRootOfTrustResponse(ver, {}) {} + GetRootOfTrustResponse(uint32_t ver, std::vector<uint8_t> rootOfTrust_param) + : KeymasterResponse(ver), rootOfTrust(std::move(rootOfTrust_param)){}; + + size_t NonErrorSerializedSize() const override { return sizeof(uint32_t) + rootOfTrust.size(); } + uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const override { + return append_collection_to_buf(buf, end, rootOfTrust); + } + bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) override { + return copy_collection_from_buf(buf_ptr, end, &rootOfTrust); + } + + std::vector<uint8_t> rootOfTrust; +}; + } // namespace keymaster diff --git a/include/keymaster/android_keymaster_utils.h b/include/keymaster/android_keymaster_utils.h index a23694b..324287a 100644 --- a/include/keymaster/android_keymaster_utils.h +++ b/include/keymaster/android_keymaster_utils.h @@ -326,7 +326,7 @@ struct CertificateChain : public keymaster_cert_chain_t { // Insert the provided blob at the front of the chain. CertificateChain takes ownership of the // contents of `new_entry`. bool push_front(const keymaster_blob_t& new_entry) { - keymaster_blob_t* new_entries = new keymaster_blob_t[entry_count + 1]; + keymaster_blob_t* new_entries = new (std::nothrow) keymaster_blob_t[entry_count + 1]; if (!new_entries) return false; new_entries[0] = new_entry; diff --git a/include/keymaster/cppcose/cppcose.h b/include/keymaster/cppcose/cppcose.h index 5803d2d..c000ebe 100644 --- a/include/keymaster/cppcose/cppcose.h +++ b/include/keymaster/cppcose/cppcose.h @@ -66,6 +66,8 @@ constexpr int kCoseEncryptUnprotectedParams = 1; constexpr int kCoseEncryptPayload = 2; constexpr int kCoseEncryptRecipients = 3; +constexpr int kCoseMac0SemanticTag = 17; + enum Label : int { ALGORITHM = 1, KEY_ID = 4, diff --git a/include/keymaster/keymaster_context.h b/include/keymaster/keymaster_context.h index 052ccf2..8c4bb57 100644 --- a/include/keymaster/keymaster_context.h +++ b/include/keymaster/keymaster_context.h @@ -23,6 +23,7 @@ #include <assert.h> #include <hardware/keymaster_defs.h> + #include <keymaster/android_keymaster_utils.h> #include <keymaster/keymaster_enforcement.h> #include <keymaster/km_version.h> @@ -32,6 +33,7 @@ namespace keymaster { class AuthorizationSet; +class AttestationContext; class KeyFactory; class OperationFactory; class SecureDeletionSecretStorage; @@ -151,6 +153,11 @@ class KeymasterContext { virtual KeymasterEnforcement* enforcement_policy() = 0; /** + * Return the attestation context for this context. + */ + virtual AttestationContext* attestation_context() { return nullptr; } + + /** * Generate an attestation certificate, with chain. * * If attest_key is null, the certificate will be signed with the factory attestation key (from diff --git a/include/keymaster/keymaster_enforcement.h b/include/keymaster/keymaster_enforcement.h index 1d783ba..5400d8f 100644 --- a/include/keymaster/keymaster_enforcement.h +++ b/include/keymaster/keymaster_enforcement.h @@ -17,10 +17,13 @@ #ifndef ANDROID_LIBRARY_KEYMASTER_ENFORCEMENT_H #define ANDROID_LIBRARY_KEYMASTER_ENFORCEMENT_H +#include <array> + #include <stdio.h> #include <keymaster/android_keymaster_messages.h> #include <keymaster/authorization_set.h> +#include <keymaster/keymaster_utils.h> namespace keymaster { @@ -181,6 +184,16 @@ class KeymasterEnforcement { virtual keymaster_error_t GenerateTimestampToken(TimestampToken* token); /** + * Compute an HMAC using the auth token HMAC key. + * + * Note: Use with caution. MACed data must contain enough structure that it's unambiguous. + */ + virtual KmErrorOr<std::array<uint8_t, 32>> + ComputeHmac(const std::vector<uint8_t>& /* data_to_mac */) const { + return KM_ERROR_UNIMPLEMENTED; + } + + /** * Creates a key ID for use in subsequent calls to AuthorizeOperation. AndroidKeymaster * uses this method for creating key IDs. The generated id must be stable in that the same * key_blob bits yield the same keyid. diff --git a/include/keymaster/keymaster_utils.h b/include/keymaster/keymaster_utils.h index 1cfc756..8154c71 100644 --- a/include/keymaster/keymaster_utils.h +++ b/include/keymaster/keymaster_utils.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#pragma once + #include <optional> #include <keymaster/logger.h> @@ -88,8 +90,7 @@ template <typename T> class KmErrorOr { T& operator*() & { return value_.value(); } const T& operator*() const& { return value_.value(); } - T&& operator*() && { return value_.value(); } - const T&& operator*() const&& { return value_.value(); } + T&& operator*() && { return std::move(value_).value(); } private: keymaster_error_t error_ = KM_ERROR_OK; diff --git a/km_openssl/ec_key_factory.cpp b/km_openssl/ec_key_factory.cpp index 2e0e2f1..4ec3175 100644 --- a/km_openssl/ec_key_factory.cpp +++ b/km_openssl/ec_key_factory.cpp @@ -234,12 +234,18 @@ keymaster_error_t EcKeyFactory::ImportKey(const AuthorizationSet& key_descriptio switch (EVP_PKEY_type(pkey->type)) { case EVP_PKEY_ED25519: key.reset(new (std::nothrow) Ed25519Key(*hw_enforced, *sw_enforced, this)); + if (key.get() == nullptr) { + return KM_ERROR_MEMORY_ALLOCATION_FAILED; + } if (!key->EvpToInternal(pkey.get())) { return KM_ERROR_UNSUPPORTED_KEY_FORMAT; } break; case EVP_PKEY_X25519: key.reset(new (std::nothrow) X25519Key(*hw_enforced, *sw_enforced, this)); + if (key.get() == nullptr) { + return KM_ERROR_MEMORY_ALLOCATION_FAILED; + } if (!key->EvpToInternal(pkey.get())) { return KM_ERROR_UNSUPPORTED_KEY_FORMAT; } @@ -249,6 +255,9 @@ keymaster_error_t EcKeyFactory::ImportKey(const AuthorizationSet& key_descriptio if (!ec_key.get()) return KM_ERROR_INVALID_ARGUMENT; key.reset(new (std::nothrow) EcKey(*hw_enforced, *sw_enforced, this, move(ec_key))); + if (key.get() == nullptr) { + return KM_ERROR_MEMORY_ALLOCATION_FAILED; + } break; } default: diff --git a/legacy_support/ec_keymaster1_key.cpp b/legacy_support/ec_keymaster1_key.cpp index fa4dc07..ddb3725 100644 --- a/legacy_support/ec_keymaster1_key.cpp +++ b/legacy_support/ec_keymaster1_key.cpp @@ -31,9 +31,9 @@ EcdsaKeymaster1KeyFactory::EcdsaKeymaster1KeyFactory(const SoftwareKeyBlobMaker& const KeymasterContext& context, const Keymaster1Engine* engine) : EcKeyFactory(blob_maker, context), engine_(engine), - sign_factory_(new EcdsaKeymaster1OperationFactory(KM_PURPOSE_SIGN, engine)), + sign_factory_(new (std::nothrow) EcdsaKeymaster1OperationFactory(KM_PURPOSE_SIGN, engine)), // For pubkey ops we can use the normal operation factories. - verify_factory_(new EcdsaVerifyOperationFactory) {} + verify_factory_(new (std::nothrow) EcdsaVerifyOperationFactory) {} static bool is_supported(uint32_t digest) { return digest == KM_DIGEST_NONE || digest == KM_DIGEST_SHA_2_256; diff --git a/legacy_support/ecdsa_keymaster1_operation.cpp b/legacy_support/ecdsa_keymaster1_operation.cpp index ede1b3f..bb8b041 100644 --- a/legacy_support/ecdsa_keymaster1_operation.cpp +++ b/legacy_support/ecdsa_keymaster1_operation.cpp @@ -104,7 +104,7 @@ OperationPtr EcdsaKeymaster1OperationFactory::CreateOperation(Key&& key, switch (purpose_) { case KM_PURPOSE_SIGN: - return OperationPtr(new EcdsaKeymaster1Operation<EcdsaSignOperation>( + return OperationPtr(new (std::nothrow) EcdsaKeymaster1Operation<EcdsaSignOperation>( key.hw_enforced_move(), key.sw_enforced_move(), digest, ecdsa.release(), engine_)); default: LOG_E( diff --git a/legacy_support/keymaster1_engine.cpp b/legacy_support/keymaster1_engine.cpp index 28a64ad..4cd16e5 100644 --- a/legacy_support/keymaster1_engine.cpp +++ b/legacy_support/keymaster1_engine.cpp @@ -135,7 +135,7 @@ RSA* Keymaster1Engine::BuildRsaKey(const KeymasterKeyBlob& blob, return nullptr; } - KeyData* key_data = new KeyData(blob, additional_params); + KeyData* key_data = new (std::nothrow) KeyData(blob, additional_params); if (!RSA_set_ex_data(rsa.get(), rsa_index_, key_data)) { *error = TranslateLastOpenSslError(); delete key_data; @@ -174,7 +174,7 @@ EC_KEY* Keymaster1Engine::BuildEcKey(const KeymasterKeyBlob& blob, return nullptr; } - KeyData* key_data = new KeyData(blob, additional_params); + KeyData* key_data = new (std::nothrow) KeyData(blob, additional_params); if (!EC_KEY_set_ex_data(ec_key.get(), ec_key_index_, key_data)) { *error = TranslateLastOpenSslError(); delete key_data; @@ -238,7 +238,7 @@ int Keymaster1Engine::duplicate_key_data(CRYPTO_EX_DATA* /* to */, const CRYPTO_ if (!data) return 1; // Default copy ctor is good. - *from_d = new KeyData(*data); + *from_d = new (std::nothrow) KeyData(*data); if (*from_d) return 1; return 0; } diff --git a/legacy_support/keymaster_passthrough_engine.cpp b/legacy_support/keymaster_passthrough_engine.cpp index ed22320..d966d71 100644 --- a/legacy_support/keymaster_passthrough_engine.cpp +++ b/legacy_support/keymaster_passthrough_engine.cpp @@ -45,33 +45,35 @@ class TKeymasterPassthroughEngine : public KeymasterPassthroughEngine { explicit TKeymasterPassthroughEngine(const KeymasterDeviceType* km_device) : km_device_(km_device) { rsa_encrypt_op_factory_.reset( - new opfactory_t(KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT, km_device_)); + new (std::nothrow) opfactory_t(KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT, km_device_)); rsa_decrypt_op_factory_.reset( - new opfactory_t(KM_ALGORITHM_RSA, KM_PURPOSE_DECRYPT, km_device_)); - rsa_sign_op_factory_.reset(new opfactory_t(KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, km_device_)); + new (std::nothrow) opfactory_t(KM_ALGORITHM_RSA, KM_PURPOSE_DECRYPT, km_device_)); + rsa_sign_op_factory_.reset(new (std::nothrow) + opfactory_t(KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, km_device_)); rsa_verify_op_factory_.reset( - new opfactory_t(KM_ALGORITHM_RSA, KM_PURPOSE_VERIFY, km_device_)); + new (std::nothrow) opfactory_t(KM_ALGORITHM_RSA, KM_PURPOSE_VERIFY, km_device_)); ec_encrypt_op_factory_.reset( - new opfactory_t(KM_ALGORITHM_EC, KM_PURPOSE_ENCRYPT, km_device_)); + new (std::nothrow) opfactory_t(KM_ALGORITHM_EC, KM_PURPOSE_ENCRYPT, km_device_)); ec_decrypt_op_factory_.reset( - new opfactory_t(KM_ALGORITHM_EC, KM_PURPOSE_DECRYPT, km_device_)); - ec_sign_op_factory_.reset(new opfactory_t(KM_ALGORITHM_EC, KM_PURPOSE_SIGN, km_device_)); + new (std::nothrow) opfactory_t(KM_ALGORITHM_EC, KM_PURPOSE_DECRYPT, km_device_)); + ec_sign_op_factory_.reset(new (std::nothrow) + opfactory_t(KM_ALGORITHM_EC, KM_PURPOSE_SIGN, km_device_)); ec_verify_op_factory_.reset( - new opfactory_t(KM_ALGORITHM_EC, KM_PURPOSE_VERIFY, km_device_)); + new (std::nothrow) opfactory_t(KM_ALGORITHM_EC, KM_PURPOSE_VERIFY, km_device_)); ec_derive_op_factory_.reset( - new opfactory_t(KM_ALGORITHM_EC, KM_PURPOSE_DERIVE_KEY, km_device_)); + new (std::nothrow) opfactory_t(KM_ALGORITHM_EC, KM_PURPOSE_DERIVE_KEY, km_device_)); aes_encrypt_op_factory_.reset( - new opfactory_t(KM_ALGORITHM_AES, KM_PURPOSE_ENCRYPT, km_device_)); + new (std::nothrow) opfactory_t(KM_ALGORITHM_AES, KM_PURPOSE_ENCRYPT, km_device_)); aes_decrypt_op_factory_.reset( - new opfactory_t(KM_ALGORITHM_AES, KM_PURPOSE_DECRYPT, km_device_)); - triple_des_encrypt_op_factory_.reset( - new opfactory_t(KM_ALGORITHM_TRIPLE_DES, KM_PURPOSE_ENCRYPT, km_device_)); - triple_des_decrypt_op_factory_.reset( - new opfactory_t(KM_ALGORITHM_TRIPLE_DES, KM_PURPOSE_DECRYPT, km_device_)); + new (std::nothrow) opfactory_t(KM_ALGORITHM_AES, KM_PURPOSE_DECRYPT, km_device_)); + triple_des_encrypt_op_factory_.reset(new (std::nothrow) opfactory_t( + KM_ALGORITHM_TRIPLE_DES, KM_PURPOSE_ENCRYPT, km_device_)); + triple_des_decrypt_op_factory_.reset(new (std::nothrow) opfactory_t( + KM_ALGORITHM_TRIPLE_DES, KM_PURPOSE_DECRYPT, km_device_)); hmac_sign_op_factory_.reset( - new opfactory_t(KM_ALGORITHM_HMAC, KM_PURPOSE_SIGN, km_device_)); + new (std::nothrow) opfactory_t(KM_ALGORITHM_HMAC, KM_PURPOSE_SIGN, km_device_)); hmac_verify_op_factory_.reset( - new opfactory_t(KM_ALGORITHM_HMAC, KM_PURPOSE_VERIFY, km_device_)); + new (std::nothrow) opfactory_t(KM_ALGORITHM_HMAC, KM_PURPOSE_VERIFY, km_device_)); } virtual ~TKeymasterPassthroughEngine() { // QUIRK: we only take ownership if this is a KM2 device. @@ -294,10 +296,10 @@ keymaster_error_t TKeymasterPassthroughEngine<keymaster2_device_t>::ImportKey( typedef UniquePtr<KeymasterPassthroughEngine> engine_ptr_t; engine_ptr_t KeymasterPassthroughEngine::createInstance(const keymaster1_device_t* dev) { - return engine_ptr_t(new TKeymasterPassthroughEngine<keymaster1_device_t>(dev)); + return engine_ptr_t(new (std::nothrow) TKeymasterPassthroughEngine<keymaster1_device_t>(dev)); } engine_ptr_t KeymasterPassthroughEngine::createInstance(const keymaster2_device_t* dev) { - return engine_ptr_t(new TKeymasterPassthroughEngine<keymaster2_device_t>(dev)); + return engine_ptr_t(new (std::nothrow) TKeymasterPassthroughEngine<keymaster2_device_t>(dev)); } } // namespace keymaster diff --git a/legacy_support/rsa_keymaster1_key.cpp b/legacy_support/rsa_keymaster1_key.cpp index 5859bde..ff5576c 100644 --- a/legacy_support/rsa_keymaster1_key.cpp +++ b/legacy_support/rsa_keymaster1_key.cpp @@ -28,11 +28,12 @@ RsaKeymaster1KeyFactory::RsaKeymaster1KeyFactory(const SoftwareKeyBlobMaker& blo const KeymasterContext& context, const Keymaster1Engine* engine) : RsaKeyFactory(blob_maker, context), engine_(engine), - sign_factory_(new RsaKeymaster1OperationFactory(KM_PURPOSE_SIGN, engine)), - decrypt_factory_(new RsaKeymaster1OperationFactory(KM_PURPOSE_DECRYPT, engine)), + sign_factory_(new (std::nothrow) RsaKeymaster1OperationFactory(KM_PURPOSE_SIGN, engine)), + decrypt_factory_(new (std::nothrow) + RsaKeymaster1OperationFactory(KM_PURPOSE_DECRYPT, engine)), // For pubkey ops we can use the normal operation factories. - verify_factory_(new RsaVerificationOperationFactory), - encrypt_factory_(new RsaEncryptionOperationFactory) {} + verify_factory_(new (std::nothrow) RsaVerificationOperationFactory), + encrypt_factory_(new (std::nothrow) RsaEncryptionOperationFactory) {} static bool is_supported(uint32_t digest) { return digest == KM_DIGEST_NONE || digest == KM_DIGEST_SHA_2_256; diff --git a/legacy_support/rsa_keymaster1_operation.cpp b/legacy_support/rsa_keymaster1_operation.cpp index a32a8a6..7f4d59f 100644 --- a/legacy_support/rsa_keymaster1_operation.cpp +++ b/legacy_support/rsa_keymaster1_operation.cpp @@ -128,11 +128,11 @@ OperationPtr RsaKeymaster1OperationFactory::CreateOperation(Key&& key, switch (purpose_) { case KM_PURPOSE_SIGN: - return OperationPtr(new RsaKeymaster1Operation<RsaSignOperation>( + return OperationPtr(new (std::nothrow) RsaKeymaster1Operation<RsaSignOperation>( key.hw_enforced_move(), key.sw_enforced_move(), digest, padding, rsa.release(), engine_)); case KM_PURPOSE_DECRYPT: - return OperationPtr(new RsaKeymaster1Operation<RsaDecryptOperation>( + return OperationPtr(new (std::nothrow) RsaKeymaster1Operation<RsaDecryptOperation>( key.hw_enforced_move(), key.sw_enforced_move(), digest, padding, rsa.release(), engine_)); default: diff --git a/ng/AndroidKeyMintDevice.cpp b/ng/AndroidKeyMintDevice.cpp index 9d2cc69..25ad463 100644 --- a/ng/AndroidKeyMintDevice.cpp +++ b/ng/AndroidKeyMintDevice.cpp @@ -213,9 +213,9 @@ void addClientAndAppData(const std::vector<uint8_t>& appId, const std::vector<ui constexpr size_t kOperationTableSize = 16; AndroidKeyMintDevice::AndroidKeyMintDevice(SecurityLevel securityLevel) - : impl_(new ::keymaster::AndroidKeymaster( - [&]() -> auto { - auto context = new PureSoftKeymasterContext( + : impl_(new (std::nothrow)::keymaster::AndroidKeymaster( + [&]() -> auto{ + auto context = new (std::nothrow) PureSoftKeymasterContext( KmVersion::KEYMINT_2, static_cast<keymaster_security_level_t>(securityLevel)); context->SetSystemVersion(::keymaster::GetOsVersion(), ::keymaster::GetOsPatchlevel()); diff --git a/ng/AndroidKeymaster3Device.cpp b/ng/AndroidKeymaster3Device.cpp index 5ab1739..8c17f69 100644 --- a/ng/AndroidKeymaster3Device.cpp +++ b/ng/AndroidKeymaster3Device.cpp @@ -85,7 +85,7 @@ inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) { class KmParamSet : public keymaster_key_param_set_t { public: explicit KmParamSet(const hidl_vec<KeyParameter>& keyParams) { - params = new keymaster_key_param_t[keyParams.size()]; + params = new (std::nothrow) keymaster_key_param_t[keyParams.size()]; length = keyParams.size(); for (size_t i = 0; i < keyParams.size(); ++i) { auto tag = legacy_enum_conversion(keyParams[i].tag); @@ -220,9 +220,9 @@ void addClientAndAppData(const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8 } // anonymous namespace AndroidKeymaster3Device::AndroidKeymaster3Device() - : impl_(new ::keymaster::AndroidKeymaster( - []() -> auto { - auto context = new PureSoftKeymasterContext(KmVersion::KEYMASTER_3); + : impl_(new (std::nothrow)::keymaster::AndroidKeymaster( + []() -> auto{ + auto context = new (std::nothrow) PureSoftKeymasterContext(KmVersion::KEYMASTER_3); context->SetSystemVersion(GetOsVersion(), GetOsPatchlevel()); context->SetVendorPatchlevel(GetVendorPatchlevel()); // Software devices cannot be configured by the boot loader but they have @@ -237,7 +237,8 @@ AndroidKeymaster3Device::AndroidKeymaster3Device() AndroidKeymaster3Device::AndroidKeymaster3Device(KeymasterContext* context, KeymasterHardwareProfile profile) - : impl_(new ::keymaster::AndroidKeymaster(context, kOperationTableSize)), profile_(profile) {} + : impl_(new (std::nothrow)::keymaster::AndroidKeymaster(context, kOperationTableSize)), + profile_(profile) {} AndroidKeymaster3Device::~AndroidKeymaster3Device() {} @@ -504,20 +505,22 @@ Return<ErrorCode> AndroidKeymaster3Device::abort(uint64_t operationHandle) { } IKeymasterDevice* CreateKeymasterDevice() { - return new AndroidKeymaster3Device(); + return new (std::nothrow) AndroidKeymaster3Device(); } IKeymasterDevice* CreateKeymasterDevice(keymaster2_device_t* km2_device) { if (ConfigureDevice(km2_device) != KM_ERROR_OK) return nullptr; - auto context = new Keymaster2PassthroughContext(KmVersion::KEYMASTER_3, km2_device); + auto context = + new (std::nothrow) Keymaster2PassthroughContext(KmVersion::KEYMASTER_3, km2_device); context->SetSystemVersion(GetOsVersion(), GetOsPatchlevel()); - return new AndroidKeymaster3Device(context, KeymasterHardwareProfile::KM2); + return new (std::nothrow) AndroidKeymaster3Device(context, KeymasterHardwareProfile::KM2); } IKeymasterDevice* CreateKeymasterDevice(keymaster1_device_t* km1_device) { - auto context = new Keymaster1PassthroughContext(KmVersion::KEYMASTER_3, km1_device); + auto context = + new (std::nothrow) Keymaster1PassthroughContext(KmVersion::KEYMASTER_3, km1_device); context->SetSystemVersion(GetOsVersion(), GetOsPatchlevel()); - return new AndroidKeymaster3Device(context, KeymasterHardwareProfile::KM1); + return new (std::nothrow) AndroidKeymaster3Device(context, KeymasterHardwareProfile::KM1); } } // namespace ng diff --git a/ng/AndroidKeymaster41Device.cpp b/ng/AndroidKeymaster41Device.cpp index c360ff2..e9abb9e 100644 --- a/ng/AndroidKeymaster41Device.cpp +++ b/ng/AndroidKeymaster41Device.cpp @@ -35,7 +35,7 @@ inline V41ErrorCode legacy_enum_conversion(const keymaster_error_t value) { } // namespace IKeymasterDevice* CreateKeymasterDevice(SecurityLevel securityLevel) { - return new AndroidKeymaster41Device(securityLevel); + return new (std::nothrow) AndroidKeymaster41Device(securityLevel); } Return<V41ErrorCode> diff --git a/ng/AndroidKeymaster4Device.cpp b/ng/AndroidKeymaster4Device.cpp index 33b329f..1072418 100644 --- a/ng/AndroidKeymaster4Device.cpp +++ b/ng/AndroidKeymaster4Device.cpp @@ -175,7 +175,7 @@ void addClientAndAppData(const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8 keymaster_key_param_set_t hidlKeyParams2Km(const hidl_vec<KeyParameter>& keyParams) { keymaster_key_param_set_t set; - set.params = new keymaster_key_param_t[keyParams.size()]; + set.params = new (std::nothrow) keymaster_key_param_t[keyParams.size()]; set.length = keyParams.size(); for (size_t i = 0; i < keyParams.size(); ++i) { @@ -219,9 +219,9 @@ keymaster_key_param_set_t hidlKeyParams2Km(const hidl_vec<KeyParameter>& keyPara } AndroidKeymaster4Device::AndroidKeymaster4Device(KmVersion version, SecurityLevel securityLevel) - : impl_(new ::keymaster::AndroidKeymaster( - [&]() -> auto { - auto context = new PureSoftKeymasterContext( + : impl_(new (std::nothrow)::keymaster::AndroidKeymaster( + [&]() -> auto{ + auto context = new (std::nothrow) PureSoftKeymasterContext( version, static_cast<keymaster_security_level_t>(securityLevel)); context->SetSystemVersion(GetOsVersion(), GetOsPatchlevel()); context->SetVendorPatchlevel(GetVendorPatchlevel()); @@ -259,7 +259,8 @@ Return<void> AndroidKeymaster4Device::computeSharedHmac( const hidl_vec<::android::hardware::keymaster::V4_0::HmacSharingParameters>& params, computeSharedHmac_cb _hidl_cb) { ComputeSharedHmacRequest request(impl_->message_version()); - request.params_array.params_array = new keymaster::HmacSharingParameters[params.size()]; + request.params_array.params_array = + new (std::nothrow) keymaster::HmacSharingParameters[params.size()]; request.params_array.num_params = params.size(); for (size_t i = 0; i < params.size(); ++i) { request.params_array.params_array[i].seed = {params[i].seed.data(), params[i].seed.size()}; @@ -586,7 +587,7 @@ Return<ErrorCode> AndroidKeymaster4Device::abort(uint64_t operationHandle) { } IKeymasterDevice* CreateKeymasterDevice(SecurityLevel securityLevel) { - return new AndroidKeymaster4Device(securityLevel); + return new (std::nothrow) AndroidKeymaster4Device(securityLevel); } } // namespace ng diff --git a/ng/AndroidRemotelyProvisionedComponentDevice.cpp b/ng/AndroidRemotelyProvisionedComponentDevice.cpp index e6bd40f..54ea70c 100644 --- a/ng/AndroidRemotelyProvisionedComponentDevice.cpp +++ b/ng/AndroidRemotelyProvisionedComponentDevice.cpp @@ -112,7 +112,10 @@ ScopedAStatus AndroidRemotelyProvisionedComponentDevice::generateCertificateRequ GenerateCsrRequest request(impl_->message_version()); request.test_mode = testMode; request.num_keys = keysToSign.size(); - request.keys_to_sign_array = new KeymasterBlob[keysToSign.size()]; + request.keys_to_sign_array = new (std::nothrow) KeymasterBlob[keysToSign.size()]; + if (request.keys_to_sign_array == nullptr) { + return km_utils::kmError2ScopedAStatus(KM_ERROR_MEMORY_ALLOCATION_FAILED); + } for (size_t i = 0; i < keysToSign.size(); i++) { request.SetKeyToSign(i, keysToSign[i].macedKey.data(), keysToSign[i].macedKey.size()); } diff --git a/ng/AndroidSharedSecret.cpp b/ng/AndroidSharedSecret.cpp index 0ae3d2d..c800666 100644 --- a/ng/AndroidSharedSecret.cpp +++ b/ng/AndroidSharedSecret.cpp @@ -44,7 +44,11 @@ ScopedAStatus AndroidSharedSecret::getSharedSecretParameters(SharedSecretParamet ScopedAStatus AndroidSharedSecret::computeSharedSecret(const vector<SharedSecretParameters>& params, vector<uint8_t>* sharingCheck) { ComputeSharedHmacRequest request(impl_->message_version()); - request.params_array.params_array = new keymaster::HmacSharingParameters[params.size()]; + request.params_array.params_array = + new (std::nothrow) keymaster::HmacSharingParameters[params.size()]; + if (request.params_array.params_array == nullptr) { + return kmError2ScopedAStatus(KM_ERROR_MEMORY_ALLOCATION_FAILED); + } request.params_array.num_params = params.size(); for (size_t i = 0; i < params.size(); ++i) { request.params_array.params_array[i].seed = {params[i].seed.data(), params[i].seed.size()}; diff --git a/ng/KeyMintAidlUtils.cpp b/ng/KeyMintAidlUtils.cpp index 17a53a5..28b5744 100644 --- a/ng/KeyMintAidlUtils.cpp +++ b/ng/KeyMintAidlUtils.cpp @@ -98,7 +98,7 @@ vector<KeyParameter> kmParamSet2Aidl(const keymaster_key_param_set_t& set) { keymaster_key_param_set_t aidlKeyParams2Km(const vector<KeyParameter>& keyParams) { keymaster_key_param_set_t set; - set.params = new keymaster_key_param_t[keyParams.size()]; + set.params = new (std::nothrow) keymaster_key_param_t[keyParams.size()]; set.length = keyParams.size(); for (size_t i = 0; i < keyParams.size(); ++i) { diff --git a/tests/android_keymaster_messages_test.cpp b/tests/android_keymaster_messages_test.cpp index db4c7b0..6b873b4 100644 --- a/tests/android_keymaster_messages_test.cpp +++ b/tests/android_keymaster_messages_test.cpp @@ -846,6 +846,27 @@ TEST(RoundTrip, GenerateTimestampTokenResponse) { } } +TEST(RoundTrip, GetRootOfTrustRequest) { + for (int ver = 0; ver <= kMaxMessageVersion; ++ver) { + std::vector<uint8_t> challenge{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + GetRootOfTrustRequest msg(ver, challenge); + + UniquePtr<GetRootOfTrustRequest> deserialized(round_trip(ver, msg, 20)); + EXPECT_EQ(deserialized->challenge, challenge); + } +} + +TEST(RoundTrip, GetRootOfTrustResponse) { + for (int ver = 0; ver <= kMaxMessageVersion; ++ver) { + std::vector<uint8_t> rootOfTrust{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + GetRootOfTrustResponse msg(ver, rootOfTrust); + msg.error = KM_ERROR_OK; + + UniquePtr<GetRootOfTrustResponse> deserialized(round_trip(ver, msg, 24)); + EXPECT_EQ(deserialized->rootOfTrust, rootOfTrust); + } +} + #define SET_ATTESTATION_ID(x) msg.x.Reinitialize(#x, strlen(#x)) void check_id(const Buffer& id, const char* value) { @@ -974,6 +995,8 @@ GARBAGE_TEST(GenerateTimestampTokenRequest); GARBAGE_TEST(GenerateTimestampTokenResponse); GARBAGE_TEST(SetAttestationIdsRequest); GARBAGE_TEST(ConfigureVerifiedBootInfoRequest); +GARBAGE_TEST(GetRootOfTrustRequest); +GARBAGE_TEST(GetRootOfTrustResponse); } // namespace test diff --git a/tests/key_blob_test.cpp b/tests/key_blob_test.cpp index f50d4fe..f69551b 100644 --- a/tests/key_blob_test.cpp +++ b/tests/key_blob_test.cpp @@ -228,7 +228,7 @@ TEST_P(KeyBlobTest, WrongHwEnforced) { // Find enforced serialization data and modify it. size_t hw_enforced_size = hw_enforced_.SerializedSize(); - UniquePtr<uint8_t[]> hw_enforced_data(new uint8_t[hw_enforced_size]); + UniquePtr<uint8_t[]> hw_enforced_data(new (std::nothrow) uint8_t[hw_enforced_size]); hw_enforced_.Serialize(hw_enforced_data.get(), hw_enforced_data.get() + hw_enforced_size); auto hw_enforced_ptr = |