Skip to contentSkip to conversation

Driver for Open Profile for DICE

PATCH Superseded David Brazdil 3 participants 12 messages Dec 9, 2021 – Dec 10, 2021

Subsystems (3)

v2 of 7 Superseded Latest is v7 →

lore
Share & tools
lore
#0 lore raw

v2 cover Driver for Open Profile for DICE

Open Profile for DICE is a secret derivation protocol used by some Android devices. The firmware/bootloader generates the secrets and hands them over to Linux in a reserved memory region.
See https://pigweed.googlesource.com/open-dice for more details.

This patchset adds the corresponding DeviceTree bindings and a driver that takes ownership of the memory region and exposes it to userspace via a misc device.

The patches are based on top of v5.16-rc4 and can also be found here:
https://android-kvm.googlesource.com/linux topic/dice_v2

Changes since v1:
* converted to miscdevice
* all mappings now write-combine to simplify semantics
* removed atomic state, any attempt at exclusive access
* simplified wipe, applied on ioctl, not on release
* fixed ioctl return value

David Brazdil (2):
dt-bindings: firmware: Add Open Profile for DICE
misc: dice: Add driver to forward secrets to userspace

 .../devicetree/bindings/firmware/dice.yaml    |  51 ++++++
 .../userspace-api/ioctl/ioctl-number.rst      |   1 +
 drivers/misc/Kconfig                          |   8 +
 drivers/misc/Makefile                         |   1 +
 drivers/misc/dice.c                           | 161 ++++++++++++++++++
 include/uapi/linux/dice.h                     |  14 ++
 6 files changed, 236 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/firmware/dice.yaml
 create mode 100644 drivers/misc/dice.c
 create mode 100644 include/uapi/linux/dice.h

--
2.34.1.400.ga245620fadb-goog

#1 lore raw

PATCH v2 1/2 dt-bindings: firmware: Add Open Profile for DICE

Add DeviceTree bindings for Open Profile for DICE. DICE is a protocol for deriving Compound Device Identifier (CDI) certificates. These are generated by the firmware/bootloader and stored in memory. Location of the buffer is described as a reserved memory region referenced by a compatible DICE device node.

See https://pigweed.googlesource.com/open-dice

---
 .../devicetree/bindings/firmware/dice.yaml    | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/firmware/dice.yaml
Documentation/devicetree/bindings/firmware/dice.yaml new file +51 -0
new file mode 100644
index 000000000000..c0726109e73d
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/firmware/dice.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Open Profile for DICE Device Tree Bindings
+
+description: |
+  This binding represents a reserved memory region containing secrets derived
+  derived following the Open Profile for DICE.
+
+  See https://pigweed.googlesource.com/open-dice/
+
+maintainers:
+  - David Brazdil <[email protected]>
+
+properties:
+  compatible:
+    enum:
+      - google,dice
+
+  memory-region:
+    maxItems: 1
+    description: |
+      phandle to the reserved memory node to be associated with the device
+      The reserved memory node should be defined as per the bindings,
+      Documentation/devicetree/bindings/reserved-memory/reserved-memory.yaml
+
+required:
+  - compatible
+  - memory-region
+
+additionalProperties: false
+
+examples:
+  - |
+    reserved-memory {
+        #address-cells = <2>;
+        #size-cells = <1>;
+
+        dice_reserved: dice@12340000 {
+            reg = <0x00 0x12340000 0x2000>;
+            no-map;
+        };
+    };
+
+    dice {
+        compatible = "google,dice";
+        memory-region = <&dice_reserved>;
+    };
Signature · 1 line
2.34.1.400.ga245620fadb-goog
#2 lore raw

PATCH v2 2/2 misc: dice: Add driver to forward secrets to userspace

In reply to David Brazdil

Open Profile for DICE is a protocol for deriving unique secrets at boot used by some Android devices. The firmware/bootloader hands over secrets in a reserved memory region, which this driver takes ownership of and exposes it to userspace via a misc device.

Userspace obtains the region's size using an ioctl and mmaps the memory to its address space. This mapping cannot be write+shared, giving userspace a guarantee that the secrets have not been overwritten by another process.

