Skip to content

Commit

Permalink
doc: add opal secure variable documentation
Browse files Browse the repository at this point in the history
This patch contains the work-in-progress documentation for the
secure variable design in OPAL. Future revisions of this patch
set will (hopefully) add new pieces of documentation here.

Signed-off-by: Eric Richter <erichte@linux.ibm.com>
[oliver: whitespace error fixes, removed old backend node docs]
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
---
V3:
 - removed metadata
 - removed get_size
 - updated _get semantics for size queries
 - added/expanded device tree properties

V4:
 - updated for new device tree changes

V5:
 - removed incorrect ibm,secureboot changes
 - rewrote bindings using a different format
 - moved secvar documentation under ibm,opal

V6:
 - moved os-secureboot-enforcing to ibm,secureboot
 - removed backend node from secvar node
 - updated documentation on secvar node compatible
  • Loading branch information
erichte-ibm authored and oohal committed Nov 7, 2019
1 parent 7af08f2 commit 04f0cdb
Show file tree
Hide file tree
Showing 3 changed files with 366 additions and 0 deletions.
169 changes: 169 additions & 0 deletions doc/device-tree/ibm,opal/secvar/binding.rst
@@ -0,0 +1,169 @@
secvar Binding
==============

This device tree binding describes the status of secure variable support,
including any size values, or values relating to the secure state of the
system.


/ibm,opal/secvar node bindings
------------------------------

Node: secvar

Description: Container of secvar related properties.

The node name must be "secvar".

It is implemented as a child of the node "/ibm,opal".

The node is optional, will be defined if the platform supports secure
variables. It will not be created if the system does not.

Properties:

- compatible

Usage:
required
Value type:
string

Definition:

This property defines the compatibility of the current running
backend. This defines the binary format of the data buffers passed
via the related secvar OPAL API functions. This also defines the
expected behavior of how updates should be processed, such as how
key updates should be signed, what the key hierarchy is, what
algorithms are in use, etc.

This value also determines how a user can signal a desire to require
all further images to require signature validations. See the
"On Enforcing Secure Mode" section below.

- status

Usage:
required
Value type:
string

Definition:

This property states the general status of secure variable support. This
will be set to "okay" if the secvar OPAL API should be working as expected,
and there were no unrecoverable faults in the basic secure variable
initialization logic.

This property may be set to "fail" if the platform does not properly
select the drivers to use. Failures may also occur if the storage devices
are inaccessible for some reason.

Failures are NOT caused by malformed data loaded or processed in either
storage or backend drivers, as these are faults correctable by a user.

- update-status

Usage:
required
Value type:
<u64>

Definition:

This property should contain the status code of the update processing
logic, as returned by the backend. This value is intended to be
consumed by userspace tools to confirm updates were processed as
intended.

The value contained in this property should adhere to the table below.
Any additional error states that may be specific to a backend should
be stored in the backend node.


- max-var-size

Usage:
required
Value type:
<u64>

Definition:

This is the maximum buffer size accepted for secure variables. The API
will reject updates larger than this value, and storage drivers must
reject loading variables larger than this value.

As this may depend on the persistant storage devices in use, this
value is determined by the storage driver, and may differ across
platforms.

- max-var-key-len

Usage:
required
Value type:
<u64>

Definition:

This is the maximum size permitted for the key of a variable. As the
value is a constant, it should be the same across platforms unless
changed in code.


Example
-------

.. code-block:: dts
/ibm,opal/secvar {
compatible = "ibm,edk2-compat-v1";
status = "okay";
max-var-size = <0x1000>;
max-var-key-len = <0x400>
};
Update Status Code Table
------------------------

The update status property should be set by the backend driver to a value
that best fits its error condition. The following table defines the
general intent of each error code, check backend specific documentation
for more detail.

