lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 3 Mar 2021 19:37:28 +0000
From:   Alex Bennée <alex.bennee@...aro.org>
To:     Ulf Hansson <ulf.hansson@...aro.org>
Cc:     Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
        Maxim Uvarov <maxim.uvarov@...aro.org>,
        Joakim Bech <joakim.bech@...aro.org>,
        Ilias Apalodimas <ilias.apalodimas@...aro.org>,
        Arnd Bergmann <arnd@...aro.org>,
        Ruchika Gupta <ruchika.gupta@...aro.org>,
        Tomas Winkler <tomas.winkler@...el.com>,
        Yang Huang <yang.huang@...el.com>,
        Bing Zhu <bing.zhu@...el.com>,
        Matti Möll <Matti.Moell@...nsynergy.com>,
        Harald Mommer <hmo@...nsynergy.com>,
        "linux-mmc@...r.kernel.org" <linux-mmc@...r.kernel.org>,
        linux-scsi <linux-scsi@...r.kernel.org>,
        linux-nvme@...r.kernel.org,
        Linus Walleij <linus.walleij@...aro.org>,
        Arnd Bergmann <arnd.bergmann@...aro.org>
Subject: Re: [RFC PATCH 1/5] rpmb: add Replay Protected Memory Block (RPMB) subsystem

Foolishly I'd missed you out of the series Cc so you only got those
two patches. You should find the rest @

Subject: [RFC PATCH  0/5] RPMB internal and user-space API + WIP
virtio-rpmb frontend
Date: Wed,  3 Mar 2021 13:54:55 +0000
Message-Id: <20210303135500.24673-1-alex.bennee@...aro.org>

assuming you are subscribed to one of the Cc'd lists.