Userspace can also issue an ioctl requesting that the memory be wiped by the driver. Because both the kernel and userspace mappings use write-combine semantics, all clients will observe the memory as zeroed after the ioctl has returned.

Cc Andrew Scull <[email protected]>
Cc Will Deacon <[email protected]>
---
 .../userspace-api/ioctl/ioctl-number.rst      |   1 +
 drivers/misc/Kconfig                          |   8 +
 drivers/misc/Makefile                         |   1 +
 drivers/misc/dice.c                           | 161 ++++++++++++++++++
 include/uapi/linux/dice.h                     |  14 ++
 5 files changed, 185 insertions(+)
 create mode 100644 drivers/misc/dice.c
 create mode 100644 include/uapi/linux/dice.h
Documentation/userspace-api/ioctl/ioctl-number.rst +1 -0
index cfe6cccf0f44..4b8bee2ffd1e 100644
@@ -341,6 +341,7 @@ Code  Seq#    Include File                                           Comments
 0xAE  40-FF  linux/kvm.h                                             Kernel-based Virtual Machine
                                                                      <mailto:[email protected]>
 0xAE  20-3F  linux/nitro_enclaves.h                                  Nitro Enclaves
+0xAE  40-5F  uapi/linux/dice.h                                       Open Profile for DICE driver
 0xAF  00-1F  linux/fsl_hypervisor.h                                  Freescale hypervisor
 0xB0  all                                                            RATIO devices in development:
                                                                      <mailto:[email protected]>
drivers/misc/Kconfig +8 -0
index 0f5a49fc7c9e..7165f4b6c41b 100644
@@ -470,6 +470,14 @@ config HISI_HIKEY_USB
 	  switching between the dual-role USB-C port and the USB-A host ports
 	  using only one USB controller.
 
+config DICE
+	tristate "Open Profile for DICE driver"
+	depends on OF_RESERVED_MEM
+	help
+	  This driver allows to ownership of a reserved memory region
+	  containing DICE secrets and expose them to userspace via
+	  a character device.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
drivers/misc/Makefile +1 -0
index a086197af544..f73c6bb23ccd 100644
@@ -59,3 +59,4 @@ obj-$(CONFIG_UACCE)		+= uacce/
 obj-$(CONFIG_XILINX_SDFEC)	+= xilinx_sdfec.o
 obj-$(CONFIG_HISI_HIKEY_USB)	+= hisi_hikey_usb.o
 obj-$(CONFIG_HI6421V600_IRQ)	+= hi6421v600-irq.o
+obj-$(CONFIG_DICE)		+= dice.o
drivers/misc/dice.c new file +161 -0

161 lines not on this page · raw message

include/uapi/linux/dice.h new file +14 -0
new file mode 100644
index 000000000000..68f7304408ed
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * IOCTLs for Open Profile for DICE character device
+ */
+
+#ifndef _UAPI_DICE_H_
+#define _UAPI_DICE_H_
+
+#include <linux/ioctl.h>
+
+#define DICE_GET_SIZE	_IO(0xAE, 0x40)
+#define DICE_WIPE	_IO(0xAE, 0x41)
+
+#endif

--
2.34.1.400.ga245620fadb-goog

#3 lore raw

Re: [PATCH v2 2/2] misc: dice: Add driver to forward secrets to userspace

Quoted 15 lines · David Brazdil

Open Profile for DICE is a protocol for deriving unique secrets at boot used by some Android devices. The firmware/bootloader hands over secrets in a reserved memory region, which this driver takes ownership of and exposes it to userspace via a misc device.

Userspace obtains the region's size using an ioctl and mmaps the memory to its address space. This mapping cannot be write+shared, giving userspace a guarantee that the secrets have not been overwritten by another process.

Userspace can also issue an ioctl requesting that the memory be wiped by the driver. Because both the kernel and userspace mappings use write-combine semantics, all clients will observe the memory as zeroed after the ioctl has returned.

Quoted 8 lines
Cc Andrew Scull <[email protected]>
Cc Will Deacon <[email protected]>
---
 .../userspace-api/ioctl/ioctl-number.rst      |   1 +
 drivers/misc/Kconfig                          |   8 +
 drivers/misc/Makefile                         |   1 +
 drivers/misc/dice.c                           | 161 ++++++++++++++++++

