linux-integrity.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Oliver O'Halloran <oohall@gmail.com>
To: Nayna Jain <nayna@linux.ibm.com>,
	linuxppc-dev@ozlabs.org, linux-efi@vger.kernel.org,
	linux-integrity@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
	Michael Ellerman <mpe@ellerman.id.au>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Paul Mackerras <paulus@samba.org>,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	Jeremy Kerr <jk@ozlabs.org>,
	Matthew Garret <matthew.garret@nebula.com>,
	Mimi Zohar <zohar@linux.ibm.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Claudio Carvalho <cclaudio@linux.ibm.com>,
	George Wilson <gcwilson@linux.ibm.com>,
	Elaine Palmer <erpalmer@us.ibm.com>,
	Eric Ricther <erichte@linux.ibm.com>
Subject: Re: [PATCH v4 1/4] powerpc/powernv: Add OPAL API interface to access secure variable
Date: Tue, 15 Oct 2019 19:11:29 +1100	[thread overview]
Message-ID: <6ebe7ed1577115664ad7d82200c6a30ea2a93658.camel@gmail.com> (raw)
In-Reply-To: <1569973311-3047-2-git-send-email-nayna@linux.ibm.com>

On Tue, 2019-10-01 at 19:41 -0400, Nayna Jain wrote:
> The X.509 certificates trusted by the platform and required to secure boot
> the OS kernel are wrapped in secure variables, which are controlled by
> OPAL.
> 
> This patch adds firmware/kernel interface to read and write OPAL secure
> variables based on the unique key.
> 
> This support can be enabled using CONFIG_OPAL_SECVAR.
> 
> Signed-off-by: Claudio Carvalho <cclaudio@linux.ibm.com>
> Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
> ---
>  arch/powerpc/include/asm/opal-api.h          |   5 +-
>  arch/powerpc/include/asm/opal.h              |   8 ++
>  arch/powerpc/include/asm/powernv.h           |   2 +
>  arch/powerpc/include/asm/secvar.h            |  35 +++++
>  arch/powerpc/kernel/Makefile                 |   2 +-
>  arch/powerpc/kernel/secvar-ops.c             |  19 +++
>  arch/powerpc/platforms/powernv/Kconfig       |   6 +
>  arch/powerpc/platforms/powernv/Makefile      |   1 +
>  arch/powerpc/platforms/powernv/opal-call.c   |   3 +
>  arch/powerpc/platforms/powernv/opal-secvar.c | 137 +++++++++++++++++++
>  arch/powerpc/platforms/powernv/opal.c        |   5 +
>  11 files changed, 221 insertions(+), 2 deletions(-)
>  create mode 100644 arch/powerpc/include/asm/secvar.h
>  create mode 100644 arch/powerpc/kernel/secvar-ops.c
>  create mode 100644 arch/powerpc/platforms/powernv/opal-secvar.c
> 
> diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h
> index 378e3997845a..c1f25a760eb1 100644
> --- a/arch/powerpc/include/asm/opal-api.h
> +++ b/arch/powerpc/include/asm/opal-api.h
> @@ -211,7 +211,10 @@
>  #define OPAL_MPIPL_UPDATE			173
>  #define OPAL_MPIPL_REGISTER_TAG			174
>  #define OPAL_MPIPL_QUERY_TAG			175
> -#define OPAL_LAST				175
> +#define OPAL_SECVAR_GET				176
> +#define OPAL_SECVAR_GET_NEXT			177
> +#define OPAL_SECVAR_ENQUEUE_UPDATE		178
> +#define OPAL_LAST				178
>  
>  #define QUIESCE_HOLD			1 /* Spin all calls at entry */
>  #define QUIESCE_REJECT			2 /* Fail all calls with OPAL_BUSY */
> diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
> index a0cf8fba4d12..03392dc3f5e2 100644
> --- a/arch/powerpc/include/asm/opal.h
> +++ b/arch/powerpc/include/asm/opal.h
> @@ -298,6 +298,13 @@ int opal_sensor_group_clear(u32 group_hndl, int token);
>  int opal_sensor_group_enable(u32 group_hndl, int token, bool enable);
>  int opal_nx_coproc_init(uint32_t chip_id, uint32_t ct);
>  
> +int opal_secvar_get(const char *key, uint64_t key_len, u8 *data,
> +		    uint64_t *data_size);
> +int opal_secvar_get_next(const char *key, uint64_t *key_len,
> +			 uint64_t key_buf_size);
> +int opal_secvar_enqueue_update(const char *key, uint64_t key_len, u8 *data,
> +			       uint64_t data_size);
> +
>  s64 opal_mpipl_update(enum opal_mpipl_ops op, u64 src, u64 dest, u64 size);
>  s64 opal_mpipl_register_tag(enum opal_mpipl_tags tag, u64 addr);
>  s64 opal_mpipl_query_tag(enum opal_mpipl_tags tag, u64 *addr);
> @@ -392,6 +399,7 @@ void opal_wake_poller(void);
>  void opal_powercap_init(void);
>  void opal_psr_init(void);
>  void opal_sensor_groups_init(void);
> +void opal_secvar_init(void);
>  
>  #endif /* __ASSEMBLY__ */
>  
> diff --git a/arch/powerpc/include/asm/powernv.h b/arch/powerpc/include/asm/powernv.h
> index e1a858718716..cff980a85dd2 100644
> --- a/arch/powerpc/include/asm/powernv.h
> +++ b/arch/powerpc/include/asm/powernv.h
> @@ -12,10 +12,12 @@ extern void powernv_set_nmmu_ptcr(unsigned long ptcr);
>  void pnv_program_cpu_hotplug_lpcr(unsigned int cpu, u64 lpcr_val);
>  
>  void pnv_tm_init(void);
> +
>  #else
>  static inline void powernv_set_nmmu_ptcr(unsigned long ptcr) { }
>  
>  static inline void pnv_tm_init(void) { }
> +
>  #endif
>  
>  #endif /* _ASM_POWERNV_H */
> diff --git a/arch/powerpc/include/asm/secvar.h b/arch/powerpc/include/asm/secvar.h
> new file mode 100644
> index 000000000000..4cc35b58b986
> --- /dev/null
> +++ b/arch/powerpc/include/asm/secvar.h
> @@ -0,0 +1,35 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2019 IBM Corporation
> + * Author: Nayna Jain
> + *
> + * PowerPC secure variable operations.
> + */
> +#ifndef SECVAR_OPS_H
> +#define SECVAR_OPS_H
> +
> +#include <linux/types.h>
> +#include <linux/errno.h>
> +
> +extern const struct secvar_operations *secvar_ops;
> +
> +struct secvar_operations {
> +	int (*get)(const char *key, uint64_t key_len, u8 *data,
> +		   uint64_t *data_size);
> +	int (*get_next)(const char *key, uint64_t *key_len,
> +			uint64_t keybufsize);
> +	int (*set)(const char *key, uint64_t key_len, u8 *data,
> +		   uint64_t data_size);
> +};
> +
> +#ifdef CONFIG_PPC_SECURE_BOOT
> +
> +extern void set_secvar_ops(const struct secvar_operations *ops);
> +
> +#else
> +
> +static inline void set_secvar_ops(const struct secvar_operations *ops) { }
> +
> +#endif
> +
> +#endif
> diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
> index e8eb2955b7d5..3cf26427334f 100644
> --- a/arch/powerpc/kernel/Makefile
> +++ b/arch/powerpc/kernel/Makefile
> @@ -161,7 +161,7 @@ ifneq ($(CONFIG_PPC_POWERNV)$(CONFIG_PPC_SVM),)
>  obj-y				+= ucall.o
>  endif
>  
> -obj-$(CONFIG_PPC_SECURE_BOOT)	+= secure_boot.o ima_arch.o
> +obj-$(CONFIG_PPC_SECURE_BOOT)	+= secure_boot.o ima_arch.o secvar-ops.o
>  
>  # Disable GCOV, KCOV & sanitizers in odd or sensitive code
>  GCOV_PROFILE_prom_init.o := n
> diff --git a/arch/powerpc/kernel/secvar-ops.c b/arch/powerpc/kernel/secvar-ops.c
> new file mode 100644
> index 000000000000..4331a5b66ec0
> --- /dev/null
> +++ b/arch/powerpc/kernel/secvar-ops.c
> @@ -0,0 +1,19 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2019 IBM Corporation
> + * Author: Nayna Jain
> + *
> + * This file initializes secvar operations for PowerPC Secureboot
> + */
> +
> +#include <stddef.h>
> +#include <asm/secvar.h>
> +
> +const struct secvar_operations *secvar_ops;
> +

