From patchwork Tue Nov 5 04:20:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 1189308 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 476c1R0jqNz9sNT for ; Tue, 5 Nov 2019 15:21:31 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 476c1Q62L8zF3n7 for ; Tue, 5 Nov 2019 15:21:30 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=linux.ibm.com (client-ip=148.163.156.1; helo=mx0a-001b2d01.pphosted.com; envelope-from=erichte@linux.ibm.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 476c0C0RYvzF3fn for ; Tue, 5 Nov 2019 15:20:26 +1100 (AEDT) Received: from pps.filterd (m0098393.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id xA54H9ZO006160 for ; Mon, 4 Nov 2019 23:20:23 -0500 Received: from e06smtp05.uk.ibm.com (e06smtp05.uk.ibm.com [195.75.94.101]) by mx0a-001b2d01.pphosted.com with ESMTP id 2w2y7mvtry-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 04 Nov 2019 23:20:23 -0500 Received: from localhost by e06smtp05.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 5 Nov 2019 04:20:18 -0000 Received: from b06cxnps3074.portsmouth.uk.ibm.com (9.149.109.194) by e06smtp05.uk.ibm.com (192.168.101.135) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Tue, 5 Nov 2019 04:20:16 -0000 Received: from d06av26.portsmouth.uk.ibm.com (d06av26.portsmouth.uk.ibm.com [9.149.105.62]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id xA54KFbb57671838 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 5 Nov 2019 04:20:15 GMT Received: from d06av26.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E3ECFAE051; Tue, 5 Nov 2019 04:20:14 +0000 (GMT) Received: from d06av26.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3C409AE058; Tue, 5 Nov 2019 04:20:14 +0000 (GMT) Received: from ceres.ibmuc.com (unknown [9.80.237.45]) by d06av26.portsmouth.uk.ibm.com (Postfix) with ESMTP; Tue, 5 Nov 2019 04:20:14 +0000 (GMT) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Mon, 4 Nov 2019 22:20:07 -0600 X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191105042011.7357-1-erichte@linux.ibm.com> References: <20191105042011.7357-1-erichte@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 19110504-0020-0000-0000-000003829BD6 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19110504-0021-0000-0000-000021D8C2FF Message-Id: <20191105042011.7357-2-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-11-05_01:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911050032 Subject: [Skiboot] [PATCH v6 1/5] doc: add opal secure variable documentation X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nayna@linux.ibm.com Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" 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. 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 Signed-off-by: Eric Richter --- doc/device-tree/ibm,opal/secvar/binding.rst | 203 ++++++++++++++++++++ doc/device-tree/ibm,secureboot.rst | 5 + doc/opal-api/opal-secvar.rst | 192 ++++++++++++++++++ 3 files changed, 400 insertions(+) create mode 100644 doc/device-tree/ibm,opal/secvar/binding.rst create mode 100644 doc/opal-api/opal-secvar.rst diff --git a/doc/device-tree/ibm,opal/secvar/binding.rst b/doc/device-tree/ibm,opal/secvar/binding.rst new file mode 100644 index 00000000..df4eb921 --- /dev/null +++ b/doc/device-tree/ibm,opal/secvar/binding.rst @@ -0,0 +1,203 @@ +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: + + + 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: + + + 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: + + + 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. + + +/ibm,opal/secvar/backend node bindings +-------------------------------------- + +The secvar node must define a child node for the current running backend. + +This node should contain any backend-specific logic that may need to be +consumed by kernels, users, etc. + +Any additional non-required properties should be documented by their +respective backend. + +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. + + Furthermore, it defines any additional, non-required properties + within this node. + + + +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. diff --git a/doc/device-tree/ibm,secureboot.rst b/doc/device-tree/ibm,secureboot.rst index 42c4ed7d..3113b3f2 100644 --- a/doc/device-tree/ibm,secureboot.rst +++ b/doc/device-tree/ibm,secureboot.rst @@ -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 ------------------- diff --git a/doc/opal-api/opal-secvar.rst b/doc/opal-api/opal-secvar.rst new file mode 100644 index 00000000..f07c570a --- /dev/null +++ b/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