Nice, almost 100 lines shorter than before!

Much better, thanks for the changes, but it can be made simpler, see comments below:

Quoted 10 lines
 include/uapi/linux/dice.h                     |  14 ++
 5 files changed, 185 insertions(+)
 create mode 100644 drivers/misc/dice.c
 create mode 100644 include/uapi/linux/dice.h
Documentation/userspace-api/ioctl/ioctl-number.rst +0 -0
index cfe6cccf0f44..4b8bee2ffd1e 100644

Documentation/userspace-api/ioctl/ioctl-number.rst Code Seq# Include File Comments · line 344

Quoted 4 lines
Documentation/userspace-api/ioctl/ioctl-number.rst +1 -0
@@ -341,6 +341,7 @@ Code  Seq#    Include File                                           Comments
 0xAE  40-FF  linux/kvm.h                                             Kernel-based Virtual Machine
                                                                      <mailto:[email protected]>
 0xAE  20-3F  linux/nitro_enclaves.h                                  Nitro Enclaves
+0xAE  40-5F  uapi/linux/dice.h                                       Open Profile for DICE driver

Why the huge range? You are only really using 40 and 41. Stick to that please.

Quoted 8 lines
Documentation/userspace-api/ioctl/ioctl-number.rst +0 -0
 0xAF  00-1F  linux/fsl_hypervisor.h                                  Freescale hypervisor
 0xB0  all                                                            RATIO devices in development:
                                                                      <mailto:[email protected]>
drivers/misc/Kconfig +0 -0
index 0f5a49fc7c9e..7165f4b6c41b 100644

drivers/misc/Kconfig config HISI_HIKEY_USB · line 479

Quoted 10 lines
drivers/misc/Kconfig +7 -0
@@ -470,6 +470,14 @@ config HISI_HIKEY_USB
 	  switching between the dual-role USB-C port and the USB-A host ports
 	  using only one USB controller.
 
+config DICE
+	tristate "Open Profile for DICE driver"
+	depends on OF_RESERVED_MEM
+	help
+	  This driver allows to ownership of a reserved memory region
+	  containing DICE secrets and expose them to userspace via
+	  a character device.

What is the module name, please add that here.

And "dice" is a very generic name. I don't mind, but if you want to name it a bit more specific, that might be better.

Quoted 56 lines
drivers/misc/Kconfig +1 -0
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
drivers/misc/Makefile +1 -0
index a086197af544..f73c6bb23ccd 100644
@@ -59,3 +59,4 @@ obj-$(CONFIG_UACCE)		+= uacce/
 obj-$(CONFIG_XILINX_SDFEC)	+= xilinx_sdfec.o
 obj-$(CONFIG_HISI_HIKEY_USB)	+= hisi_hikey_usb.o
 obj-$(CONFIG_HI6421V600_IRQ)	+= hi6421v600-irq.o
+obj-$(CONFIG_DICE)		+= dice.o
drivers/misc/dice.c new file +37 -0
new file mode 100644
index 000000000000..06f3754feb71
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 - Google LLC
+ * Author: David Brazdil <[email protected]>
+ *
+ * Driver for Open Profile for DICE.
+ *
+ * This driver takes ownership of a reserved memory region containing secrets
+ * derived following the Open Profile for DICE. The contents of the memory
+ * region are not interpreted by the kernel but can be mapped into a userspace
+ * process via a misc device. The memory region can also be wiped, removing
+ * the secrets from memory.
+ *
+ * Userspace can access the data by (w/o error handling):
+ *
+ *     int fd = open("/dev/dice", O_RDONLY | O_CLOEXEC);
+ *     size_t size = ioctl(fd, DICE_GET_SIZE);
+ *     void *data = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
+ *     ioctl(fd, DICE_WIPE);
+ *     close(fd);
+ */
+
+#include <linux/dice.h>
+#include <linux/io.h>
+#include <linux/miscdevice.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/platform_device.h>
+
+static int dice_mmap(struct file *filp, struct vm_area_struct *vma);
+static long dice_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+
+static const struct file_operations dice_fops = {
+	.mmap = dice_mmap,
+	.unlocked_ioctl = dice_ioctl,
+};

drivers/misc/dice.c line 47