On Wed, 3 Mar 2021 at 15:29, Ulf Hansson <ulf.hansson@...aro.org> wrote:
>
> On Wed, 3 Mar 2021 at 14:55, Alex Bennée <alex.bennee@...aro.org> wrote:
> >
> > A number of storage technologies support a specialised hardware
> > partition designed to be resistant to replay attacks. The underlying
> > HW protocols differ but the operations are common. The RPMB partition
> > cannot be accessed via standard block layer, but by a set of specific
> > commands: WRITE, READ, GET_WRITE_COUNTER, and PROGRAM_KEY. Such a
> > partition provides authenticated and replay protected access, hence
> > suitable as a secure storage.
> >
> > The RPMB layer aims to provide in-kernel API for Trusted Execution
> > Environment (TEE) devices that are capable to securely compute block
> > frame signature. In case a TEE device wishes to store a replay
> > protected data, requests the storage device via RPMB layer to store
> > the data.
> >
> > A TEE device driver can claim the RPMB interface, for example, via
> > class_interface_register(). The RPMB layer provides a series of
> > operations for interacting with the device.
> >
> >   * program_key - a one time operation for setting up a new device
> >   * get_capacity - introspect the device capacity
> >   * get_write_count - check the write counter
> >   * write_blocks - write a series of blocks to the RPMB device
> >   * read_blocks - read a series of blocks from the RPMB device
> >
> > The detailed operation of implementing the access is left to the TEE
> > device driver itself.
> >
> > [This is based-on Thomas Winkler's proposed API from:
> >
> >   https://lore.kernel.org/linux-mmc/1478548394-8184-2-git-send-email-tomas.winkler@intel.com/
> >
> > The principle difference is the framing details and HW specific
> > bits (JDEC vs NVME frames) are left to the lower level TEE driver to
> > worry about. The eventual userspace ioctl interface will aim to be
> > similarly generic. This is an RFC to follow up on:
> >
> >   Subject: RPMB user space ABI
> >   Date: Thu, 11 Feb 2021 14:07:00 +0000
> >   Message-ID: <87mtwashi4.fsf@...aro.org>]
> >
> > Signed-off-by: Alex Bennée <alex.bennee@...aro.org>
> > Cc: Tomas Winkler <tomas.winkler@...el.com>
> > Cc: Ulf Hansson <ulf.hansson@...aro.org>
> > Cc: Linus  Walleij <linus.walleij@...aro.org>
> > Cc: Arnd Bergmann <arnd.bergmann@...aro.org>
> > Cc: Ilias Apalodimas <ilias.apalodimas@...aro.org>
>
> Alex, I promise to have a closer look at this and provide my opinions.
>
> However, it looks like you have posted patch 1 and patch2, but the
> remainder 3, 4, 5 I can't find. Was this perhaps intentional?
>
> Moreover, I think these kinds of changes deserve a proper
> cover-letter, describing the overall goal with the series. Can you
> perhaps re-submit, so clarify things.
>
> Kind regards
> Uffe
>
> > ---
> >  MAINTAINERS                |   7 +
> >  drivers/char/Kconfig       |   2 +
> >  drivers/char/Makefile      |   1 +
> >  drivers/char/rpmb/Kconfig  |  11 +
> >  drivers/char/rpmb/Makefile |   7 +
> >  drivers/char/rpmb/core.c   | 429 +++++++++++++++++++++++++++++++++++++
> >  include/linux/rpmb.h       | 163 ++++++++++++++
> >  7 files changed, 620 insertions(+)
> >  create mode 100644 drivers/char/rpmb/Kconfig
> >  create mode 100644 drivers/char/rpmb/Makefile
> >  create mode 100644 drivers/char/rpmb/core.c
> >  create mode 100644 include/linux/rpmb.h
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index bfc1b86e3e73..076f3983526c 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -15369,6 +15369,13 @@ T:     git git://linuxtv.org/media_tree.git
> >  F:     Documentation/devicetree/bindings/media/allwinner,sun8i-a83t-de2-rotate.yaml
> >  F:     drivers/media/platform/sunxi/sun8i-rotate/
> >
> > +RPMB SUBSYSTEM
> > +M:     ?
> > +L:     linux-kernel@...r.kernel.org
> > +S:     Supported
> > +F:     drivers/char/rpmb/*
> > +F:     include/linux/rpmb.h
> > +
> >  RTL2830 MEDIA DRIVER
> >  M:     Antti Palosaari <crope@....fi>
> >  L:     linux-media@...r.kernel.org
> > diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
> > index d229a2d0c017..a7834cc3e0ea 100644
> > --- a/drivers/char/Kconfig
> > +++ b/drivers/char/Kconfig
> > @@ -471,6 +471,8 @@ config ADI
> >           and SSM (Silicon Secured Memory).  Intended consumers of this
> >           driver include crash and makedumpfile.
> >
> > +source "drivers/char/rpmb/Kconfig"
> > +
> >  endmenu
> >
> >  config RANDOM_TRUST_CPU
> > diff --git a/drivers/char/Makefile b/drivers/char/Makefile
> > index ffce287ef415..0eed6e21a7a7 100644
> > --- a/drivers/char/Makefile
> > +++ b/drivers/char/Makefile
> > @@ -47,3 +47,4 @@ obj-$(CONFIG_PS3_FLASH)               += ps3flash.o
> >  obj-$(CONFIG_XILLYBUS)         += xillybus/
> >  obj-$(CONFIG_POWERNV_OP_PANEL) += powernv-op-panel.o
> >  obj-$(CONFIG_ADI)              += adi.o
> > +obj-$(CONFIG_RPMB)             += rpmb/
> > diff --git a/drivers/char/rpmb/Kconfig b/drivers/char/rpmb/Kconfig
> > new file mode 100644
> > index 000000000000..431c2823cf70
> > --- /dev/null
> > +++ b/drivers/char/rpmb/Kconfig
> > @@ -0,0 +1,11 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (c) 2015-2019, Intel Corporation.
> > +
> > +config RPMB
> > +       tristate "RPMB partition interface"
> > +       help
> > +         Unified RPMB partition interface for eMMC and UFS.
> > +         Provides interface for in kernel security controllers to
> > +         access RPMB partition.
> > +
> > +         If unsure, select N.
> > diff --git a/drivers/char/rpmb/Makefile b/drivers/char/rpmb/Makefile
> > new file mode 100644
> > index 000000000000..24d4752a9a53
> > --- /dev/null
> > +++ b/drivers/char/rpmb/Makefile
> > @@ -0,0 +1,7 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (c) 2015-2019, Intel Corporation.
> > +
> > +obj-$(CONFIG_RPMB) += rpmb.o
> > +rpmb-objs += core.o
> > +
> > +ccflags-y += -D__CHECK_ENDIAN__
> > diff --git a/drivers/char/rpmb/core.c b/drivers/char/rpmb/core.c
> > new file mode 100644
> > index 000000000000..a2e21c14986a
> > --- /dev/null
> > +++ b/drivers/char/rpmb/core.c
> > @@ -0,0 +1,429 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright(c) 2015 - 2019 Intel Corporation. All rights reserved.
> > + * Copyright(c) 2021 - Linaro Ltd.
> > + */
> > +#include <linux/module.h>
> > +#include <linux/init.h>
> > +#include <linux/kernel.h>
> > +#include <linux/mutex.h>
> > +#include <linux/list.h>
> > +#include <linux/device.h>
> > +#include <linux/slab.h>
> > +
> > +#include <linux/rpmb.h>
> > +
> > +static DEFINE_IDA(rpmb_ida);
> > +
> > +/**
> > + * rpmb_dev_get() - increase rpmb device ref counter
> > + * @rdev: rpmb device
> > + */
> > +struct rpmb_dev *rpmb_dev_get(struct rpmb_dev *rdev)
> > +{
> > +       return get_device(&rdev->dev) ? rdev : NULL;
> > +}
> > +EXPORT_SYMBOL_GPL(rpmb_dev_get);
> > +
> > +/**
> > + * rpmb_dev_put() - decrease rpmb device ref counter
> > + * @rdev: rpmb device
> > + */
> > +void rpmb_dev_put(struct rpmb_dev *rdev)
> > +{
> > +       put_device(&rdev->dev);
> > +}
> > +EXPORT_SYMBOL_GPL(rpmb_dev_put);
> > +
> > +/**
> > + * rpmb_program_key() - program the RPMB access key
> > + * @rdev: rpmb device
> > + * @key: key data
> > + * @keylen: length of key data
> > + *
> > + * A successful programming of the key implies it has been set by the
> > + * driver and can be used.
> > + *
> > + * Return:
> > + * *        0 on success
> > + * *        -EINVAL on wrong parameters
> > + * *        -EPERM key already programmed
> > + * *        -EOPNOTSUPP if device doesn't support the requested operation
> > + * *        < 0 if the operation fails
> > + */
> > +int rpmb_program_key(struct rpmb_dev *rdev, key_serial_t keyid)
> > +{
> > +       int err;
> > +
> > +       if (!rdev || !keyid)
> > +               return -EINVAL;
> > +
> > +       mutex_lock(&rdev->lock);
> > +       err = -EOPNOTSUPP;
> > +       if (rdev->ops && rdev->ops->program_key) {
> > +               err = rdev->ops->program_key(rdev->dev.parent, rdev->target,
> > +                                            keyid);
> > +       }
> > +       mutex_unlock(&rdev->lock);
> > +
> > +       return err;
> > +}
> > +EXPORT_SYMBOL_GPL(rpmb_program_key);
> > +
> > +/**
> > + * rpmb_get_capacity() - returns the capacity of the rpmb device
> > + * @rdev: rpmb device
> > + *
> > + * Return:
> > + * *        capacity of the device in units of 128K, on success
> > + * *        -EINVAL on wrong parameters
> > + * *        -EOPNOTSUPP if device doesn't support the requested operation
> > + * *        < 0 if the operation fails
> > + */
> > +int rpmb_get_capacity(struct rpmb_dev *rdev)
> > +{
> > +       int err;
> > +
> > +       if (!rdev)
> > +               return -EINVAL;
> > +
> > +       mutex_lock(&rdev->lock);
> > +       err = -EOPNOTSUPP;
> > +       if (rdev->ops && rdev->ops->get_capacity)
> > +               err = rdev->ops->get_capacity(rdev->dev.parent, rdev->target);
> > +       mutex_unlock(&rdev->lock);
> > +
> > +       return err;
> > +}
> > +EXPORT_SYMBOL_GPL(rpmb_get_capacity);
> > +
> > +/**
> > + * rpmb_get_write_count() - returns the write counter of the rpmb device
> > + * @rdev: rpmb device
> > + *
> > + * Return:
> > + * *        counter
> > + * *        -EINVAL on wrong parameters
> > + * *        -EOPNOTSUPP if device doesn't support the requested operation
> > + * *        < 0 if the operation fails
> > + */
> > +int rpmb_get_write_count(struct rpmb_dev *rdev)
> > +{
> > +       int err;
> > +
> > +       if (!rdev)
> > +               return -EINVAL;
> > +
> > +       mutex_lock(&rdev->lock);
> > +       err = -EOPNOTSUPP;
> > +       if (rdev->ops && rdev->ops->get_write_count)
> > +               err = rdev->ops->get_write_count(rdev->dev.parent, rdev->target);
> > +       mutex_unlock(&rdev->lock);
> > +
> > +       return err;
> > +}
> > +EXPORT_SYMBOL_GPL(rpmb_get_write_count);
> > +
> > +/**
> > + * rpmb_write_blocks() - write data to RPMB device
> > + * @rdev: rpmb device
> > + * @addr: block address (index of first block - 256B blocks)
> > + * @count: number of 256B blosks
> > + * @data: pointer to data to program
> > + *
> > + * Write a series of blocks to the RPMB device.
> > + *
> > + * Return:
> > + * *        0 on success
> > + * *        -EINVAL on wrong parameters
> > + * *        -EACCESS no key set
> > + * *        -EOPNOTSUPP if device doesn't support the requested operation
> > + * *        < 0 if the operation fails
> > + */
> > +int rpmb_write_blocks(struct rpmb_dev *rdev, key_serial_t keyid, int addr,
> > +                     int count, u8 *data)
> > +{
> > +       int err;
> > +
> > +       if (!rdev || !count || !data)
> > +               return -EINVAL;
> > +
> > +       mutex_lock(&rdev->lock);
> > +       err = -EOPNOTSUPP;
> > +       if (rdev->ops && rdev->ops->write_blocks) {
> > +               err = rdev->ops->write_blocks(rdev->dev.parent, rdev->target, keyid,
> > +                                             addr, count, data);
> > +       }
> > +       mutex_unlock(&rdev->lock);
> > +
> > +       return err;
> > +}
> > +EXPORT_SYMBOL_GPL(rpmb_write_blocks);
> > +
> > +/**
> > + * rpmb_read_blocks() - read data from RPMB device
> > + * @rdev: rpmb device
> > + * @addr: block address (index of first block - 256B blocks)
> > + * @count: number of 256B blocks
> > + * @data: pointer to data to read
> > + *
> > + * Read a series of one or more blocks from the RPMB device.
> > + *
> > + * Return:
> > + * *        0 on success
> > + * *        -EINVAL on wrong parameters
> > + * *        -EACCESS no key set
> > + * *        -EOPNOTSUPP if device doesn't support the requested operation
> > + * *        < 0 if the operation fails
> > + */
> > +int rpmb_read_blocks(struct rpmb_dev *rdev, int addr, int count, u8 *data)
> > +{
> > +       int err;
> > +
> > +       if (!rdev || !count || !data)
> > +               return -EINVAL;
> > +
> > +       mutex_lock(&rdev->lock);
> > +       err = -EOPNOTSUPP;
> > +       if (rdev->ops && rdev->ops->read_blocks) {
> > +               err = rdev->ops->read_blocks(rdev->dev.parent, rdev->target,
> > +                                            addr, count, data);
> > +       }
> > +       mutex_unlock(&rdev->lock);
> > +
> > +       return err;
> > +}
> > +EXPORT_SYMBOL_GPL(rpmb_read_blocks);
> > +
> > +
> > +static void rpmb_dev_release(struct device *dev)
> > +{
> > +       struct rpmb_dev *rdev = to_rpmb_dev(dev);
> > +
> > +       ida_simple_remove(&rpmb_ida, rdev->id);
> > +       kfree(rdev);
> > +}
> > +
> > +struct class rpmb_class = {
> > +       .name = "rpmb",
> > +       .owner = THIS_MODULE,
> > +       .dev_release = rpmb_dev_release,
> > +};
> > +EXPORT_SYMBOL(rpmb_class);
> > +
> > +/**
> > + * rpmb_dev_find_device() - return first matching rpmb device
> > + * @data: data for the match function
> > + * @match: the matching function
> > + *
> > + * Return: matching rpmb device or NULL on failure
> > + */
> > +static
> > +struct rpmb_dev *rpmb_dev_find_device(const void *data,
> > +                                     int (*match)(struct device *dev,
> > +                                                  const void *data))
> > +{
> > +       struct device *dev;
> > +
> > +       dev = class_find_device(&rpmb_class, NULL, data, match);
> > +
> > +       return dev ? to_rpmb_dev(dev) : NULL;
> > +}
> > +
> > +struct device_with_target {
> > +       const struct device *dev;
> > +       u8 target;
> > +};
> > +
> > +static int match_by_parent(struct device *dev, const void *data)
> > +{
> > +       const struct device_with_target *d = data;
> > +       struct rpmb_dev *rdev = to_rpmb_dev(dev);
> > +
> > +       return (d->dev && dev->parent == d->dev && rdev->target == d->target);
> > +}
> > +
> > +/**
> > + * rpmb_dev_find_by_device() - retrieve rpmb device from the parent device
> > + * @parent: parent device of the rpmb device
> > + * @target: RPMB target/region within the physical device
> > + *
> > + * Return: NULL if there is no rpmb device associated with the parent device
> > + */
> > +struct rpmb_dev *rpmb_dev_find_by_device(struct device *parent, u8 target)
> > +{
> > +       struct device_with_target t;
> > +
> > +       if (!parent)
> > +               return NULL;
> > +
> > +       t.dev = parent;
> > +       t.target = target;
> > +
> > +       return rpmb_dev_find_device(&t, match_by_parent);
> > +}
> > +EXPORT_SYMBOL_GPL(rpmb_dev_find_by_device);
> > +
> > +/**
> > + * rpmb_dev_unregister() - unregister RPMB partition from the RPMB subsystem
> > + * @rdev: the rpmb device to unregister
> > + * Return:
> > + * *        0 on success
> > + * *        -EINVAL on wrong parameters
> > + */
> > +int rpmb_dev_unregister(struct rpmb_dev *rdev)
> > +{
> > +       if (!rdev)
> > +               return -EINVAL;
> > +
> > +       mutex_lock(&rdev->lock);
> > +       device_del(&rdev->dev);
> > +       mutex_unlock(&rdev->lock);
> > +
> > +       rpmb_dev_put(rdev);
> > +
> > +       return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(rpmb_dev_unregister);
> > +
> > +/**
> > + * rpmb_dev_unregister_by_device() - unregister RPMB partition
> > + *     from the RPMB subsystem
> > + * @dev: the parent device of the rpmb device
> > + * @target: RPMB target/region within the physical device
> > + * Return:
> > + * *        0 on success
> > + * *        -EINVAL on wrong parameters
> > + * *        -ENODEV if a device cannot be find.
> > + */
> > +int rpmb_dev_unregister_by_device(struct device *dev, u8 target)
> > +{
> > +       struct rpmb_dev *rdev;
> > +
> > +       if (!dev)
> > +               return -EINVAL;
> > +
> > +       rdev = rpmb_dev_find_by_device(dev, target);
> > +       if (!rdev) {
> > +               dev_warn(dev, "no disk found %s\n", dev_name(dev->parent));
> > +               return -ENODEV;
> > +       }
> > +
> > +       rpmb_dev_put(rdev);
> > +
> > +       return rpmb_dev_unregister(rdev);
> > +}
> > +EXPORT_SYMBOL_GPL(rpmb_dev_unregister_by_device);
> > +
> > +/**
> > + * rpmb_dev_get_drvdata() - driver data getter
> > + * @rdev: rpmb device
> > + *
> > + * Return: driver private data
> > + */
> > +void *rpmb_dev_get_drvdata(const struct rpmb_dev *rdev)
> > +{
> > +       return dev_get_drvdata(&rdev->dev);
> > +}
> > +EXPORT_SYMBOL_GPL(rpmb_dev_get_drvdata);
> > +
> > +/**
> > + * rpmb_dev_set_drvdata() - driver data setter
> > + * @rdev: rpmb device
> > + * @data: data to store
> > + */
> > +void rpmb_dev_set_drvdata(struct rpmb_dev *rdev, void *data)
> > +{
> > +       dev_set_drvdata(&rdev->dev, data);
> > +}
> > +EXPORT_SYMBOL_GPL(rpmb_dev_set_drvdata);
> > +
> > +/**
> > + * rpmb_dev_register - register RPMB partition with the RPMB subsystem
> > + * @dev: storage device of the rpmb device
> > + * @target: RPMB target/region within the physical device
> > + * @ops: device specific operations
> > + *
> > + * Return: a pointer to rpmb device
> > + */
> > +struct rpmb_dev *rpmb_dev_register(struct device *dev, u8 target,
> > +                                  const struct rpmb_ops *ops)
> > +{
> > +       struct rpmb_dev *rdev;
> > +       int id;
> > +       int ret;
> > +
> > +       if (!dev || !ops)
> > +               return ERR_PTR(-EINVAL);
> > +
> > +       if (!ops->program_key)
> > +               return ERR_PTR(-EINVAL);
> > +
> > +       if (!ops->get_capacity)
> > +               return ERR_PTR(-EINVAL);
> > +
> > +       if (!ops->get_write_count)
> > +               return ERR_PTR(-EINVAL);
> > +
> > +       if (!ops->write_blocks)
> > +               return ERR_PTR(-EINVAL);
> > +
> > +       if (!ops->read_blocks)
> > +               return ERR_PTR(-EINVAL);
> > +
> > +       if (ops->type == RPMB_TYPE_ANY || ops->type > RPMB_TYPE_MAX)
> > +               return ERR_PTR(-EINVAL);
> > +
> > +       rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
> > +       if (!rdev)
> > +               return ERR_PTR(-ENOMEM);
> > +
> > +       id = ida_simple_get(&rpmb_ida, 0, 0, GFP_KERNEL);
> > +       if (id < 0) {
> > +               ret = id;
> > +               goto exit;
> > +       }
> > +
> > +       mutex_init(&rdev->lock);
> > +       rdev->ops = ops;
> > +       rdev->id = id;
> > +       rdev->target = target;
> > +
> > +       dev_set_name(&rdev->dev, "rpmb%d", id);
> > +       rdev->dev.class = &rpmb_class;
> > +       rdev->dev.parent = dev;
> > +       ret = device_register(&rdev->dev);
> > +       if (ret)
> > +               goto exit;
> > +
> > +       dev_dbg(&rdev->dev, "registered device\n");
> > +
> > +       return rdev;
> > +
> > +exit:
> > +       if (id >= 0)
> > +               ida_simple_remove(&rpmb_ida, id);
> > +       kfree(rdev);
> > +       return ERR_PTR(ret);
> > +}
> > +EXPORT_SYMBOL_GPL(rpmb_dev_register);
> > +
> > +static int __init rpmb_init(void)
> > +{
> > +       ida_init(&rpmb_ida);
> > +       class_register(&rpmb_class);
> > +       return 0;
> > +}
> > +
> > +static void __exit rpmb_exit(void)
> > +{
> > +       class_unregister(&rpmb_class);
> > +       ida_destroy(&rpmb_ida);
> > +}
> > +
> > +subsys_initcall(rpmb_init);
> > +module_exit(rpmb_exit);
> > +
> > +MODULE_AUTHOR("Intel Corporation");
> > +MODULE_DESCRIPTION("RPMB class");
> > +MODULE_LICENSE("GPL v2");
> > diff --git a/include/linux/rpmb.h b/include/linux/rpmb.h
> > new file mode 100644
> > index 000000000000..718ba7c91ecd
> > --- /dev/null
> > +++ b/include/linux/rpmb.h
> > @@ -0,0 +1,163 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
> > +/*
> > + * Copyright (C) 2015-2019 Intel Corp. All rights reserved
> > + * Copyright (C) 2021 Linaro Ltd
> > + */
> > +#ifndef __RPMB_H__
> > +#define __RPMB_H__
> > +
> > +#include <linux/types.h>
> > +#include <linux/device.h>
> > +#include <linux/kref.h>
> > +#include <linux/key.h>
> > +
> > +/**
> > + * struct rpmb_ops - RPMB ops to be implemented by underlying block device
> > + *
> > + * @program_key    : program device key (once only op).
> > + * @get_capacity   : rpmb size in 128K units in for region/target.
> > + * @get_write_count: return the device write counter
> > + * @write_blocks   : write blocks to RPMB device
> > + * @read_blocks    : read blocks from RPMB device
> > + * @block_size     : block size in half sectors (1 == 256B)
> > + * @wr_cnt_max     : maximal number of blocks that can be
> > + *                   written in one access.
> > + * @rd_cnt_max     : maximal number of blocks that can be
> > + *                   read in one access.
> > + * @auth_method    : rpmb_auth_method
> > + * @dev_id         : unique device identifier
> > + * @dev_id_len     : unique device identifier length
> > + */
> > +struct rpmb_ops {
> > +       int (*program_key)(struct device *dev, u8 target, key_serial_t keyid);
> > +       int (*get_capacity)(struct device *dev, u8 target);
> > +       int (*get_write_count)(struct device *dev, u8 target);
> > +       int (*write_blocks)(struct device *dev, u8 target, key_serial_t keyid,
> > +                           int addr, int count, u8 *data);
> > +       int (*read_blocks)(struct device *dev, u8 target,
> > +                          int addr, int count, u8 *data);
> > +       u16 block_size;
> > +       u16 wr_cnt_max;
> > +       u16 rd_cnt_max;
> > +       u16 auth_method;
> > +       const u8 *dev_id;
> > +       size_t dev_id_len;
> > +};
> > +
> > +/**
> > + * struct rpmb_dev - device which can support RPMB partition
> > + *
> > + * @lock       : the device lock
> > + * @dev        : device
> > + * @id         : device id
> > + * @target     : RPMB target/region within the physical device
> > + * @ops        : operation exported by block layer
> > + */
> > +struct rpmb_dev {
> > +       struct mutex lock; /* device serialization lock */
> > +       struct device dev;
> > +       int id;
> > +       u8 target;
> > +       const struct rpmb_ops *ops;
> > +};
> > +
> > +#define to_rpmb_dev(x) container_of((x), struct rpmb_dev, dev)
> > +
> > +#if IS_ENABLED(CONFIG_RPMB)
> > +struct rpmb_dev *rpmb_dev_get(struct rpmb_dev *rdev);
> > +void rpmb_dev_put(struct rpmb_dev *rdev);
> > +struct rpmb_dev *rpmb_dev_find_by_device(struct device *parent, u8 target);
> > +struct rpmb_dev *rpmb_dev_get_by_type(u32 type);
> > +struct rpmb_dev *rpmb_dev_register(struct device *dev, u8 target,
> > +                                  const struct rpmb_ops *ops);
> > +void *rpmb_dev_get_drvdata(const struct rpmb_dev *rdev);
> > +void rpmb_dev_set_drvdata(struct rpmb_dev *rdev, void *data);
> > +int rpmb_dev_unregister(struct rpmb_dev *rdev);
> > +int rpmb_dev_unregister_by_device(struct device *dev, u8 target);
> > +int rpmb_program_key(struct rpmb_dev *rdev, key_serial_t keyid);
> > +int rpmb_get_capacity(struct rpmb_dev *rdev);
> > +int rpmb_get_write_count(struct rpmb_dev *rdev);
> > +int rpmb_write_blocks(struct rpmb_dev *rdev, key_serial_t keyid,
> > +                     int addr, int count, u8 *data);
> > +int rpmb_read_blocks(struct rpmb_dev *rdev, int addr, int count, u8 *data);
> > +
> > +#else
> > +static inline struct rpmb_dev *rpmb_dev_get(struct rpmb_dev *rdev)
> > +{
> > +       return NULL;
> > +}
> > +
> > +static inline void rpmb_dev_put(struct rpmb_dev *rdev) { }
> > +
> > +static inline struct rpmb_dev *rpmb_dev_find_by_device(struct device *parent,
> > +                                                      u8 target)
> > +{
> > +       return NULL;
> > +}
> > +
> > +static inline
> > +struct rpmb_dev *rpmb_dev_get_by_type(enum rpmb_type type)
> > +{
> > +       return NULL;
> > +}
> > +
> > +static inline void *rpmb_dev_get_drvdata(const struct rpmb_dev *rdev)
> > +{
> > +       return NULL;
> > +}
> > +
> > +static inline void rpmb_dev_set_drvdata(struct rpmb_dev *rdev, void *data)
> > +{
> > +}
> > +
> > +static inline struct rpmb_dev *
> > +rpmb_dev_register(struct device *dev, u8 target, const struct rpmb_ops *ops)
> > +{
> > +       return NULL;
> > +}
> > +
> > +static inline int rpmb_dev_unregister(struct rpmb_dev *dev)
> > +{
> > +       return 0;
> > +}
> > +
> > +static inline int rpmb_dev_unregister_by_device(struct device *dev, u8 target)
> > +{
> > +       return 0;
> > +}
> > +
> > +static inline int rpmb_program_key(struct rpmb_dev *rdev, key_serial_t keyid)
> > +{
> > +       return 0;
> > +}
> > +
> > +static inline rpmb_set_key(struct rpmb_dev *rdev, u8 *key, int keylen);
> > +{
> > +       return 0;
> > +}
> > +
> > +static inline int rpmb_get_capacity(struct rpmb_dev *rdev)
> > +{
> > +       return 0;
> > +}
> > +
> > +static inline int rpmb_get_write_count(struct rpmb_dev *rdev)
> > +{
> > +       return 0;
> > +}
> > +
> > +static inline int rpmb_write_blocks(struct rpmb_dev *rdev, int addr, int count,
> > +                                   u8 *data)
> > +{
> > +       return 0;
> > +}
> > +
> > +static inline int rpmb_read_blocks(struct rpmb_dev *rdev, int addr, int count,
> > +                                  u8 *data)
> > +{
> > +       return 0;
> > +}
> > +
> > +#endif /* CONFIG_RPMB */
> > +
> > +#endif /* __RPMB_H__ */
> > --
> > 2.20.1
> >



-- 
Alex Bennée
KVM/QEMU Hacker for Linaro

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