blob: eefd1194e46fbc3266469cf965742227bd5fa338 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/storage/fs_test/crypt_service.h"
#include <fidl/fuchsia.fxfs/cpp/wire.h>
#include <lib/fdio/directory.h>
#include <lib/fidl/llcpp/channel.h>
#include <lib/fidl/llcpp/connect_service.h>
#include <lib/service/llcpp/service.h>
#include "sdk/lib/syslog/cpp/macros.h"
namespace fs_test {
zx::status<> SetUpCryptWithRandomKeys(
fidl::UnownedClientEnd<fuchsia_io::Directory> service_directory) {
fidl::WireSyncClient<fuchsia_fxfs::CryptManagement> client;
if (auto management_service_or =
service::ConnectAt<fuchsia_fxfs::CryptManagement>(service_directory);
management_service_or.is_error()) {
FX_LOGS(ERROR) << "Unable to connect to crypt management service: "
<< management_service_or.status_string();
return management_service_or.take_error();
} else {
client = fidl::BindSyncClient(*std::move(management_service_or));
}
unsigned char key[32];
zx_cprng_draw(key, sizeof(key));
if (auto result = client->AddWrappingKey(0, fidl::VectorView<unsigned char>::FromExternal(key));
!result.ok()) {
FX_LOGS(ERROR) << "Failed to add wrapping key: " << result.status_string();
return zx::error(result.status());
}
zx_cprng_draw(key, sizeof(key));
if (auto result = client->AddWrappingKey(1, fidl::VectorView<unsigned char>::FromExternal(key));
!result.ok()) {
FX_LOGS(ERROR) << "Failed to add wrapping key: " << result.status_string();
return zx::error(result.status());
}
if (auto result = client->SetActiveKey(fuchsia_fxfs::wire::KeyPurpose::kData, 0); !result.ok()) {
FX_LOGS(ERROR) << "Failed to set active data key: " << result.status_string();
return zx::error(result.status());
}
if (auto result = client->SetActiveKey(fuchsia_fxfs::wire::KeyPurpose::kMetadata, 1);
!result.ok()) {
FX_LOGS(ERROR) << "Failed to set active data key: " << result.status_string();
return zx::error(result.status());
}
return zx::ok();
}
zx::status<zx::channel> GetCryptService() {
static bool initialized = false;
if (!initialized) {
auto service_endpoints_or = fidl::CreateEndpoints<fuchsia_io::Directory>();
if (service_endpoints_or.is_error()) {
FX_LOGS(ERROR) << "Unable to create endpoints: " << service_endpoints_or.status_string();
return service_endpoints_or.take_error();
}
if (zx_status_t status =
fdio_open("/svc",
static_cast<uint32_t>(fuchsia_io::wire::OpenFlags::kRightReadable |
fuchsia_io::wire::OpenFlags::kRightWritable),
service_endpoints_or->server.TakeChannel().release());
status != ZX_OK) {
FX_LOGS(ERROR) << "Unable to open /svc: " << zx_status_get_string(status);
return zx::error(status);
}
if (auto status = SetUpCryptWithRandomKeys(service_endpoints_or->client); status.is_error()) {
return status.take_error();
}
initialized = true;
}
if (auto crypt_service_or = service::Connect<fuchsia_fxfs::Crypt>();
crypt_service_or.is_error()) {
FX_LOGS(ERROR) << "Unable to connect to the crypt service: "
<< crypt_service_or.status_string();
return crypt_service_or.take_error();
} else {
return zx::ok(crypt_service_or->TakeChannel());
}
}
} // namespace fs_test