Quoted 10 lines
drivers/misc/dice.c new file +10 -0
+
+static struct miscdevice dice_misc = {
+	.name	= "dice",
+	.minor	= MISC_DYNAMIC_MINOR,
+	.fops	= &dice_fops,
+	.mode	= 0400,
+};
+
+static struct reserved_mem *dice_rmem;
+static DEFINE_SPINLOCK(dice_lock);

These should be per-device, not global, right? Please put them in a local structure that lives off of the platform device. Then everything is dynamic and nothing is static making it all much simpler again.

Do that and you can get rid of the pre-definitions of dice_mmap() and dice_ioctl() above as well.

Quoted 17 lines
drivers/misc/dice.c new file +17 -0
+
+static int dice_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	/* Do not allow userspace to modify the underlying data. */
+	if ((vma->vm_flags & VM_WRITE) && (vma->vm_flags & VM_SHARED))
+		return -EPERM;
+
+	/* Create write-combine mapping so all clients observe a wipe. */
+	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+	vma->vm_flags |= VM_DONTCOPY | VM_DONTDUMP;
+	return vm_iomap_memory(vma, dice_rmem->base, dice_rmem->size);
+}
+
+static int dice_wipe(void)
+{
+	void *kaddr;
+

drivers/misc/dice.c line 74

Quoted 10 lines
drivers/misc/dice.c new file +10 -0
+	spin_lock(&dice_lock);
+	kaddr = devm_memremap(dice_misc.this_device, dice_rmem->base,
+			      dice_rmem->size, MEMREMAP_WC);
+	if (IS_ERR(kaddr)) {
+		spin_unlock(&dice_lock);
+		return PTR_ERR(kaddr);
+	}
+
+	memzero_explicit(kaddr, dice_rmem->size);
+	devm_memunmap(dice_misc.this_device, kaddr);

Do you really need to call memzero_explicit()? This isn't "local" memory, if the compiler "optimizes away" a normal call, it would be _VERY_ broken.

Quoted 5 lines
drivers/misc/dice.c new file +5 -0
+	spin_unlock(&dice_lock);
+	return 0;
+}
+
+static long dice_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)

drivers/misc/dice.c line 89

Quoted 10 lines
drivers/misc/dice.c new file +10 -0
+{
+	switch (cmd) {
+	case DICE_GET_SIZE:
+		/* Checked against INT_MAX in dice_probe(). */
+		return dice_rmem->size;
+	case DICE_WIPE:
+		return dice_wipe();
+	}
+
+	return -ENOIOCTLCMD;

-ENOTTY please.

As you only have 2 ioctls, why not just use read/write for this? Write would cause dice_wipe() to happen, and read would return the size in the buffer provided. Then no ioctl is needed at all.

drivers/misc/dice.c line 100

Quoted 11 lines
drivers/misc/dice.c new file +11 -0
+}
+
+static int __init dice_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *rmem_np;
+	struct reserved_mem *rmem;
+	int ret;
+
+	if (dice_rmem) {
+		dev_err(dev, "only one instance of device allowed\n");

Why? That's a device-specific thing, not a driver-specific thing. Make this all dynamic and you don't need to care about it at all.

Again, simplification :)

thanks,

greg k-h

#4 lore raw

Re: [PATCH v2 2/2] misc: dice: Add driver to forward secrets to userspace

Hi!

Quoted 6 lines

drivers/misc/dice.c line 74

Quoted 2 lines
drivers/misc/dice.c new file +2 -0
+	memzero_explicit(kaddr, dice_rmem->size);
+	devm_memunmap(dice_misc.this_device, kaddr);

Do you really need to call memzero_explicit()? This isn't "local" memory, if the compiler "optimizes away" a normal call, it would be _VERY_ broken.

For clearing secrets, I believe memzero_explicit is nice documentation.

Best regards,
Pavel

Signature · 1 line
http://www.livejournal.com/~pavelmachek
#5 lore raw

Re: [PATCH v2 2/2] misc: dice: Add driver to forward secrets to userspace

Quoted 11 lines · Pavel Machek

Hi!

Quoted 6 lines

drivers/misc/dice.c line 74