> +void set_secvar_ops(const struct secvar_operations *ops)
> +{
> +	if (!ops)
> +		secvar_ops = NULL;
> +	secvar_ops = ops;
> +}

Seems a little redundant.

> diff --git a/arch/powerpc/platforms/powernv/Kconfig b/arch/powerpc/platforms/powernv/Kconfig
> index 938803eab0ad..a1c7c8e2e683 100644
> --- a/arch/powerpc/platforms/powernv/Kconfig
> +++ b/arch/powerpc/platforms/powernv/Kconfig
> @@ -50,3 +50,9 @@ config PPC_VAS
>  config SCOM_DEBUGFS
>  	bool "Expose SCOM controllers via debugfs"
>  	depends on DEBUG_FS
> +
> +config OPAL_SECVAR
> +	bool "OPAL Secure Variables"
> +	depends on PPC_POWERNV
> +	help
> +	  This enables the kernel to access OPAL secure variables.
> diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile
> index a3ac9646119d..0ae688bde9b7 100644
> --- a/arch/powerpc/platforms/powernv/Makefile
> +++ b/arch/powerpc/platforms/powernv/Makefile
> @@ -20,3 +20,4 @@ obj-$(CONFIG_PPC_MEMTRACE)	+= memtrace.o
>  obj-$(CONFIG_PPC_VAS)	+= vas.o vas-window.o vas-debug.o
>  obj-$(CONFIG_OCXL_BASE)	+= ocxl.o
>  obj-$(CONFIG_SCOM_DEBUGFS) += opal-xscom.o
> +obj-$(CONFIG_OPAL_SECVAR) += opal-secvar.o
> diff --git a/arch/powerpc/platforms/powernv/opal-call.c b/arch/powerpc/platforms/powernv/opal-call.c
> index a2aa5e433ac8..5cd0f52d258f 100644
> --- a/arch/powerpc/platforms/powernv/opal-call.c
> +++ b/arch/powerpc/platforms/powernv/opal-call.c
> @@ -290,3 +290,6 @@ OPAL_CALL(opal_nx_coproc_init,			OPAL_NX_COPROC_INIT);
>  OPAL_CALL(opal_mpipl_update,			OPAL_MPIPL_UPDATE);
>  OPAL_CALL(opal_mpipl_register_tag,		OPAL_MPIPL_REGISTER_TAG);
>  OPAL_CALL(opal_mpipl_query_tag,			OPAL_MPIPL_QUERY_TAG);
> +OPAL_CALL(opal_secvar_get,			OPAL_SECVAR_GET);
> +OPAL_CALL(opal_secvar_get_next,			OPAL_SECVAR_GET_NEXT);
> +OPAL_CALL(opal_secvar_enqueue_update,		OPAL_SECVAR_ENQUEUE_UPDATE);
> diff --git a/arch/powerpc/platforms/powernv/opal-secvar.c b/arch/powerpc/platforms/powernv/opal-secvar.c
> new file mode 100644
> index 000000000000..ad5c6b8019dd
> --- /dev/null
> +++ b/arch/powerpc/platforms/powernv/opal-secvar.c
> @@ -0,0 +1,137 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * PowerNV code for secure variables
> + *
> + * Copyright (C) 2019 IBM Corporation
> + * Author: Claudio Carvalho
> + *         Nayna Jain
> + *
> + * APIs to access secure variables managed by OPAL.
> + */
> +
> +#define pr_fmt(fmt) "secvar: "fmt
> +
> +#include <linux/types.h>
> +#include <asm/opal.h>
> +#include <asm/secvar.h>
> +#include <asm/secure_boot.h>
> +
> +static int opal_status_to_err(int rc)
> +{
> +	int err;
> +
> +	switch (rc) {
> +	case OPAL_SUCCESS:
> +		err = 0;
> +		break;
> +	case OPAL_UNSUPPORTED:
> +		err = -ENXIO;
> +		break;
> +	case OPAL_PARAMETER:
> +		err = -EINVAL;
> +		break;
> +	case OPAL_RESOURCE:
> +		err = -ENOSPC;
> +		break;
> +	case OPAL_HARDWARE:
> +		err = -EIO;
> +		break;
> +	case OPAL_NO_MEM:
> +		err = -ENOMEM;
> +		break;
> +	case OPAL_EMPTY:
> +		err = -ENOENT;
> +		break;
> +	case OPAL_PARTIAL:
> +		err = -EFBIG;
> +		break;
> +	default:
> +		err = -EINVAL;
> +	}
> +
> +	return err;
> +}
> +
> +static bool is_opal_secvar_supported(void)
> +{
> +	static bool opal_secvar_supported;
> +	static bool initialized;
> +
> +	if (initialized)
> +		return opal_secvar_supported;
> +
> +	if (!is_powerpc_os_sb_supported()) {
> +		opal_secvar_supported = false;
> +		goto out;
> +	}
> +
> +	if (!opal_check_token(OPAL_SECVAR_GET)
> +			|| !opal_check_token(OPAL_SECVAR_GET_NEXT)
> +			|| !opal_check_token(OPAL_SECVAR_ENQUEUE_UPDATE)) {
> +		pr_err("OPAL doesn't support secure variables\n");
> +		opal_secvar_supported = false;
> +	} else {
> +		opal_secvar_supported = true;
> +	}
> +
> +out:
> +	initialized = true;
> +
> +	return opal_secvar_supported;
> +}
> +

