blob: a5cff3e41d8cde495f382fc7e5cbe79cdb234931 [file] [log] [blame] [edit]
// Copyright 2023 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "arc/keymint/keymint_server.h"
#include <utility>
#include <base/check.h>
#include <base/functional/bind.h>
#include <base/logging.h>
#include <base/task/single_thread_task_runner.h>
#include <base/threading/platform_thread.h>
#include <keymaster/android_keymaster_messages.h>
#include <libarc-attestation/lib/interface.h>
#include <mojo/keymint.mojom.h>
#include "arc/keymint/conversion.h"
// The implementations of |arc::mojom::KeyMintServer| methods below have the
// following overall pattern:
//
// * Generate an std::unique_ptr to a KeyMint request data structure from the
// arguments received from Mojo, usually through the helpers in conversion.h.
//
// * Execute the operation in |backend->keymint()|, posting this task to a
// background thread. This produces a KeyMint response data structure.
//
// * Post the response to a callback that runs on the original thread (in this
// case, the Mojo thread where the request started).
//
// * Convert the KeyMint response to the Mojo return values, and run the
// result callback.
//
namespace arc::keymint {
namespace {
constexpr size_t kOperationTableSize = 16;
// TODO(b/278968783): Add version negotiation for KeyMint.
// KeyMint Message versions are drawn from Android
// Keymaster Messages.
constexpr int32_t kKeyMintMessageVersion = 4;
constexpr ::keymaster::KmVersion kKeyMintVersion =
::keymaster::KmVersion::KEYMINT_2;
} // namespace
KeyMintServer::Backend::Backend()
: context_(new context::ArcKeyMintContext(kKeyMintVersion)),
keymint_(context_, kOperationTableSize, kKeyMintMessageVersion) {}
KeyMintServer::Backend::~Backend() = default;
KeyMintServer::KeyMintServer()
: backend_thread_("BackendKeyMintThread"), weak_ptr_factory_(this) {
CHECK(backend_thread_.Start()) << "Failed to start keymint thread";
}
KeyMintServer::~KeyMintServer() = default;
void KeyMintServer::UpdateContextPlaceholderKeys(
std::vector<mojom::ChromeOsKeyPtr> keys,
base::OnceCallback<void(bool)> callback) {
base::OnceCallback<void(bool)> callback_in_original_runner = base::BindOnce(
[](scoped_refptr<base::TaskRunner> original_task_runner,
base::OnceCallback<void(bool)> callback, bool success) {
original_task_runner->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), success));
},
base::SingleThreadTaskRunner::GetCurrentDefault(), std::move(callback));
backend_thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(
[](context::ArcKeyMintContext* context,
std::vector<mojom::ChromeOsKeyPtr> keys,
base::OnceCallback<void(bool)> callback) {
// |context| is guaranteed valid here because it's owned
// by |backend_|, which outlives the |backend_thread_|
// this runs on.
context->set_placeholder_keys(std::move(keys));
std::move(callback).Run(/*success=*/true);
},
backend_.context(), std::move(keys),
std::move(callback_in_original_runner)));
}
void KeyMintServer::SetSystemVersion(uint32_t android_version,
uint32_t android_patchlevel) {
auto task_lambda = [](context::ArcKeyMintContext* context,
uint32_t android_version, uint32_t android_patchlevel) {
// |context| is guaranteed valid here because it's owned
// by |backend_|, which outlives the |backend_thread_|
// this runs on.
context->SetSystemVersion(android_version, android_patchlevel);
};
backend_thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(task_lambda, backend_.context(),
android_version, android_patchlevel));
}
template <typename KmMember, typename KmRequest, typename KmResponse>
void KeyMintServer::RunKeyMintRequest(
const base::Location& location,
KmMember member,
std::unique_ptr<KmRequest> request,
base::OnceCallback<void(std::unique_ptr<KmResponse>)> callback) {
auto task_lambda =
[](const base::Location& location,
scoped_refptr<base::TaskRunner> original_task_runner,
::keymaster::AndroidKeymaster* keymaster, KmMember member,
std::unique_ptr<KmRequest> request,
base::OnceCallback<void(std::unique_ptr<KmResponse>)> callback) {
// Prepare a KeyMint response data structure.
auto response =
std::make_unique<KmResponse>(keymaster->message_version());
// Execute the operation.
(*keymaster.*member)(*request, response.get());
// Post |callback| to the |original_task_runner| given |response|.
original_task_runner->PostTask(
location, base::BindOnce(std::move(callback), std::move(response)));
};
// Post the KeyMint operation to a background thread while capturing the
// current task runner.
backend_thread_.task_runner()->PostTask(
location,
base::BindOnce(task_lambda, location,
base::SingleThreadTaskRunner::GetCurrentDefault(),
backend_.keymint(), member, std::move(request),
std::move(callback)));
}
template <typename KmMember, typename KmResponse>
void KeyMintServer::RunKeyMintRequest_EmptyInput(
const base::Location& location,
KmMember member,
base::OnceCallback<void(std::unique_ptr<KmResponse>)> callback) {
auto task_lambda =
[](const base::Location& location,
scoped_refptr<base::TaskRunner> original_task_runner,
::keymaster::AndroidKeymaster* keymaster, KmMember member,
base::OnceCallback<void(std::unique_ptr<KmResponse>)> callback) {
// Prepare a KeyMint response data structure.
auto response =
std::make_unique<KmResponse>(keymaster->message_version());
// Execute the operation.
auto result = (*keymaster.*member)();
response->error = result.error;
// Post |callback| to the |original_task_runner| given |response|.
original_task_runner->PostTask(
location, base::BindOnce(std::move(callback), std::move(response)));
};
// Post the KeyMint operation to a background thread while capturing the
// current task runner.
backend_thread_.task_runner()->PostTask(
location,
base::BindOnce(task_lambda, location,
base::SingleThreadTaskRunner::GetCurrentDefault(),
backend_.keymint(), member, std::move(callback)));
}
template <typename KmMember, typename KmRequest, typename KmResponse>
void KeyMintServer::RunKeyMintRequest_SingleInput(
const base::Location& location,
KmMember member,
std::unique_ptr<KmRequest> request,
base::OnceCallback<void(std::unique_ptr<KmResponse>)> callback) {
auto task_lambda =
[](const base::Location& location,
scoped_refptr<base::TaskRunner> original_task_runner,
::keymaster::AndroidKeymaster* keymaster, KmMember member,
std::unique_ptr<KmRequest> request,
base::OnceCallback<void(std::unique_ptr<KmResponse>)> callback) {
// Prepare a KeyMint response data structure.
auto response =
std::make_unique<KmResponse>(keymaster->message_version());
// Execute the operation.
auto result = (*keymaster.*member)(*request);
// Post |callback| to the |original_task_runner| given |response|.
response->error = result.error;
original_task_runner->PostTask(
location, base::BindOnce(std::move(callback), std::move(response)));
};
// Post the KeyMint operation to a background thread while capturing the
// current task runner.
backend_thread_.task_runner()->PostTask(
location,
base::BindOnce(task_lambda, location,
base::SingleThreadTaskRunner::GetCurrentDefault(),
backend_.keymint(), member, std::move(request),
std::move(callback)));
}
void KeyMintServer::AddRngEntropy(const std::vector<uint8_t>& data,
AddRngEntropyCallback callback) {
// Convert input |data| into |km_request|. All data is deep copied to avoid
// use-after-free.
auto km_request =
std::make_unique<::keymaster::AddEntropyRequest>(kKeyMintMessageVersion);
ConvertToKeymasterMessage(data, &km_request->random_data);
auto task_lambda = base::BindOnce(
[](AddRngEntropyCallback callback,
std::unique_ptr<::keymaster::AddEntropyResponse> km_response) {
// Run callback.
std::move(callback).Run(km_response->error);
},
std::move(callback));
// Call keymint.
RunKeyMintRequest(FROM_HERE, &::keymaster::AndroidKeymaster::AddRngEntropy,
std::move(km_request), std::move(task_lambda));
}
void KeyMintServer::GetKeyCharacteristics(
arc::mojom::keymint::GetKeyCharacteristicsRequestPtr request,
GetKeyCharacteristicsCallback callback) {
// Convert input |request| into |km_request|. All data is deep copied to avoid
// use-after-free.
auto km_request = MakeGetKeyCharacteristicsRequest(
request, backend_.keymint()->message_version());
auto task_lambda = base::BindOnce(
[](GetKeyCharacteristicsCallback callback,
std::unique_ptr<::keymaster::GetKeyCharacteristicsResponse>
km_response) {
// Prepare mojo response.
CHECK(km_response);
auto response = MakeGetKeyCharacteristicsResult(*km_response);
// Run callback.
std::move(callback).Run(std::move(response));
},
std::move(callback));
// Call keymint.
RunKeyMintRequest(FROM_HERE,
&::keymaster::AndroidKeymaster::GetKeyCharacteristics,
std::move(km_request), std::move(task_lambda));
}
void KeyMintServer::GenerateKey(
arc::mojom::keymint::GenerateKeyRequestPtr request,
GenerateKeyCallback callback) {
auto km_request =
MakeGenerateKeyRequest(request, backend_.keymint()->message_version());
auto task_lambda = base::BindOnce(
[](GenerateKeyCallback callback,
std::unique_ptr<::keymaster::GenerateKeyResponse> km_response) {
// Prepare mojo response.
CHECK(km_response);
auto response = MakeGenerateKeyResult(*km_response);
// Run callback.
std::move(callback).Run(std::move(response));
},
std::move(callback));
// Call keymint.
RunKeyMintRequest(FROM_HERE, &::keymaster::AndroidKeymaster::GenerateKey,
std::move(km_request), std::move(task_lambda));
}
void KeyMintServer::ImportKey(arc::mojom::keymint::ImportKeyRequestPtr request,
ImportKeyCallback callback) {
auto km_request =
MakeImportKeyRequest(request, backend_.keymint()->message_version());
auto task_lambda = base::BindOnce(
[](ImportKeyCallback callback,
std::unique_ptr<::keymaster::ImportKeyResponse> km_response) {
// Prepare mojo response.
CHECK(km_response);
auto response = MakeImportKeyResult(*km_response);
// Run callback.
std::move(callback).Run(std::move(response));
},
std::move(callback));
// Call keymint.
RunKeyMintRequest(FROM_HERE, &::keymaster::AndroidKeymaster::ImportKey,
std::move(km_request), std::move(task_lambda));
}
void KeyMintServer::ImportWrappedKey(
arc::mojom::keymint::ImportWrappedKeyRequestPtr request,
ImportWrappedKeyCallback callback) {
auto km_request = MakeImportWrappedKeyRequest(
request, backend_.keymint()->message_version());
auto task_lambda = base::BindOnce(
[](ImportKeyCallback callback,
std::unique_ptr<::keymaster::ImportWrappedKeyResponse> km_response) {
// Prepare mojo response.
CHECK(km_response);
auto response = MakeImportWrappedKeyResult(*km_response);
std::move(callback).Run(std::move(response));
},
std::move(callback));
// Call keymint.
RunKeyMintRequest(FROM_HERE, &::keymaster::AndroidKeymaster::ImportWrappedKey,
std::move(km_request), std::move(task_lambda));
}
void KeyMintServer::UpgradeKey(
arc::mojom::keymint::UpgradeKeyRequestPtr request,
UpgradeKeyCallback callback) {
auto km_request =
MakeUpgradeKeyRequest(request, backend_.keymint()->message_version());
auto task_lambda = base::BindOnce(
[](UpgradeKeyCallback callback,
std::unique_ptr<::keymaster::UpgradeKeyResponse> km_response) {
// Prepare mojo response.
CHECK(km_response);
auto response = MakeUpgradeKeyResult(*km_response);
// Run callback.
std::move(callback).Run(std::move(response));
},
std::move(callback));
// Call keymint.
RunKeyMintRequest(FROM_HERE, &::keymaster::AndroidKeymaster::UpgradeKey,
std::move(km_request), std::move(task_lambda));
}
void KeyMintServer::DeleteKey(const std::vector<uint8_t>& key_blob,
DeleteKeyCallback callback) {
// Convert input |key_blob| into |km_request|. All data is deep copied to
// avoid use-after-free.
auto km_request = std::make_unique<::keymaster::DeleteKeyRequest>(
backend_.keymint()->message_version());
km_request->SetKeyMaterial(key_blob.data(), key_blob.size());
auto task_lambda = base::BindOnce(
[](DeleteKeyCallback callback,
std::unique_ptr<::keymaster::DeleteKeyResponse> km_response) {
// Run callback.
CHECK(km_response);
std::move(callback).Run(km_response->error);
},
std::move(callback));
// Call keymint.
RunKeyMintRequest(FROM_HERE, &::keymaster::AndroidKeymaster::DeleteKey,
std::move(km_request), std::move(task_lambda));
}
void KeyMintServer::DeleteAllKeys(DeleteAllKeysCallback callback) {
// Prepare keymint request.
auto km_request = std::make_unique<::keymaster::DeleteAllKeysRequest>(
backend_.keymint()->message_version());
auto task_lambda = base::BindOnce(
[](DeleteAllKeysCallback callback,
std::unique_ptr<::keymaster::DeleteAllKeysResponse> km_response) {
// Run callback.
CHECK(km_response);
std::move(callback).Run(km_response->error);
},
std::move(callback));
// Call keymint.
RunKeyMintRequest(FROM_HERE, &::keymaster::AndroidKeymaster::DeleteAllKeys,
std::move(km_request), std::move(task_lambda));
}
void KeyMintServer::DestroyAttestationIds(
DestroyAttestationIdsCallback callback) {
// Implement this when needed.
std::move(callback).Run(KM_ERROR_UNIMPLEMENTED);
}
void KeyMintServer::Begin(arc::mojom::keymint::BeginRequestPtr request,
BeginCallback callback) {
// Convert input |request| into |km_request|. All data is deep copied to avoid
// use-after-free.
auto km_request =
MakeBeginOperationRequest(request, backend_.keymint()->message_version());
auto task_lambda = base::BindOnce(
[](BeginCallback callback,
std::unique_ptr<::keymaster::BeginOperationResponse> km_response) {
// Prepare mojo response.
CHECK(km_response);
auto response = MakeBeginResult(*km_response);
// Run callback.
std::move(callback).Run(std::move(response));
},
std::move(callback));
// Call KeyMint.
RunKeyMintRequest(FROM_HERE, &::keymaster::AndroidKeymaster::BeginOperation,
std::move(km_request), std::move(task_lambda));
}
void KeyMintServer::DeviceLocked(
bool password_only,
arc::mojom::keymint::TimeStampTokenPtr timestamp_token,
DeviceLockedCallback callback) {
// Convert input |request| into |km_request|. All data is deep copied to avoid
// use-after-free.
auto km_request =
MakeDeviceLockedRequest(password_only, std::move(timestamp_token),
backend_.keymint()->message_version());
auto task_lambda = base::BindOnce(
[](DeviceLockedCallback callback,
std::unique_ptr<::keymaster::DeviceLockedResponse> km_response) {
// Run callback.
CHECK(km_response);
std::move(callback).Run(km_response->error);
},
std::move(callback));
// Call KeyMint.
RunKeyMintRequest_SingleInput(FROM_HERE,
&::keymaster::AndroidKeymaster::DeviceLocked,
std::move(km_request), std::move(task_lambda));
}
void KeyMintServer::EarlyBootEnded(EarlyBootEndedCallback callback) {
auto task_lambda = base::BindOnce(
[](EarlyBootEndedCallback callback,
std::unique_ptr<::keymaster::EarlyBootEndedResponse> km_response) {
// Run callback.
CHECK(km_response);
std::move(callback).Run(km_response->error);
},
std::move(callback));
// Call KeyMint.
RunKeyMintRequest_EmptyInput(FROM_HERE,
&::keymaster::AndroidKeymaster::EarlyBootEnded,
std::move(task_lambda));
// Signal to libarc-attestation to start provisioning the certificate for
// attestation.
LOG(INFO) << "Provisioning the Lib Arc-Attestation DK Certificate";
arc_attestation::ProvisionDkCert(false /* blocking */);
}
void KeyMintServer::ConvertStorageKeyToEphemeral(
const std::vector<uint8_t>& storage_key_blob,
ConvertStorageKeyToEphemeralCallback callback) {
// Implement this when needed.
auto error =
arc::mojom::keymint::ByteArrayOrError::NewError(KM_ERROR_UNIMPLEMENTED);
std::move(callback).Run(std::move(error));
}
void KeyMintServer::GetRootOfTrustChallenge(
GetRootOfTrustChallengeCallback callback) {
// Implement this when needed.
auto error =
arc::mojom::keymint::ByteArrayOrError::NewError(KM_ERROR_UNIMPLEMENTED);
std::move(callback).Run(std::move(error));
}
void KeyMintServer::GetRootOfTrust(const std::vector<uint8_t>& challenge,
GetRootOfTrustCallback callback) {
// Implement this when needed.
auto error =
arc::mojom::keymint::ByteArrayOrError::NewError(KM_ERROR_UNIMPLEMENTED);
std::move(callback).Run(std::move(error));
}
void KeyMintServer::SendRootOfTrust(const std::vector<uint8_t>& root_of_trust,
SendRootOfTrustCallback callback) {
// Implement this when needed.
std::move(callback).Run(KM_ERROR_UNIMPLEMENTED);
}
void KeyMintServer::UpdateAad(arc::mojom::keymint::UpdateRequestPtr request,
UpdateAadCallback callback) {
// Convert input |request| into |km_request|. All data is deep copied to avoid
// use-after-free.
auto km_request = MakeUpdateAadOperationRequest(
request, backend_.keymint()->message_version());
auto task_lambda = base::BindOnce(
[](UpdateAadCallback callback,
std::unique_ptr<::keymaster::UpdateOperationResponse> km_response) {
// Prepare mojo response.
CHECK(km_response);
auto response = MakeUpdateResult(*km_response);
std::move(callback).Run(km_response->error);
},
std::move(callback));
// Call KeyMint.
RunKeyMintRequest(FROM_HERE, &::keymaster::AndroidKeymaster::UpdateOperation,
std::move(km_request), std::move(task_lambda));
}
void KeyMintServer::Update(arc::mojom::keymint::UpdateRequestPtr request,
UpdateCallback callback) {
// Convert input |request| into |km_request|. All data is deep copied to avoid
// use-after-free.
auto km_request = MakeUpdateOperationRequest(
request, backend_.keymint()->message_version());
auto input_size = km_request->input.buffer_size();
auto task_lambda = base::BindOnce(
[](UpdateCallback callback, const size_t input_size,
std::unique_ptr<::keymaster::UpdateOperationResponse> km_response) {
// Prepare mojo response.
CHECK(km_response);
auto response = MakeUpdateResult(*km_response);
// Run callback.
// This logic is derived from AndroidKeyMintOperation.cpp
if (km_response->error == KM_ERROR_OK &&
km_response->input_consumed != input_size) {
LOG(ERROR) << "KeyMint Server: Unknown error in Update due to size "
"mismatch.";
std::move(callback).Run(
arc::mojom::keymint::ByteArrayOrError::NewError(
KM_ERROR_UNKNOWN_ERROR));
} else {
std::move(callback).Run(std::move(response));
}
},
std::move(callback), std::move(input_size));
// Call KeyMint.
RunKeyMintRequest(FROM_HERE, &::keymaster::AndroidKeymaster::UpdateOperation,
std::move(km_request), std::move(task_lambda));
}
void KeyMintServer::Finish(arc::mojom::keymint::FinishRequestPtr request,
FinishCallback callback) {
// Convert input |request| into |km_request|. All data is deep copied to avoid
// use-after-free.
auto km_request = MakeFinishOperationRequest(
request, backend_.keymint()->message_version());
auto task_lambda = base::BindOnce(
[](FinishCallback callback,
std::unique_ptr<::keymaster::FinishOperationResponse> km_response) {
// Prepare mojo response.
CHECK(km_response);
auto response = MakeFinishResult(*km_response);
// Run callback.
std::move(callback).Run(std::move(response));
},
std::move(callback));
// Call KeyMint.
RunKeyMintRequest(FROM_HERE, &::keymaster::AndroidKeymaster::FinishOperation,
std::move(km_request), std::move(task_lambda));
}
void KeyMintServer::Abort(uint64_t op_handle, AbortCallback callback) {
// Prepare keymint request.
auto km_request = std::make_unique<::keymaster::AbortOperationRequest>(
backend_.keymint()->message_version());
km_request->op_handle = op_handle;
auto task_lambda = base::BindOnce(
[](AbortCallback callback,
std::unique_ptr<::keymaster::AbortOperationResponse> km_response) {
// Run callback.
CHECK(km_response);
std::move(callback).Run(km_response->error);
},
std::move(callback));
// Call keymint.
RunKeyMintRequest(FROM_HERE, &::keymaster::AndroidKeymaster::AbortOperation,
std::move(km_request), std::move(task_lambda));
}
void KeyMintServer::GetSharedSecretParameters(
GetSharedSecretParametersCallback callback) {
auto task_lambda = base::BindOnce(
[](GetSharedSecretParametersCallback callback,
std::unique_ptr<::keymaster::GetHmacSharingParametersResponse>
km_response) {
// Prepare mojo response.
CHECK(km_response);
auto response = MakeGetSharedSecretParametersResult(*km_response);
// Run callback.
std::move(callback).Run(std::move(response));
},
std::move(callback));
// Call keymint.
RunKeyMintRequest_EmptyInput(
FROM_HERE, &::keymaster::AndroidKeymaster::GetHmacSharingParameters,
std::move(task_lambda));
}
void KeyMintServer::ComputeSharedSecret(
const std::vector<arc::mojom::keymint::SharedSecretParametersPtr> request,
ComputeSharedSecretCallback callback) {
// Convert input |request| into |km_request|. All data is deep copied to avoid
// use-after-free.
auto km_request = MakeComputeSharedSecretRequest(
request, backend_.keymint()->message_version());
// Validate the |km_request| before passing to Reference impl.
if (km_request->params_array.params_array == nullptr) {
auto response = arc::mojom::keymint::ByteArrayOrError::NewError(
KM_ERROR_MEMORY_ALLOCATION_FAILED);
std::move(callback).Run(std::move(response));
return;
}
// Validate nonce size for each shared secret parameter.
for (size_t i = 0; i < request.size(); i++) {
if (sizeof(km_request->params_array.params_array[i].nonce) !=
request[i]->nonce.size()) {
auto response = arc::mojom::keymint::ByteArrayOrError::NewError(
KM_ERROR_INVALID_ARGUMENT);
std::move(callback).Run(std::move(response));
return;
}
}
auto task_lambda = base::BindOnce(
[](ComputeSharedSecretCallback callback,
std::unique_ptr<::keymaster::ComputeSharedHmacResponse> km_response) {
// Prepare mojo response.
CHECK(km_response);
auto response = MakeComputeSharedSecretResult(*km_response);
// Run callback.
std::move(callback).Run(std::move(response));
},
std::move(callback));
// Call KeyMint.
RunKeyMintRequest_SingleInput(
FROM_HERE, &::keymaster::AndroidKeymaster::ComputeSharedHmac,
std::move(km_request), std::move(task_lambda));
}
void KeyMintServer::GenerateTimeStamp(const uint64 challenge,
GenerateTimeStampCallback callback) {
// Convert input |request| into |km_request|. All data is deep copied to avoid
// use-after-free.
auto km_request =
std::make_unique<::keymaster::GenerateTimestampTokenRequest>(
backend_.keymint()->message_version());
km_request->challenge = challenge;
auto task_lambda = base::BindOnce(
[](GenerateTimeStampCallback callback,
std::unique_ptr<::keymaster::GenerateTimestampTokenResponse>
km_response) {
// Prepare mojo response.
CHECK(km_response);
auto response = MakeGenerateTimeStampTokenResult(*km_response);
// Run callback.
std::move(callback).Run(std::move(response));
},
std::move(callback));
// Call KeyMint.
RunKeyMintRequest(FROM_HERE,
&::keymaster::AndroidKeymaster::GenerateTimestampToken,
std::move(km_request), std::move(task_lambda));
}
void KeyMintServer::GenerateEcdsaP256KeyPair(
bool test_mode, GenerateEcdsaP256KeyPairCallback callback) {
// Prepare keymint request.
auto km_request = std::make_unique<::keymaster::GenerateRkpKeyRequest>(
backend_.keymint()->message_version());
km_request->test_mode = test_mode;
auto task_lambda = base::BindOnce(
[](GenerateEcdsaP256KeyPairCallback callback,
std::unique_ptr<::keymaster::GenerateRkpKeyResponse> km_response) {
CHECK(km_response);
arc::mojom::keymint::GenerateEcdsaP256KeyPairResultOrErrorPtr response =
MakeGenerateEcdsaP256KeyPairResult(*km_response);
// Run callback.
std::move(callback).Run(std::move(response));
},
std::move(callback));
// Call keymint.
RunKeyMintRequest(FROM_HERE, &::keymaster::AndroidKeymaster::GenerateRkpKey,
std::move(km_request), std::move(task_lambda));
}
} // namespace arc::keymint