Quoted 2 lines
drivers/misc/dice.c new file +2 -0
+	memzero_explicit(kaddr, dice_rmem->size);
+	devm_memunmap(dice_misc.this_device, kaddr);

Do you really need to call memzero_explicit()? This isn't "local" memory, if the compiler "optimizes away" a normal call, it would be _VERY_ broken.

For clearing secrets, I believe memzero_explicit is nice documentation.

Only if it's really needed please.

#6 lore raw

Re: [PATCH v2 2/2] misc: dice: Add driver to forward secrets to userspace

In reply to Greg Kroah-Hartman
Quoted 25 lines · Greg Kroah-Hartman
Quoted 15 lines · David Brazdil

Open Profile for DICE is a protocol for deriving unique secrets at boot used by some Android devices. The firmware/bootloader hands over secrets in a reserved memory region, which this driver takes ownership of and exposes it to userspace via a misc device.

Userspace obtains the region's size using an ioctl and mmaps the memory to its address space. This mapping cannot be write+shared, giving userspace a guarantee that the secrets have not been overwritten by another process.

Userspace can also issue an ioctl requesting that the memory be wiped by the driver. Because both the kernel and userspace mappings use write-combine semantics, all clients will observe the memory as zeroed after the ioctl has returned.

Quoted 8 lines
Cc Andrew Scull <[email protected]>
Cc Will Deacon <[email protected]>
---
 .../userspace-api/ioctl/ioctl-number.rst      |   1 +
 drivers/misc/Kconfig                          |   8 +
 drivers/misc/Makefile                         |   1 +
 drivers/misc/dice.c                           | 161 ++++++++++++++++++
Quoted 4 lines

Nice, almost 100 lines shorter than before!

Much better, thanks for the changes, but it can be made simpler, see comments below:

Yep, thanks for all the tips!

Quoted 6 lines
Quoted 6 lines
 include/uapi/linux/dice.h                     |  14 ++
 5 files changed, 185 insertions(+)
 create mode 100644 drivers/misc/dice.c
 create mode 100644 include/uapi/linux/dice.h
Quoted 12 lines

Documentation/userspace-api/ioctl/ioctl-number.rst Code Seq# Include File Comments · line 344

Quoted 9 lines
Documentation/userspace-api/ioctl/ioctl-number.rst +1 -0
index cfe6cccf0f44..4b8bee2ffd1e 100644
@@ -341,6 +341,7 @@ Code  Seq#    Include File                                           Comments
 0xAE  40-FF  linux/kvm.h                                             Kernel-based Virtual Machine
                                                                      <mailto:[email protected]>
 0xAE  20-3F  linux/nitro_enclaves.h                                  Nitro Enclaves
+0xAE  40-5F  uapi/linux/dice.h                                       Open Profile for DICE driver

Why the huge range? You are only really using 40 and 41. Stick to that please.

I understood the comments at the top of this file as encouraging devs to err on the side of caution and be more liberal with the reservations in case more ioctls are needed in the future. But I agree that it is highly unlikely this driver will ever need 32 of them.

Quoted 22 lines
Quoted 9 lines
Documentation/userspace-api/ioctl/ioctl-number.rst +0 -0
 0xAF  00-1F  linux/fsl_hypervisor.h                                  Freescale hypervisor
 0xB0  all                                                            RATIO devices in development:
                                                                      <mailto:[email protected]>
drivers/misc/Kconfig +0 -0
index 0f5a49fc7c9e..7165f4b6c41b 100644

drivers/misc/Kconfig config HISI_HIKEY_USB · line 479

Quoted 10 lines
drivers/misc/Kconfig +7 -0
@@ -470,6 +470,14 @@ config HISI_HIKEY_USB
 	  switching between the dual-role USB-C port and the USB-A host ports
 	  using only one USB controller.
 
+config DICE
+	tristate "Open Profile for DICE driver"
+	depends on OF_RESERVED_MEM
+	help
+	  This driver allows to ownership of a reserved memory region
+	  containing DICE secrets and expose them to userspace via
+	  a character device.

What is the module name, please add that here.

Quoted 2 lines

And "dice" is a very generic name. I don't mind, but if you want to name it a bit more specific, that might be better.

Does "open-dice" sound good? I think that's the shorthand used on the official website.

