Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Secdev driver #2

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
5 changes: 5 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,11 @@ M: Wei Liu <[email protected]>
S: Supported
T: git https://xenbits.xenproject.org/git-http/seabios.git

SECURITY HARDWARE DRIVERS
M: Daniel P. Smith <[email protected]>
S: Maintained
F: xen/drivers/security/

STUB DOMAINS
M: Samuel Thibault <[email protected]>
S: Supported
Expand Down
33 changes: 33 additions & 0 deletions xen/arch/x86/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <xen/dmi.h>
#include <xen/pfn.h>
#include <xen/nodemask.h>
#include <xen/secdev.h>
#include <xen/virtual_region.h>
#include <xen/watchdog.h>
#include <public/version.h>
Expand Down Expand Up @@ -951,6 +952,35 @@ static struct domain *__init create_dom0(const module_t *image,
write_cr4(read_cr4() & ~X86_CR4_SMAP);
}

/* Dom0 can now be measure as the comand line has been finalized. */
if ( secdev_available(SECDEV_TPM) )
{
void *image_base = bootstrap_map(image);
secdev_opt_t opts = { 0 };

opts.tpm.domain.locality = SECDEV_TPM_DEFAULT_LOCALITY;
opts.tpm.domain.pcr = SECDEV_TPM_DEFAULT_PCR;

opts.tpm.domain.kern = image_base + headroom;
opts.tpm.domain.kern_size = image->mod_end - headroom;

opts.tpm.domain.cmdline = cmdline;

printk(XENLOG_INFO "%pd: measuring kernel%s\n", d,
initrd ? " and ramdisk" : "");

if ( initrd )
{
opts.tpm.domain.initrd = bootstrap_map(initrd);
opts.tpm.domain.initrd_size = initrd->mod_end;
}

if ( secdev_measure_domain(SECDEV_TPM, &opts) < 0 )
printk(XENLOG_ERR " Domain measurement failed\n");

bootstrap_map(NULL);
}

if ( construct_dom0(d, image, headroom, initrd, cmdline) != 0 )
panic("Could not construct domain 0\n");

Expand Down Expand Up @@ -1770,6 +1800,9 @@ void __init noreturn __start_xen(unsigned long mbi_p)

tboot_probe();

if ( secdev_init() == 0 )
printk("Security Devices initialized\n");

open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period);

if ( opt_watchdog )
Expand Down
2 changes: 2 additions & 0 deletions xen/drivers/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ source "drivers/passthrough/Kconfig"

source "drivers/pci/Kconfig"

source "drivers/security/Kconfig"

source "drivers/video/Kconfig"

config HAS_VPCI
Expand Down
1 change: 1 addition & 0 deletions xen/drivers/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ obj-$(CONFIG_HAS_VPCI) += vpci/
obj-$(CONFIG_HAS_PASSTHROUGH) += passthrough/
obj-$(CONFIG_ACPI) += acpi/
obj-$(CONFIG_VIDEO) += video/
obj-$(CONFIG_SECURITY_DEVICES) += security/
19 changes: 19 additions & 0 deletions xen/drivers/security/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

config SECURITY_DEVICES
bool "Security Devices (UNSUPPORTED)" if UNSUPPORTED
default n
---help---
Enable Xen to manage and use platform security hardware.

Say Y here if your platform has security hardware.

config TPM_HARDWARE
bool "TPM Support"
default y
depends on SECURITY_DEVICES
select CRYPTO
---help---
Xen will take control of a TPM, if present, and make it available
for the hypervisor and domains.

Say Y here if it is desired for Xen to use the TPM.
2 changes: 2 additions & 0 deletions xen/drivers/security/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
obj-$(CONFIG_SECURITY_DEVICES) += secdev.o
obj-$(CONFIG_TPM_HARDWARE) += tpm/
106 changes: 106 additions & 0 deletions xen/drivers/security/secdev.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/* SPDX-License-Identifier: BSD-3-Clause */