> +static int opal_get_variable(const char *key, uint64_t ksize,
> +			     u8 *data, uint64_t *dsize)
> +{
> +	int rc;
> +
> +	if (dsize)
> +		*dsize = cpu_to_be64(*dsize);

Is passing a NULL size pointer ever a valid thing to do? I'd check with
Eric first, but IIRC OPAL will just reject that with OPAL_PARAMETER.
> +
> +	rc = opal_secvar_get(key, ksize, data, dsize);
> +
> +	if (dsize)
> +		*dsize = be64_to_cpu(*dsize);
> +
> +	return opal_status_to_err(rc);
> +}
> +
> +static int opal_get_next_variable(const char *key, uint64_t *keylen,
> +				  uint64_t keybufsize)
> +{
> +	int rc;
> +
> +	if (keylen)
> +		*keylen = cpu_to_be64(*keylen);same question
same here

> +
> +	rc = opal_secvar_get_next(key, keylen, keybufsize);
> +
> +	if (keylen)
> +		*keylen = be64_to_cpu(*keylen);
> +
> +	return opal_status_to_err(rc);
> +}

*snip*

> +void opal_secvar_init(void)
> +{
> +	if (!is_opal_secvar_supported())
> +		set_secvar_ops(NULL);

You might as well fold is_opal_secvar_supported() into this function
since its the only caller.

> +
> +	set_secvar_ops(&opal_secvar_ops);
> +}

