blob: 224471a0865ebb9ba5f535d32cbbb49f48014c42 [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.
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <ddk/device.h>
#include <ddktl/device.h>
#include <fbl/macros.h>
#include <fbl/mutex.h>
#include <zircon/compiler.h>
#include <zircon/types.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 {
public:
explicit DeviceManager(zx_device_t* parent)
: DeviceManagerType(parent), state_(kBinding){}
~DeviceManager() = default;
DISALLOW_COPY_ASSIGN_AND_MOVE(DeviceManager);
// Adds the device
zx_status_t Bind();
// ddk::Device methods; see ddktl/device.h
void DdkUnbind() __TA_EXCLUDES(mtx_);
void DdkRelease();
// ddk::Messageable methods
zx_status_t DdkMessage(fidl_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_);
// Calls |Unseal| with a fixed key.
// TODO(security): ZX-3257. This stopgap should be removed when the zxcrypt FIDL interface is
// available.
void AutoUnseal() __TA_EXCLUDES(mtx_);
private:
// Represents the state of this device.
// TODO(security): ZX-3257. When |AutoUnseal| is removed, this can be reduced to a simple
// boolean indicating un/sealed.
enum State {
kBinding,
kSealed,
kUnsealed,
kUnbinding,
kRemoved,
};
// Unseals the zxcrypt volume and adds it as a |zxcrypt::Device| to the device tree.
// TODO(security): ZX-3257. When |AutoUnseal| is removed, this can be merged into |Unseal|.
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|,|Unbind|, an |AutoUnseal| are exclusive to each
// other, and protects access to |state_|.
// TODO(security): ZX-3257. Update comment when |AutoUnseal|, |state_| are removed.
fbl::Mutex mtx_;
// TODO(security): ZX-3257. See commnt on |State| above.
State state_ __TA_GUARDED(mtx_);
};
} // namespace zxcrypt