/* * Copyright 2018 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 "remote_keymaster.h" #include #include #include #include #include namespace keymaster { RemoteKeymaster::RemoteKeymaster(cuttlefish::SharedFdKeymasterChannel* channel, int32_t message_version) : channel_(channel), message_version_(message_version) {} RemoteKeymaster::~RemoteKeymaster() {} void RemoteKeymaster::ForwardCommand(AndroidKeymasterCommand command, const Serializable& req, KeymasterResponse* rsp) { if (!channel_->SendRequest(command, req)) { LOG(ERROR) << "Failed to send keymaster message: " << command; rsp->error = KM_ERROR_UNKNOWN_ERROR; return; } auto response = channel_->ReceiveMessage(); if (!response) { LOG(ERROR) << "Failed to receive keymaster response: " << command; rsp->error = KM_ERROR_UNKNOWN_ERROR; return; } const uint8_t* buffer = response->payload; const uint8_t* buffer_end = response->payload + response->payload_size; if (!rsp->Deserialize(&buffer, buffer_end)) { LOG(ERROR) << "Failed to deserialize keymaster response: " << command; rsp->error = KM_ERROR_UNKNOWN_ERROR; return; } } bool RemoteKeymaster::Initialize() { // We don't need to bother with GetVersion, because CF HAL and remote sides // are always compiled together, so will never disagree about message // versions. ConfigureRequest req(message_version()); req.os_version = GetOsVersion(); req.os_patchlevel = GetOsPatchlevel(); ConfigureResponse rsp(message_version()); Configure(req, &rsp); if (rsp.error != KM_ERROR_OK) { LOG(ERROR) << "Failed to configure keymaster: " << rsp.error; return false; } // Set the vendor patchlevel to value retrieved from system property (which // requires SELinux permission). ConfigureVendorPatchlevelRequest vendor_req(message_version()); vendor_req.vendor_patchlevel = GetVendorPatchlevel(); ConfigureVendorPatchlevelResponse vendor_rsp = ConfigureVendorPatchlevel(vendor_req); if (vendor_rsp.error != KM_ERROR_OK) { LOG(ERROR) << "Failed to configure keymaster vendor patchlevel: " << vendor_rsp.error; return false; } // Set the boot patchlevel to value retrieved from system property (which // requires SELinux permission). ConfigureBootPatchlevelRequest boot_req(message_version()); static constexpr char boot_prop_name[] = "ro.vendor.boot_security_patch"; auto boot_prop_value = android::base::GetProperty(boot_prop_name, ""); boot_prop_value = android::base::StringReplace(boot_prop_value.data(), "-", "", /* all */ true); boot_req.boot_patchlevel = std::stoi(boot_prop_value); ConfigureBootPatchlevelResponse boot_rsp = ConfigureBootPatchlevel(boot_req); if (boot_rsp.error != KM_ERROR_OK) { LOG(ERROR) << "Failed to configure keymaster boot patchlevel: " << boot_rsp.error; return false; } // Pass verified boot information to the remote KM implementation auto vbmeta_digest = GetVbmetaDigest(); if (vbmeta_digest) { ConfigureVerifiedBootInfoRequest request( message_version(), GetVerifiedBootState(), GetBootloaderState(), *vbmeta_digest); ConfigureVerifiedBootInfoResponse response = ConfigureVerifiedBootInfo(request); if (response.error != KM_ERROR_OK) { LOG(ERROR) << "Failed to configure keymaster verified boot info: " << response.error; return false; } } // Pass attestation IDs to the remote KM implementation. // Skip MEID as it is not present on emulators. SetAttestationIdsKM3Request requestKM3(message_version()); static constexpr char brand_prop_name[] = "ro.product.brand"; static constexpr char device_prop_name[] = "ro.product.device"; static constexpr char product_prop_name[] = "ro.product.name"; static constexpr char serial_prop_name[] = "ro.serialno"; static constexpr char manufacturer_prop_name[] = "ro.product.manufacturer"; static constexpr char model_prop_name[] = "ro.product.model"; std::string brand_prop_value = android::base::GetProperty(brand_prop_name, ""); std::string device_prop_value = android::base::GetProperty(device_prop_name, ""); std::string product_prop_value = android::base::GetProperty(product_prop_name, ""); std::string serial_prop_value = android::base::GetProperty(serial_prop_name, ""); std::string manufacturer_prop_value = android::base::GetProperty(manufacturer_prop_name, ""); std::string model_prop_value = android::base::GetProperty(model_prop_name, ""); // Currently modem_simulator always returns one fixed value. See // `handleGetIMEI` in // device/google/cuttlefish/host/commands/modem_simulator/misc_service.cpp for // more details. // This should be updated once the below bug is fixed - // b/263188546 - Use device-specific IMEI values rather than one hardcoded // value. std::string imei_value = "867400022047199"; requestKM3.base.imei.Reinitialize(imei_value.data(), imei_value.size()); requestKM3.base.brand.Reinitialize(brand_prop_value.data(), brand_prop_value.size()); requestKM3.base.device.Reinitialize(device_prop_value.data(), device_prop_value.size()); requestKM3.base.product.Reinitialize(product_prop_value.data(), product_prop_value.size()); requestKM3.base.serial.Reinitialize(serial_prop_value.data(), serial_prop_value.size()); requestKM3.base.manufacturer.Reinitialize(manufacturer_prop_value.data(), manufacturer_prop_value.size()); requestKM3.base.model.Reinitialize(model_prop_value.data(), model_prop_value.size()); std::string second_imei_value = "867400022047199"; requestKM3.second_imei.Reinitialize(second_imei_value.data(), second_imei_value.size()); SetAttestationIdsKM3Response responseKM3 = SetAttestationIdsKM3(requestKM3); if (responseKM3.error != KM_ERROR_OK) { LOG(ERROR) << "Failed to configure keymaster attestation IDs: " << responseKM3.error; return false; } return true; } void RemoteKeymaster::GetVersion(const GetVersionRequest& request, GetVersionResponse* response) { ForwardCommand(GET_VERSION, request, response); } void RemoteKeymaster::SupportedAlgorithms( const SupportedAlgorithmsRequest& request, SupportedAlgorithmsResponse* response) { ForwardCommand(GET_SUPPORTED_ALGORITHMS, request, response); } void RemoteKeymaster::SupportedBlockModes( const SupportedBlockModesRequest& request, SupportedBlockModesResponse* response) { ForwardCommand(GET_SUPPORTED_BLOCK_MODES, request, response); } void RemoteKeymaster::SupportedPaddingModes( const SupportedPaddingModesRequest& request, SupportedPaddingModesResponse* response) { ForwardCommand(GET_SUPPORTED_PADDING_MODES, request, response); } void RemoteKeymaster::SupportedDigests(const SupportedDigestsRequest& request, SupportedDigestsResponse* response) { ForwardCommand(GET_SUPPORTED_DIGESTS, request, response); } void RemoteKeymaster::SupportedImportFormats( const SupportedImportFormatsRequest& request, SupportedImportFormatsResponse* response) { ForwardCommand(GET_SUPPORTED_IMPORT_FORMATS, request, response); } void RemoteKeymaster::SupportedExportFormats( const SupportedExportFormatsRequest& request, SupportedExportFormatsResponse* response) { ForwardCommand(GET_SUPPORTED_EXPORT_FORMATS, request, response); } void RemoteKeymaster::AddRngEntropy(const AddEntropyRequest& request, AddEntropyResponse* response) { ForwardCommand(ADD_RNG_ENTROPY, request, response); } void RemoteKeymaster::Configure(const ConfigureRequest& request, ConfigureResponse* response) { ForwardCommand(CONFIGURE, request, response); } void RemoteKeymaster::GenerateKey(const GenerateKeyRequest& request, GenerateKeyResponse* response) { if (message_version_ < MessageVersion(KmVersion::KEYMINT_1) && !request.key_description.Contains(TAG_CREATION_DATETIME)) { GenerateKeyRequest datedRequest(request.message_version); datedRequest.key_description.push_back(TAG_CREATION_DATETIME, java_time(time(NULL))); ForwardCommand(GENERATE_KEY, datedRequest, response); } else { ForwardCommand(GENERATE_KEY, request, response); } } void RemoteKeymaster::GenerateRkpKey(const GenerateRkpKeyRequest& request, GenerateRkpKeyResponse* response) { ForwardCommand(GENERATE_RKP_KEY, request, response); } void RemoteKeymaster::GenerateCsr(const GenerateCsrRequest& request, GenerateCsrResponse* response) { ForwardCommand(GENERATE_CSR, request, response); } void RemoteKeymaster::GenerateCsrV2(const GenerateCsrV2Request& request, GenerateCsrV2Response* response) { ForwardCommand(GENERATE_CSR_V2, request, response); } void RemoteKeymaster::GetKeyCharacteristics( const GetKeyCharacteristicsRequest& request, GetKeyCharacteristicsResponse* response) { ForwardCommand(GET_KEY_CHARACTERISTICS, request, response); } void RemoteKeymaster::ImportKey(const ImportKeyRequest& request, ImportKeyResponse* response) { ForwardCommand(IMPORT_KEY, request, response); } void RemoteKeymaster::ImportWrappedKey(const ImportWrappedKeyRequest& request, ImportWrappedKeyResponse* response) { ForwardCommand(IMPORT_WRAPPED_KEY, request, response); } void RemoteKeymaster::ExportKey(const ExportKeyRequest& request, ExportKeyResponse* response) { ForwardCommand(EXPORT_KEY, request, response); } void RemoteKeymaster::AttestKey(const AttestKeyRequest& request, AttestKeyResponse* response) { ForwardCommand(ATTEST_KEY, request, response); } void RemoteKeymaster::UpgradeKey(const UpgradeKeyRequest& request, UpgradeKeyResponse* response) { ForwardCommand(UPGRADE_KEY, request, response); } void RemoteKeymaster::DeleteKey(const DeleteKeyRequest& request, DeleteKeyResponse* response) { ForwardCommand(DELETE_KEY, request, response); } void RemoteKeymaster::DeleteAllKeys(const DeleteAllKeysRequest& request, DeleteAllKeysResponse* response) { ForwardCommand(DELETE_ALL_KEYS, request, response); } void RemoteKeymaster::BeginOperation(const BeginOperationRequest& request, BeginOperationResponse* response) { ForwardCommand(BEGIN_OPERATION, request, response); } void RemoteKeymaster::UpdateOperation(const UpdateOperationRequest& request, UpdateOperationResponse* response) { ForwardCommand(UPDATE_OPERATION, request, response); } void RemoteKeymaster::FinishOperation(const FinishOperationRequest& request, FinishOperationResponse* response) { ForwardCommand(FINISH_OPERATION, request, response); } void RemoteKeymaster::AbortOperation(const AbortOperationRequest& request, AbortOperationResponse* response) { ForwardCommand(ABORT_OPERATION, request, response); } GetHmacSharingParametersResponse RemoteKeymaster::GetHmacSharingParameters() { // Unused empty buffer to allow ForwardCommand to have something to serialize Buffer request; GetHmacSharingParametersResponse response(message_version()); ForwardCommand(GET_HMAC_SHARING_PARAMETERS, request, &response); return response; } ComputeSharedHmacResponse RemoteKeymaster::ComputeSharedHmac( const ComputeSharedHmacRequest& request) { ComputeSharedHmacResponse response(message_version()); ForwardCommand(COMPUTE_SHARED_HMAC, request, &response); return response; } VerifyAuthorizationResponse RemoteKeymaster::VerifyAuthorization( const VerifyAuthorizationRequest& request) { VerifyAuthorizationResponse response(message_version()); ForwardCommand(VERIFY_AUTHORIZATION, request, &response); return response; } DeviceLockedResponse RemoteKeymaster::DeviceLocked( const DeviceLockedRequest& request) { DeviceLockedResponse response(message_version()); ForwardCommand(DEVICE_LOCKED, request, &response); return response; } EarlyBootEndedResponse RemoteKeymaster::EarlyBootEnded() { // Unused empty buffer to allow ForwardCommand to have something to serialize Buffer request; EarlyBootEndedResponse response(message_version()); ForwardCommand(EARLY_BOOT_ENDED, request, &response); return response; } void RemoteKeymaster::GenerateTimestampToken( GenerateTimestampTokenRequest& request, GenerateTimestampTokenResponse* response) { ForwardCommand(GENERATE_TIMESTAMP_TOKEN, request, response); } ConfigureVendorPatchlevelResponse RemoteKeymaster::ConfigureVendorPatchlevel( const ConfigureVendorPatchlevelRequest& request) { ConfigureVendorPatchlevelResponse response(message_version()); ForwardCommand(CONFIGURE_VENDOR_PATCHLEVEL, request, &response); return response; } ConfigureBootPatchlevelResponse RemoteKeymaster::ConfigureBootPatchlevel( const ConfigureBootPatchlevelRequest& request) { ConfigureBootPatchlevelResponse response(message_version()); ForwardCommand(CONFIGURE_BOOT_PATCHLEVEL, request, &response); return response; } ConfigureVerifiedBootInfoResponse RemoteKeymaster::ConfigureVerifiedBootInfo( const ConfigureVerifiedBootInfoRequest& request) { ConfigureVerifiedBootInfoResponse response(message_version()); ForwardCommand(CONFIGURE_VERIFIED_BOOT_INFO, request, &response); return response; } GetRootOfTrustResponse RemoteKeymaster::GetRootOfTrust( const GetRootOfTrustRequest& request) { GetRootOfTrustResponse response(message_version()); ForwardCommand(GET_ROOT_OF_TRUST, request, &response); return response; } GetHwInfoResponse RemoteKeymaster::GetHwInfo() { // Unused empty buffer to allow ForwardCommand to have something to serialize Buffer request; GetHwInfoResponse response(message_version()); ForwardCommand(GET_HW_INFO, request, &response); return response; } SetAttestationIdsResponse RemoteKeymaster::SetAttestationIds( const SetAttestationIdsRequest& request) { SetAttestationIdsResponse response(message_version()); ForwardCommand(SET_ATTESTATION_IDS, request, &response); return response; } SetAttestationIdsKM3Response RemoteKeymaster::SetAttestationIdsKM3( const SetAttestationIdsKM3Request& request) { SetAttestationIdsKM3Response response(message_version()); ForwardCommand(SET_ATTESTATION_IDS_KM3, request, &response); return response; } } // namespace keymaster