+-----------------+-----------------------------------------------+
| update-status | Generic Reason |
+-----------------|-----------------------------------------------+
| OPAL_SUCCESS | Updates were found and processed successfully |
+-----------------|-----------------------------------------------+
| OPAL_EMPTY | No updates were found, none processed |
+-----------------|-----------------------------------------------+
| OPAL_PARAMETER | Malformed, or unexpected update data blob |
+-----------------|-----------------------------------------------+
| OPAL_PERMISSION | Update failed to apply, possible auth failure |
+-----------------|-----------------------------------------------+
| OPAL_HARDWARE | Misc. storage-related error |
+-----------------|-----------------------------------------------+
| OPAL_RESOURCE | Out of space (reported by storage |
+-----------------|-----------------------------------------------+
| OPAL_NO_MEM | Out of memory |
+-----------------+-----------------------------------------------+


On Enforcing Secure Mode
------------------------

The os-secureboot-enforcing property in /ibm,secureboot/ is created by the
backend if the owner has expressed a desire for boot loaders, kernels, etc
to require any images to be signed by an appropriate key stored in secure
variables. As this property is created by the backend, it is up to the
backend to define what the required state of the secure variables should
be to enter this mode.

For example, we may want to only enable secure boot if we have a top-
level "Platform Key", so this property is created by the backend if
by the end of update processing, a "PK" variable exists. By enrolling a
PK, the system will be in "secure mode" until the PK is deleted.
5 changes: 5 additions & 0 deletions doc/device-tree/ibm,secureboot.rst
Expand Up @@ -33,6 +33,11 @@ Required properties
hw-key-hash-size: hw-key-hash size
os-secureboot-enforcing:
this property is created by the secure variable backend
if it detects a desire by the owner to requre any
images (e.g. kernels) to be signed by an appropriate
key stored in secure variables.
Obsolete properties
-------------------
Expand Down
192 changes: 192 additions & 0 deletions doc/opal-api/opal-secvar.rst
@@ -0,0 +1,192 @@
OPAL Secure Variable API
========================

Overview
--------

In order to support host OS secure boot on POWER systems, the platform needs
some form of tamper-resistant persistant storage for authorized public keys.
Furthermore, these keys must be retrieveable by the host kernel, and new
keys must be able to be submitted.

OPAL exposes an abstracted "variable" API, in which these keys can be stored
and retrieved. At a high level, ``opal_secvar_get`` retrieves a specific
variable corresponding to a particular key. ``opal_secvar_get_next`` can be
used to iterate through the keys of the stored variables.
``opal_secvar_enqueue_update`` can be used to submit a new variable for
processing on next boot.

OPAL_SECVAR_GET
===============
::

#define OPAL_SECVAR_GET 176

``OPAL_SECVAR_GET`` call retrieves a data blob associated with the supplied
key.


Parameters
----------
::

char *key
uint64_t key_len
void *data
uint64_t *data_size

``key``
a buffer used to associate with the variable data. May
be any encoding, but must not be all zeroes

``key_len``
size of the key buffer in bytes

``data``
return buffer to store the data blob of the requested variable if
a match was found. May be set to NULL to only query the size into
``data_size``

``data_size``
reference to the size of the ``data`` buffer. OPAL sets this to
the size of the requested variable if found.


Return Values
-------------

``OPAL_SUCCESS``
the requested data blob was copied successfully. ``data`` was NULL,
and the ``data_size`` value was set successfully

``OPAL_PARAMETER``
``key`` is NULL.
``key_len`` is zero.
``data_size`` is NULL.

``OPAL_EMPTY``
no variable with the supplied ``key`` was found

``OPAL_PARTIAL``
the buffer size provided in ``data_size`` was insufficient.
``data_size`` is set to the minimum required size.

``OPAL_UNSUPPORTED``
secure variables are not supported by the platform

``OPAL_RESOURCE``
secure variables are supported, but did not initialize properly

OPAL_SECVAR_GET_NEXT
====================
::

#define OPAL_SECVAR_GET_NEXT 177

``OPAL_SECVAR_GET_NEXT`` returns the key of the next variable in the secure
variable bank in sequence.

Parameters
----------
::

char *key
uint64_t *key_len
uint64_t key_buf_size


``key``
name of the previous variable or empty. The key of the next
variable in sequence will be copied to ``key``. If passed as empty,
returns the first variable in the bank

``key_len``
length in bytes of the key in the ``key`` buffer. OPAL sets
this to the length in bytes of the next variable in sequence

``key_buf_size``
maximum size of the ``key`` buffer. The next key will not be
copied if this value is less than the length of the next key


Return Values
-------------

``OPAL_SUCCESS``
the key and length of the next variable in sequence was copied
successfully

``OPAL_PARAMETER``
``key`` or ``key_length`` is NULL.
``key_size`` is zero.
``key_length`` is impossibly large. No variable with the associated
``key`` was found

``OPAL_EMPTY``
end of list reached

``OPAL_PARTIAL``
the size specified in ``key_size`` is insufficient for the next
variable's key length. ``key_length`` is set to the next variable's
length, but ``key`` is untouched

``OPAL_UNSUPPORTED``
secure variables are not supported by the platform

``OPAL_RESOURCE``
secure variables are supported, but did not initialize properly

OPAL_SECVAR_ENQUEUE_UPDATE
==========================
::

#define OPAL_SECVAR_ENQUEUE_UPDATE 178

``OPAL_SECVAR_ENQUEUE`` call appends the supplied variable data to the
queue for processing on next boot.

Parameters
----------
::

char *key
uint64_t key_len
void *data
uint64_t data_size

``key``
a buffer used to associate with the variable data. May
be any encoding, but must not be all zeroes

``key_len``
size of the key buffer in bytes

``data``
buffer containing the blob of data to enqueue

``data_size``
size of the ``data`` buffer

Return Values
-------------

``OPAL_SUCCESS``
the variable was appended to the update queue bank successfully

``OPAL_PARAMETER``
``key`` or ``data`` was NULL.
``key`` was empty.
``key_len`` or ``data_size`` was zero.
``key_len``, ``data_size`` is larger than the maximum size

``OPAL_NO_MEM``
OPAL was unable to allocate memory for the variable update

``OPAL_HARDWARE``
OPAL was unable to write the update to persistant storage

``OPAL_UNSUPPORTED``
secure variables are not supported by the platform

``OPAL_RESOURCE``
secure variables are supported, but did not initialize properly

0 comments on commit 04f0cdb

Please sign in to comment.