Quoted 71 lines
Quoted 56 lines
drivers/misc/Kconfig +1 -0
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
drivers/misc/Makefile +1 -0
index a086197af544..f73c6bb23ccd 100644
@@ -59,3 +59,4 @@ obj-$(CONFIG_UACCE)		+= uacce/
 obj-$(CONFIG_XILINX_SDFEC)	+= xilinx_sdfec.o
 obj-$(CONFIG_HISI_HIKEY_USB)	+= hisi_hikey_usb.o
 obj-$(CONFIG_HI6421V600_IRQ)	+= hi6421v600-irq.o
+obj-$(CONFIG_DICE)		+= dice.o
drivers/misc/dice.c new file +37 -0
new file mode 100644
index 000000000000..06f3754feb71
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 - Google LLC
+ * Author: David Brazdil <[email protected]>
+ *
+ * Driver for Open Profile for DICE.
+ *
+ * This driver takes ownership of a reserved memory region containing secrets
+ * derived following the Open Profile for DICE. The contents of the memory
+ * region are not interpreted by the kernel but can be mapped into a userspace
+ * process via a misc device. The memory region can also be wiped, removing
+ * the secrets from memory.
+ *
+ * Userspace can access the data by (w/o error handling):
+ *
+ *     int fd = open("/dev/dice", O_RDONLY | O_CLOEXEC);
+ *     size_t size = ioctl(fd, DICE_GET_SIZE);
+ *     void *data = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
+ *     ioctl(fd, DICE_WIPE);
+ *     close(fd);
+ */
+
+#include <linux/dice.h>
+#include <linux/io.h>
+#include <linux/miscdevice.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/platform_device.h>
+
+static int dice_mmap(struct file *filp, struct vm_area_struct *vma);
+static long dice_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+
+static const struct file_operations dice_fops = {
+	.mmap = dice_mmap,
+	.unlocked_ioctl = dice_ioctl,
+};

drivers/misc/dice.c line 47

Quoted 10 lines
drivers/misc/dice.c new file +10 -0
+
+static struct miscdevice dice_misc = {
+	.name	= "dice",
+	.minor	= MISC_DYNAMIC_MINOR,
+	.fops	= &dice_fops,
+	.mode	= 0400,
+};
+
+static struct reserved_mem *dice_rmem;
+static DEFINE_SPINLOCK(dice_lock);

These should be per-device, not global, right? Please put them in a local structure that lives off of the platform device. Then everything is dynamic and nothing is static making it all much simpler again.

Quoted 2 lines

Do that and you can get rid of the pre-definitions of dice_mmap() and dice_ioctl() above as well.0

Ack

Quoted 23 lines
Quoted 23 lines
drivers/misc/dice.c new file +23 -0
+
+static int dice_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	/* Do not allow userspace to modify the underlying data. */
+	if ((vma->vm_flags & VM_WRITE) && (vma->vm_flags & VM_SHARED))
+		return -EPERM;
+
+	/* Create write-combine mapping so all clients observe a wipe. */
+	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+	vma->vm_flags |= VM_DONTCOPY | VM_DONTDUMP;
+	return vm_iomap_memory(vma, dice_rmem->base, dice_rmem->size);
+}
+
+static int dice_wipe(void)
+{
+	void *kaddr;
+
+	spin_lock(&dice_lock);
+	kaddr = devm_memremap(dice_misc.this_device, dice_rmem->base,
+			      dice_rmem->size, MEMREMAP_WC);
+	if (IS_ERR(kaddr)) {
+		spin_unlock(&dice_lock);
+		return PTR_ERR(kaddr);
Quoted 8 lines

drivers/misc/dice.c line 74

Quoted 4 lines
drivers/misc/dice.c new file +4 -0
+	}
+
+	memzero_explicit(kaddr, dice_rmem->size);
+	devm_memunmap(dice_misc.this_device, kaddr);

Do you really need to call memzero_explicit()? This isn't "local" memory, if the compiler "optimizes away" a normal call, it would be _VERY_ broken.

I agree that it's not needed here. Seemed in line with other code that handles secrets but i'm happy to just use memset.

Quoted 9 lines
Quoted 9 lines
drivers/misc/dice.c new file +9 -0
+	spin_unlock(&dice_lock);
+	return 0;
+}
+
+static long dice_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	switch (cmd) {
+	case DICE_GET_SIZE:
+		/* Checked against INT_MAX in dice_probe(). */
Quoted 8 lines

drivers/misc/dice.c line 89

Quoted 6 lines
drivers/misc/dice.c new file +6 -0
+		return dice_rmem->size;
+	case DICE_WIPE:
+		return dice_wipe();
+	}
+
+	return -ENOIOCTLCMD;