Doesn't this unconditionally set the secvar ops to &opal_secvar_ops?

> diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
> index 38e90270280b..8e654d3735c1 100644
> --- a/arch/powerpc/platforms/powernv/opal.c
> +++ b/arch/powerpc/platforms/powernv/opal.c
> @@ -32,6 +32,8 @@
>  #include <asm/mce.h>
>  #include <asm/imc-pmu.h>
>  #include <asm/bug.h>
> +#include <asm/secvar.h>
> +#include <asm/secure_boot.h>
>  
>  #include "powernv.h"
>  
> @@ -1002,6 +1004,9 @@ static int __init opal_init(void)
>  	/* Initialise OPAL Power control interface */
>  	opal_power_control_init();
>  
> +	/* Initialize OPAL secure variables */
> +	opal_secvar_init();
> +
>  	return 0;
>  }
>  machine_subsys_initcall(powernv, opal_init);


  reply	other threads:[~2019-10-15  8:11 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-01 23:41 [PATCH v4 0/4] powerpc: expose secure variables to the kernel and userspace Nayna Jain
2019-10-01 23:41 ` [PATCH v4 1/4] powerpc/powernv: Add OPAL API interface to access secure variable Nayna Jain
2019-10-15  8:11   ` Oliver O'Halloran [this message]
2019-10-01 23:41 ` [PATCH v4 2/4] powerpc: expose secure variables to userspace via sysfs Nayna Jain
2019-10-15  8:34   ` Oliver O'Halloran
2019-10-01 23:41 ` [PATCH v4 3/4] x86/efi: move common keyring handler functions to new file Nayna Jain
2019-10-01 23:41 ` [PATCH v4 4/4] powerpc: load firmware trusted keys/hashes into kernel keyring Nayna Jain

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6ebe7ed1577115664ad7d82200c6a30ea2a93658.camel@gmail.com \
    --to=oohall@gmail.com \
    --cc=ard.biesheuvel@linaro.org \
    --cc=benh@kernel.crashing.org \
    --cc=cclaudio@linux.ibm.com \
    --cc=erichte@linux.ibm.com \
    --cc=erpalmer@us.ibm.com \
    --cc=gcwilson@linux.ibm.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jk@ozlabs.org \
    --cc=linux-efi@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@ozlabs.org \
    --cc=matthew.garret@nebula.com \
    --cc=mpe@ellerman.id.au \
    --cc=nayna@linux.ibm.com \
    --cc=paulus@samba.org \
    --cc=zohar@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).