blob: 449fe23d2c0b4de9c0e8078a5f1a7b9c1dd2d145 [file] [log] [blame]
// Copyright 2021 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/testing/zxcrypt.h"
#include <fcntl.h>
#include <lib/component/incoming/cpp/protocol.h>
#include <lib/device-watcher/cpp/device-watcher.h>
#include <lib/syslog/cpp/macros.h>
#include <ramdevice-client/ramdisk.h>
#include "src/security/lib/zxcrypt/client.h"
#include "src/storage/lib/utils/topological_path.h"
namespace storage {
zx::result<std::string> CreateZxcryptVolume(const std::string& device_path) {
std::string controller_path = device_path + "/device_controller";
zx::result controller = component::Connect<fuchsia_device::Controller>(controller_path);
if (controller.is_error()) {
FX_PLOGS(ERROR, controller.error_value()) << "Could not open test block device";
return zx::error(ZX_ERR_BAD_STATE);
}
fbl::unique_fd dev_fd(open("/dev", O_RDONLY));
if (!dev_fd) {
FX_LOGS(ERROR) << "Could not open /dev";
return zx::error(ZX_ERR_BAD_STATE);
}
zxcrypt::VolumeManager volume_manager(std::move(controller.value()), std::move(dev_fd));
zx::channel driver_chan;
auto status = zx::make_result(volume_manager.OpenClient(zx::sec(2), driver_chan));
if (status.is_error()) {
FX_LOGS(ERROR) << "Could not bind zxcrypt driver on " << device_path;
return status.take_error();
}
zxcrypt::EncryptedVolumeClient volume(std::move(driver_chan));
status = zx::make_result(volume.FormatWithImplicitKey(0));
if (status.is_error()) {
FX_LOGS(ERROR) << "Could not create test zxcrypt volume on " << device_path;
return status.take_error();
}
status = zx::make_result(volume.UnsealWithImplicitKey(0));
if (status.is_error()) {
FX_LOGS(ERROR) << "Could not unseal test zxcrypt volume";
return status.take_error();
}
auto topological_path_or = storage::GetTopologicalPath(device_path);
if (topological_path_or.is_error()) {
FX_LOGS(ERROR) << "Could not get topological path for " << device_path;
return topological_path_or.take_error();
}
std::string zxcrypt_device_path = topological_path_or.value() + "/zxcrypt/unsealed/block";
if (zx::result channel =
device_watcher::RecursiveWaitForFile(zxcrypt_device_path.c_str(), zx::sec(2));
channel.is_error()) {
FX_PLOGS(ERROR, channel.error_value())
<< "Test zxcrypt device never appeared at " << zxcrypt_device_path;
return channel.take_error();
}
return zx::ok(std::move(zxcrypt_device_path));
}
} // namespace storage