-ENOTTY please.

I have no personal attachment to ENOIOCTLCMD, but it is documented as "no ioctl command" and converted to ENOTTY before returning to userspace. That made me think this was the right thing to do.

Quoted 3 lines

As you only have 2 ioctls, why not just use read/write for this? Write would cause dice_wipe() to happen, and read would return the size in the buffer provided. Then no ioctl is needed at all.

Fine by me but does feel like a bit of a hack. Is that a common pattern?

Quoted 21 lines

drivers/misc/dice.c line 100

Quoted 12 lines
drivers/misc/dice.c new file +11 -0
+}
+
+static int __init dice_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *rmem_np;
+	struct reserved_mem *rmem;
+	int ret;
+
+	if (dice_rmem) {
+		dev_err(dev, "only one instance of device allowed\n");

Why? That's a device-specific thing, not a driver-specific thing. Make this all dynamic and you don't need to care about it at all.

Again, simplification :)

thanks,

greg k-h

#7 lore raw

Re: [PATCH v2 2/2] misc: dice: Add driver to forward secrets to userspace

Quoted 7 lines · David Brazdil
Quoted 4 lines · Greg Kroah-Hartman

What is the module name, please add that here.

And "dice" is a very generic name. I don't mind, but if you want to name it a bit more specific, that might be better.

Does "open-dice" sound good? I think that's the shorthand used on the official website.

That might be better.

Naming is hard.

Quoted 13 lines
Quoted 5 lines
Quoted 5 lines
drivers/misc/dice.c new file +5 -0
+static long dice_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	switch (cmd) {
+	case DICE_GET_SIZE:
+		/* Checked against INT_MAX in dice_probe(). */
Quoted 8 lines

drivers/misc/dice.c line 89

Quoted 6 lines
drivers/misc/dice.c new file +6 -0
+		return dice_rmem->size;
+	case DICE_WIPE:
+		return dice_wipe();
+	}
+
+	return -ENOIOCTLCMD;

-ENOTTY please.

Quoted 3 lines

I have no personal attachment to ENOIOCTLCMD, but it is documented as "no ioctl command" and converted to ENOTTY before returning to userspace. That made me think this was the right thing to do.

ENOTTY is better please.

Quoted 4 lines
Quoted 3 lines

As you only have 2 ioctls, why not just use read/write for this? Write would cause dice_wipe() to happen, and read would return the size in the buffer provided. Then no ioctl is needed at all.

Fine by me but does feel like a bit of a hack. Is that a common pattern?

ioctls are hacks too :)

read/write like this is fine to do, might make the code simpler, and allow the code to be used by scripts easier. At the very least, wipe can be done by any language instead of only those that allow ioctls.

thanks,

greg k-h

#8 lore raw

Re: [PATCH v2 2/2] misc: dice: Add driver to forward secrets to userspace

In your first email you also mentioned removing the check in dice_probe() that only allows a single instance. On a second thought, I think it's simpler to keep it there for now, even if the memory is dynamically allocated, which I agree makes the code cleaner.
The reason being that if we allowed multiple instances, we'd also need some static unique identifier that ties the cdev filename to the DT entry, same as /dev/disk/by-uuid/. Just adding an index number to the misc device nodename based on DT probe order sounds very fragile, and anything more sophisticated sounds like too much trouble for something we don't have a clear use case for right now.

Quoted 36 lines · Greg Kroah-Hartman
Quoted 7 lines · David Brazdil
Quoted 4 lines · Greg Kroah-Hartman

What is the module name, please add that here.

And "dice" is a very generic name. I don't mind, but if you want to name it a bit more specific, that might be better.

Does "open-dice" sound good? I think that's the shorthand used on the official website.

That might be better.

Naming is hard.

