blob: a7f5a04b57366debe640819eb9236bf544f08321 [file] [log] [blame] [edit]
// Copyright 2019 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.
#ifndef SRC_SECURITY_LIB_ZXCRYPT_FDIO_VOLUME_H_
#define SRC_SECURITY_LIB_ZXCRYPT_FDIO_VOLUME_H_
#include <fidl/fuchsia.hardware.block/cpp/wire.h>
#include <memory>
#include "src/security/lib/fcrypto/secret.h"
#include "src/security/lib/zxcrypt/volume.h"
namespace zxcrypt {
// |zxcrypt::FdioVolume| is a zxcrypt volume which does IO via a file descriptor
// to an underlying block device without any support from the zxcrypt driver
// implementation. It can be used on the host to prepare zxcrypt images, and is
// often more convenient for testing.
class __EXPORT FdioVolume final : public Volume {
public:
explicit FdioVolume(fidl::ClientEnd<fuchsia_hardware_block::Block> channel);
// Creates a new zxcrypt volume associated with the given file descriptor,
// |block|, and returns it via |out|, if provided. This will format
// the block device as zxcrypt using the given |key|, which will be
// associated with key slot 0. This method takes ownership of
// |block|. Note that |key| is not strengthened
// and MUST have cryptographic key length of at least 128 bits.
static zx_status_t Create(fidl::ClientEnd<fuchsia_hardware_block::Block> channel,
const crypto::Secret& key, std::unique_ptr<FdioVolume>* out = nullptr);
// Opens a zxcrypt volume on the block device described by |block|
// using the |key| corresponding to given key |slot|. This method takes
// ownership of |block|. Note that |key| is not strengthened and MUST
// have cryptographic key length of at least 128 bits. This is a convenience
// method that calls |Init()| and then |FdioVolume::Unlock()|.
static zx_status_t Unlock(fidl::ClientEnd<fuchsia_hardware_block::Block> channel,
const crypto::Secret& key, key_slot_t slot,
std::unique_ptr<FdioVolume>* out);
// Returns a new volume object corresponding to the block device given by
// |block| and populated with the block and FVM information.
static zx_status_t Init(fidl::ClientEnd<fuchsia_hardware_block::Block> channel,
std::unique_ptr<FdioVolume>* out = nullptr);
// Opens a zxcrypt volume on the block device described by |fd| using the |key| corresponding to
// given key |slot|.
zx_status_t Unlock(const crypto::Secret& key, key_slot_t slot);
// Adds a given |key| to the given key |slot|. This key can then be used to |Open| the
// zxcrypt device. This method can only be called if the volume belongs to libzxcrypt.
zx_status_t Enroll(const crypto::Secret& key, key_slot_t slot);
// Removes the root key in the given key |slot|. This key can no longer be used to |Open| the
// zxcrypt device. This method can only be called if the volume belongs to libzxcrypt.
zx_status_t Revoke(key_slot_t slot);
private:
friend class testing::TestDevice;
// Retrieves the block and FVM information and adjusts it
zx_status_t Init();
zx_status_t GetBlockInfo(BlockInfo* out) override;
zx_status_t GetFvmSliceSize(uint64_t* out) override;
zx_status_t DoBlockFvmVsliceQuery(uint64_t vslice_start, SliceRegion ranges[MAX_SLICE_REGIONS],
uint64_t* slice_count) override;
zx_status_t DoBlockFvmExtend(uint64_t start_slice, uint64_t slice_count) override;
// Reads a block from the current offset on the underlying device.
zx_status_t Read() override;
// Writes a block to the current offset on the underlying device.
zx_status_t Write() override;
// Flushes all pending writes to the underlying device.
zx_status_t Flush() override;
// The underlying block device.
fidl::ClientEnd<fuchsia_hardware_block::Block> channel_;
};
} // namespace zxcrypt
#endif // SRC_SECURITY_LIB_ZXCRYPT_FDIO_VOLUME_H_