blob: cd7fd7abc1e037469485b86d256008c29639883e [file] [log] [blame]
// 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.
#include <stddef.h>
#include <stdint.h>
#include <zircon/compiler.h>
#include <zircon/types.h>
#include <ddk/device.h>
#include <ddktl/device.h>
#include <fbl/macros.h>
#include <fbl/mutex.h>
#include <zxcrypt/volume.h>
namespace zxcrypt {
// |zxcrypt::DeviceManager| is a "wrapper" driver for zxcrypt volumes. Each block device with valid
// zxcrypt metadata will result in a wrapper being created, but the wrapper cannot perform any block
// operations. To perform block operations, |Unseal| must first be called with a valid key and
// slot, which will cause an unsealed |zxcrypt::Device| to be added to the device tree.
class DeviceManager;
using DeviceManagerType = ddk::Device<DeviceManager, ddk::Unbindable, ddk::Messageable>;
class DeviceManager final : public DeviceManagerType {
explicit DeviceManager(zx_device_t* parent) : DeviceManagerType(parent), state_(kBinding) {}
~DeviceManager() = default;
static zx_status_t Create(void* ctx, zx_device_t* parent);
// Adds the device
zx_status_t Bind();
// ddk::Device methods; see ddktl/device.h
void DdkUnbind(ddk::UnbindTxn txn) __TA_EXCLUDES(mtx_);
void DdkRelease();
// ddk::Messageable methods
zx_status_t DdkMessage(fidl_incoming_msg_t* msg, fidl_txn_t* txn) __TA_EXCLUDES(mtx_);
// Unseals the zxcrypt volume and adds it as a |zxcrypt::Device| to the device tree.
zx_status_t Unseal(const uint8_t* ikm, size_t ikm_len, key_slot_t slot) __TA_EXCLUDES(mtx_);
// Removes the unsealed |zxcrypt::Device|, if present.
zx_status_t Seal() __TA_EXCLUDES(mtx_);
// Clobbers the superblock (and any backup superblocks), preventing future
// Unseal operations from succeeding (provided no other program is
// manipulating the underlying block device).
zx_status_t Shred() __TA_EXCLUDES(mtx_);
// Represents the state of this device.
enum State {
// Unseals the zxcrypt volume and adds it as a |zxcrypt::Device| to the device tree.
zx_status_t UnsealLocked(const uint8_t* ikm, size_t ikm_len, key_slot_t slot) __TA_REQUIRES(mtx_);
// Used to ensure calls to |Unseal|, |Seal|, and |Unbind| are exclusive to each
// other, and protects access to |state_|.
fbl::Mutex mtx_;
State state_ __TA_GUARDED(mtx_);
} // namespace zxcrypt