Quoted 13 lines
Quoted 5 lines
Quoted 5 lines
drivers/misc/dice.c new file +5 -0
+static long dice_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	switch (cmd) {
+	case DICE_GET_SIZE:
+		/* Checked against INT_MAX in dice_probe(). */
Quoted 8 lines

drivers/misc/dice.c line 89

Quoted 6 lines
drivers/misc/dice.c new file +6 -0
+		return dice_rmem->size;
+	case DICE_WIPE:
+		return dice_wipe();
+	}
+
+	return -ENOIOCTLCMD;

-ENOTTY please.

Quoted 3 lines

I have no personal attachment to ENOIOCTLCMD, but it is documented as "no ioctl command" and converted to ENOTTY before returning to userspace. That made me think this was the right thing to do.

ENOTTY is better please.

Quoted 3 lines
Quoted 3 lines

As you only have 2 ioctls, why not just use read/write for this? Write would cause dice_wipe() to happen, and read would return the size in the buffer provided. Then no ioctl is needed at all.

Quoted 7 lines
Quoted 1 line

Fine by me but does feel like a bit of a hack. Is that a common pattern?

ioctls are hacks too :)

read/write like this is fine to do, might make the code simpler, and allow the code to be used by scripts easier. At the very least, wipe can be done by any language instead of only those that allow ioctls.

Alright, read/write it is. And that gets rid of ioctls altogether.

-David

#9 lore raw

Re: [PATCH v2 2/2] misc: dice: Add driver to forward secrets to userspace

Quoted 4 lines · David Brazdil

In your first email you also mentioned removing the check in dice_probe() that only allows a single instance. On a second thought, I think it's simpler to keep it there for now, even if the memory is dynamically allocated, which I agree makes the code cleaner.

I don't remember what check you are talking about at all, sorry.

Remember some of us review hundreds of patches each week :(

Quoted 6 lines

The reason being that if we allowed multiple instances, we'd also need some static unique identifier that ties the cdev filename to the DT entry, same as /dev/disk/by-uuid/. Just adding an index number to the misc device nodename based on DT probe order sounds very fragile, and anything more sophisticated sounds like too much trouble for something we don't have a clear use case for right now.

Just add a number to the device node name like every other device in the system has. Nothing new or special here, right?

thanks,

greg k-h

#10 lore raw

DRM? Re: [PATCH v2 2/2] misc: dice: Add driver to forward secrets to userspace

In reply to David Brazdil

Hi!

drivers/misc/Kconfig config HISI_HIKEY_USB · line 480

Quoted 8 lines
drivers/misc/Kconfig +8 -0
+config DICE
+	tristate "Open Profile for DICE driver"
+	depends on OF_RESERVED_MEM
+	help
+	  This driver allows to ownership of a reserved memory region
+	  containing DICE secrets and expose them to userspace via
+	  a character device.
+

Explaining what DICE is (and what Open Profile is) would be useful.

I see it is for some kind of DRM? Why is in non-evil and why do we want it in Linux?
Pavel

Signature · 1 line
http://www.livejournal.com/~pavelmachek
#11 lore raw

Re: DRM? Re: [PATCH v2 2/2] misc: dice: Add driver to forward secrets to userspace

Hi Pavel,

Quoted 12 lines · Pavel Machek

Hi!

drivers/misc/Kconfig config HISI_HIKEY_USB · line 480

Quoted 8 lines
drivers/misc/Kconfig +8 -0
+config DICE
+	tristate "Open Profile for DICE driver"
+	depends on OF_RESERVED_MEM
+	help
+	  This driver allows to ownership of a reserved memory region
+	  containing DICE secrets and expose them to userspace via
+	  a character device.
+

Explaining what DICE is (and what Open Profile is) would be useful.

Sure, I'll expand the description.

Quoted 2 lines

I see it is for some kind of DRM? Why is in non-evil and why do we want it in Linux?

Best to think of this as an extension to verified boot where each boot stage signs the hashes of the software it loaded. The certificate is what's passed in this reserved memory region. It is used in the context of confidential computing for remote attestation, and it is very similar to the EFI-based approach from IBM for SEV:
https://lore.kernel.org/all/[email protected]/

There's a link to the project's documentation in the cover letter with much more technical detail if you're interested.

-David