/*
* Copyright (c) 2023, Apertus Solutions, LLC
* All rights reserved.
*/

#include <xen/err.h>
#include <xen/lib.h>

#include "secdev.h"
#include "tpm/tpm_drv.h"

static struct {
struct secdev_handle *tpm;
} dev_handles;

static struct secdev_handle *get_dev_handle(secdev_id_t id)
{
switch ( id )
{
case SECDEV_TPM:
if ( dev_handles.tpm != NULL )
return dev_handles.tpm;

printk(XENLOG_ERR "Requested TPM but no TPM was registered\n");
break;
default:
printk(XENLOG_ERR "Unknown device id (%d)\n", id);
}

return NULL;
}

ssize_t secdev_getrandom(enum secdev_id dev_id, secdev_opt_t *opts)
{
struct secdev_handle *h = get_dev_handle(dev_id);
secdev_result_t res;
int ret = 0;

if ( h == NULL )
return -EINVAL;

if ( h->getrandom == NULL )
{
printk(XENLOG_ERR "getrandom() unsupported by security device (%d) \n",
dev_id);
return -EINVAL;
}

ret = h->getrandom(opts, &res);
if ( ret < 0 )
return ret;

return res.tpm.random.len;
}

int secdev_measure_buffer(enum secdev_id dev_id, secdev_opt_t *opts)
{
struct secdev_handle *h = get_dev_handle(dev_id);
secdev_result_t res;

if ( h == NULL )
return -EINVAL;

if ( h->measure_buffer == NULL )
{
printk(XENLOG_ERR "measure_domain() unsupported by security device (%d) \n",
dev_id);
return -EINVAL;
}

return h->measure_buffer(opts, &res);
}

int secdev_measure_domain(enum secdev_id dev_id, secdev_opt_t *opts)
{
struct secdev_handle *h = get_dev_handle(dev_id);
secdev_result_t res;

if ( h == NULL )
return -EINVAL;

if ( h->measure_domain == NULL )
{
printk(XENLOG_ERR "measure_domain() unsupported by security device (%d) \n",
dev_id);
return -EINVAL;
}

return h->measure_domain(opts, &res);
}

bool secdev_available(enum secdev_id dev_id)
{
return (get_dev_handle(dev_id) != NULL);
}

int secdev_init(void)
{
#ifdef CONFIG_TPM_HARDWARE
dev_handles.tpm = tpm_driver_init();
#endif

return 0;
}
38 changes: 38 additions & 0 deletions xen/drivers/security/secdev.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* SPDX-License-Identifier: BSD-3-Clause */

/*
* Copyright (c) 2023, Apertus Solutions, LLC
* All rights reserved.
*/

#ifndef __SECDEV_H__
#define __SECDEV_H__

#include <xen/lib/hash.h>
#include <xen/secdev.h>

struct tpm_dev_result {
union {
struct {
ssize_t len;
} random;
struct {
hash_t digest;
} measure;
};
};

typedef union secdev_result {
struct tpm_dev_result tpm;
} secdev_result_t;

struct secdev_handle {
int (*getrandom)(secdev_opt_t *opts, secdev_result_t *res);
int (*measure_buffer)(secdev_opt_t *opts, secdev_result_t *res);
int (*register_domain)(secdev_opt_t *opts, secdev_result_t *res);
int (*measure_domain)(secdev_opt_t *opts, secdev_result_t *res);
int (*launch_domain)(secdev_opt_t *opts, secdev_result_t *res);
int (*direct_op)(secdev_opt_t *opts, secdev_result_t *res);
};

#endif
5 changes: 5 additions & 0 deletions xen/drivers/security/tpm/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
obj-y += tpm.o
obj-y += tpm_mmio.o
obj-y += tpm_12.o
obj-y += tpm_20.o
obj-y += tpm_drv.o
Loading