From patchwork Thu Apr 11 22:45:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 1084344 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 44gGNv5JLBz9s55 for ; Fri, 12 Apr 2019 08:46:55 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 44gGNv43pVzDqT3 for ; Fri, 12 Apr 2019 08:46:55 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=linux.ibm.com (client-ip=148.163.158.5; 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 (mx0b-001b2d01.pphosted.com [148.163.158.5]) (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 44gGN102QYzDqSr for ; Fri, 12 Apr 2019 08:46:08 +1000 (AEST) Received: from pps.filterd (m0098416.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x3BMhovb051240 for ; Thu, 11 Apr 2019 18:46:04 -0400 Received: from e06smtp07.uk.ibm.com (e06smtp07.uk.ibm.com [195.75.94.103]) by mx0b-001b2d01.pphosted.com with ESMTP id 2rtc2cdqjh-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 11 Apr 2019 18:46:04 -0400 Received: from localhost by e06smtp07.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 11 Apr 2019 23:46:00 +0100 Received: from b06cxnps3075.portsmouth.uk.ibm.com (9.149.109.195) by e06smtp07.uk.ibm.com (192.168.101.137) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Thu, 11 Apr 2019 23:45:57 +0100 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps3075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x3BMjuxG29950008 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 11 Apr 2019 22:45:56 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D682811C071; Thu, 11 Apr 2019 22:45:55 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1983511C058; Thu, 11 Apr 2019 22:45:55 +0000 (GMT) Received: from yorha.ibmuc.com (unknown [9.80.238.6]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 11 Apr 2019 22:45:54 +0000 (GMT) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Thu, 11 Apr 2019 17:45:44 -0500 X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190411224551.29401-1-erichte@linux.ibm.com> References: <20190411224551.29401-1-erichte@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 19041122-0028-0000-0000-0000035FE7F6 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19041122-0029-0000-0000-0000241F10AA Message-Id: <20190411224551.29401-2-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-04-11_14:, , 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-1810050000 definitions=main-1904110145 Subject: [Skiboot] [RFC v2 1/8] core/flash.c: add SECBOOT read and write support 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: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" From: Claudio Carvalho In secure boot enabled systems, the petitboot linux kernel verifies the OS kernel against x509 certificates that are wrapped in secure variables controlled by OPAL. These secure variables are stored in the PNOR SECBOOT partition, as well as the updates submitted for them using userspace tools. This patch adds read and write support to the PNOR SECBOOT partition so that OPAL can handle the secure variables. CC: Jeremy Kerr Signed-off-by: Claudio Carvalho --- core/flash.c | 130 +++++++++++++++++++++++++++++++++++++++++++++ include/platform.h | 4 ++ 2 files changed, 134 insertions(+) diff --git a/core/flash.c b/core/flash.c index 1ed42607..2862bc6b 100644 --- a/core/flash.c +++ b/core/flash.c @@ -51,6 +51,10 @@ static struct lock flash_lock; static struct flash *nvram_flash; static u32 nvram_offset, nvram_size; +/* secboot-on-flash support */ +static struct flash *secboot_flash; +static u32 secboot_offset, secboot_size; + bool flash_reserve(void) { bool rc = false; @@ -74,6 +78,91 @@ void flash_release(void) unlock(&flash_lock); } +static int flash_secboot_info(uint32_t *total_size) +{ + int rc; + + lock(&flash_lock); + if (!secboot_flash) { + rc = OPAL_HARDWARE; + } else if (secboot_flash->busy) { + rc = OPAL_BUSY; + } else { + *total_size = secboot_size; + rc = OPAL_SUCCESS; + } + unlock(&flash_lock); + + return rc; +} + +static int flash_secboot_read(void *dst, uint32_t src, uint32_t len) +{ + int rc; + + if (!try_lock(&flash_lock)) + return OPAL_BUSY; + + if (!secboot_flash) { + rc = OPAL_HARDWARE; + goto out; + } + + if (secboot_flash->busy) { + rc = OPAL_BUSY; + goto out; + } + + if ((src + len) > secboot_size) { + prerror("FLASH_SECBOOT: read out of bound (0x%x,0x%x)\n", + src, len); + rc = OPAL_PARAMETER; + goto out; + } + + secboot_flash->busy = true; + unlock(&flash_lock); + + rc = blocklevel_read(secboot_flash->bl, secboot_offset + src, dst, len); + + lock(&flash_lock); + secboot_flash->busy = false; +out: + unlock(&flash_lock); + return rc; +} + +static int flash_secboot_write(uint32_t dst, void *src, uint32_t len) +{ + int rc; + + if (!try_lock(&flash_lock)) + return OPAL_BUSY; + + if (secboot_flash->busy) { + rc = OPAL_BUSY; + goto out; + } + + if ((dst + len) > secboot_size) { + prerror("FLASH_SECBOOT: write out of bound (0x%x,0x%x)\n", + dst, len); + rc = OPAL_PARAMETER; + goto out; + } + + secboot_flash->busy = true; + unlock(&flash_lock); + + rc = blocklevel_write(secboot_flash->bl, secboot_offset + dst, src, len); + + lock(&flash_lock); + secboot_flash->busy = false; +out: + unlock(&flash_lock); + return rc; +} + static int flash_nvram_info(uint32_t *total_size) { int rc; @@ -163,6 +252,46 @@ out: return rc; } + +static int flash_secboot_probe(struct flash *flash, struct ffs_handle *ffs) +{ + uint32_t start, size, part; + bool ecc; + int rc; + + prlog(PR_INFO, "FLASH: probing for SECBOOT\n"); + + rc = ffs_lookup_part(ffs, "SECBOOT", &part); + if (rc) { + prlog(PR_WARNING, "FLASH: no SECBOOT partition found\n"); + return OPAL_HARDWARE; + } + + rc = ffs_part_info(ffs, part, NULL, + &start, &size, NULL, &ecc); + if (rc) { + /** + * @fwts-label SECBOOTNoPartition + * @fwts-advice OPAL could not find an SECBOOT partition + * on the system flash. Check that the system flash + * has a valid partition table, and that the firmware + * build process has added a SECBOOT partition. + */ + prlog(PR_ERR, "FLASH: Can't parse ffs info for SECBOOT\n"); + return OPAL_HARDWARE; + } + + secboot_flash = flash; + secboot_offset = start; + secboot_size = ecc ? ecc_buffer_size_minus_ecc(size) : size; + + platform.secboot_info = flash_secboot_info; + platform.secboot_read = flash_secboot_read; + platform.secboot_write = flash_secboot_write; + + return 0; +} + static int flash_nvram_probe(struct flash *flash, struct ffs_handle *ffs) { uint32_t start, size, part; @@ -256,6 +385,7 @@ static void setup_system_flash(struct flash *flash, struct dt_node *node, prlog(PR_INFO, "FLASH: registered system flash device %s\n", name); flash_nvram_probe(flash, ffs); + flash_secboot_probe(flash, ffs); } static int num_flashes(void) diff --git a/include/platform.h b/include/platform.h index de4638f3..0cc9c234 100644 --- a/include/platform.h +++ b/include/platform.h @@ -181,6 +181,10 @@ struct platform { uint32_t len); int (*nvram_write)(uint32_t dst, void *src, uint32_t len); + int (*secboot_info)(uint32_t *total_size); + int (*secboot_read)(void *dst, uint32_t src, uint32_t len); + int (*secboot_write)(uint32_t dst, void *src, uint32_t len); + /* * OCC timeout. This return how long we should wait for the OCC * before timing out. This lets us use a high value on larger FSP From patchwork Thu Apr 11 22:45:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 1084342 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 44gGNN60cnz9s5c for ; Fri, 12 Apr 2019 08:46:28 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 44gGNN4sCWzDqTG for ; Fri, 12 Apr 2019 08:46:28 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) 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 44gGMx5qmTzDqSt for ; Fri, 12 Apr 2019 08:46:05 +1000 (AEST) Received: from pps.filterd (m0098399.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x3BMhsBU096097 for ; Thu, 11 Apr 2019 18:46:03 -0400 Received: from e06smtp01.uk.ibm.com (e06smtp01.uk.ibm.com [195.75.94.97]) by mx0a-001b2d01.pphosted.com with ESMTP id 2rtcc75bm7-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 11 Apr 2019 18:46:02 -0400 Received: from localhost by e06smtp01.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 11 Apr 2019 23:46:00 +0100 Received: from b06cxnps4074.portsmouth.uk.ibm.com (9.149.109.196) by e06smtp01.uk.ibm.com (192.168.101.131) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Thu, 11 Apr 2019 23:45:59 +0100 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps4074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x3BMjvXY52035654 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 11 Apr 2019 22:45:57 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A7F6511C05C; Thu, 11 Apr 2019 22:45:57 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 29E4411C06C; Thu, 11 Apr 2019 22:45:57 +0000 (GMT) Received: from yorha.ibmuc.com (unknown [9.80.238.6]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 11 Apr 2019 22:45:57 +0000 (GMT) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Thu, 11 Apr 2019 17:45:45 -0500 X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190411224551.29401-1-erichte@linux.ibm.com> References: <20190411224551.29401-1-erichte@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 19041122-4275-0000-0000-00000326EB0D X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19041122-4276-0000-0000-000038360D44 Message-Id: <20190411224551.29401-3-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-04-11_14:, , 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-1810050000 definitions=main-1904110145 Subject: [Skiboot] [RFC v2 2/8] doc: add opal secvar 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: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This patch contains all the relevant documentation for the secure variable support in OPAL. This may be split and squashed with their relevant implementations in the future, but kept separate for now. Notably missing at the moment is the documentation for the SECBOOT PNOR partition usage, which will be included in a future revision. v2: - removed k_ prefix on all parameters - changed all uint64_t types to their actual intended type - added a new overview preamble, work in progress Signed-off-by: Eric Richter --- doc/opal-api/opal-secvar.rst | 188 +++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 doc/opal-api/opal-secvar.rst diff --git a/doc/opal-api/opal-secvar.rst b/doc/opal-api/opal-secvar.rst new file mode 100644 index 00000000..382b9eb4 --- /dev/null +++ b/doc/opal-api/opal-secvar.rst @@ -0,0 +1,188 @@ +OPAL Secure Variables +===================== + +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 name+vendor guid pair (see "types" below). +``opal_secvar_get_next`` can be used to iterate through the stored +variables. ``opal_secvar_enqueue_update`` can be used to submit a new +variable for processing on next boot. + +Types +----- + +This document uses the following non-standard types: +:: + + char16_t - 16-bit char, in little endian ucs2 + guid_t - 16-byte UUID blob + + +OPAL_SECVAR_GET +=============== +:: + + #define OPAL_SECVAR_GET 170 + +``OPAL_SECVAR_GET`` call retrieves a data blob associated with the supplied +name and vendor guid. + +Parameters +---------- +:: + + char16_t *name + guid_t *vendor + uint32_t *attributes + uint64_t *data_size + void *data + +``name`` + the name of the requested variable as a 16-bit char + +``vendor`` + the vendor guid of the requested variable + +``attributes`` + optional bitfield reference to be set by OPAL for attributes +related to the variable data + +``data_size`` + reference to the size of the ``data`` buffer. OPAL sets this if +the buffer size is insufficient for the requested variable + +``data`` + return buffer to store the data blob of the requested variable if +a match was found. May be set to NULL to request only the size + +Return Values +------------- + +``OPAL_SUCCESS`` + data from the requested variable was copied successfully, or +``data`` was set to NULL and the ``data_size`` was set to the +requested variable's size + +``OPAL_PARAMETER`` + ``name``, ``vendor`` or ``data_size`` are invalid buffers, +contain invalid values + +``OPAL_EMPTY`` + no variable with the supplied ``name`` and ``vendor`` was found + +``OPAL_PARTIAL`` + the buffer size provided in ``data_size`` is too small for the +requested variable + +``OPAL_UNSUPPORTED`` + secure variable support is disabled + +OPAL_SECVAR_GET_NEXT +==================== +:: + + #define OPAL_SECVAR_GET_NEXT 171 + +``OPAL_SECVAR_GET_NEXT`` returns the name and vendor guid of the next +variable in the secure variable bank in sequence. + +Parameters +---------- +:: + + size_t *name_size + char16_t *name + guid_t *vendor + +``name_size`` + size of the ``name`` buffer. OPAL sets this to the size of the +next variable in sequence + +``name`` + name of the previous variable or empty. The name of the next +variable in sequence will be copied to ``name`` + +``vendor`` + vendor guid of the previous variable or empty. The vendor of the +next vendor in sequence will be copied to ``vendor`` + +Return Values +------------- + +``OPAL_SUCCESS`` + the name and vendor of the next variable in sequence was copied +successfully + +``OPAL_PARAMETER`` + ``name`` or ``vendor`` are invalid buffers, or were not found. +``name_size`` is an invalid value. A variable matching the +supplied non-empty ``name`` and ``vendor`` was not found + +``OPAL_EMPTY`` + end of list reached + +``OPAL_PARTIAL`` + the size specified in ``name_size`` is insufficient for the next +variable's name size + +``OPAL_HARDWARE`` + secure variable support is disabled + +OPAL_SECVAR_ENQUEUE_UPDATE +========================== +:: + + #define OPAL_SECVAR_ENQUEUE_UPDATE 172 + +``OPAL_SECVAR_ENQUEUE`` call appends the supplied variable data to the +queue for processing on next boot. + +Parameters +---------- +:: + + char16_t *name + guid_t *vendor + uint32_t attributes + size_t data_size + void *data + +``name`` + the name of the submitted variable as a 16-bit char + +``vendor`` + the vendor guid of the submitted variable + +``attributes`` + bitfield of attributes + +``data_size`` + size of the buffer to copy from ``data`` + +``data`` + blob of data to be stored + +Return Values +------------- + +``OPAL_SUCCESS`` + the variable was appended to the update queue bank successfully + +``OPAL_PARAMETER`` + ``name``, ``vendor`` or ``data`` are invalid buffers. +``name`` is empty. ``data_size`` is an invalid value. ``data_size`` +was set to zero (potentially an unsupported deletion attempt) + +``OPAL_NO_MEM`` + OPAL was unable to allocate memory for the variable + +``OPAL_UNSUPPORTED`` + secure variable support is disabled From patchwork Thu Apr 11 22:45:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 1084343 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44gGNd6sYFz9s55 for ; Fri, 12 Apr 2019 08:46:41 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 44gGNd4gJMzDqT1 for ; Fri, 12 Apr 2019 08:46:41 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) 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 44gGMz6Pr7zDqSr for ; Fri, 12 Apr 2019 08:46:07 +1000 (AEST) Received: from pps.filterd (m0098399.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x3BMhtPg096237 for ; Thu, 11 Apr 2019 18:46:06 -0400 Received: from e06smtp07.uk.ibm.com (e06smtp07.uk.ibm.com [195.75.94.103]) by mx0a-001b2d01.pphosted.com with ESMTP id 2rtcc75bnu-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 11 Apr 2019 18:46:06 -0400 Received: from localhost by e06smtp07.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 11 Apr 2019 23:46:04 +0100 Received: from b06cxnps4076.portsmouth.uk.ibm.com (9.149.109.198) by e06smtp07.uk.ibm.com (192.168.101.137) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Thu, 11 Apr 2019 23:46:01 +0100 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x3BMjxIB31260884 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 11 Apr 2019 22:45:59 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 78B9711C073; Thu, 11 Apr 2019 22:45:59 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id EF61E11C058; Thu, 11 Apr 2019 22:45:58 +0000 (GMT) Received: from yorha.ibmuc.com (unknown [9.80.238.6]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 11 Apr 2019 22:45:58 +0000 (GMT) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Thu, 11 Apr 2019 17:45:46 -0500 X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190411224551.29401-1-erichte@linux.ibm.com> References: <20190411224551.29401-1-erichte@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 19041122-0028-0000-0000-0000035FE7F7 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19041122-0029-0000-0000-0000241F10AB Message-Id: <20190411224551.29401-4-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-04-11_14:, , 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=951 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904110145 Subject: [Skiboot] [RFC v2 3/8] platform.h: add secure variable storage hooks 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: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" Different platforms may support a range of features that can be used for persistent secure variable storage. This patch adds the following hooks to the platform struct, to be implemented by platforms that support secure variables: - secvar_platform_init - secvar_load_bank - secvar_write_bank secvar_platform_init performs any loading or initialization that the platform may need to prepare the internal banks. This may include initialization or formatting of a pnor section, TPM, etc. secvar_load_bank loads a bank from the platform's storage into the in-memory cache. secvar_write_bank takes an in-memory cache and writes it to the platform's storage. A subsequent patch will provide an implementation that should be usable for most p9 systems that use the SECBOOT pnor partition. Signed-off-by: Eric Richter --- include/platform.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/platform.h b/include/platform.h index 0cc9c234..c4aa92a0 100644 --- a/include/platform.h +++ b/include/platform.h @@ -185,6 +185,11 @@ struct platform { int (*secboot_read)(void *dst, uint32_t src, uint32_t len); int (*secboot_write)(uint32_t dst, void *src, uint32_t len); + // TODO: Document this + int (*secvar_platform_init)(void); + int (*secvar_load_bank)(struct list_head *bank, int section); + int (*secvar_write_bank)(struct list_head *bank, int section); + /* * OCC timeout. This return how long we should wait for the OCC * before timing out. This lets us use a high value on larger FSP From patchwork Thu Apr 11 22:45:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 1084345 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 44gGP771QVz9s55 for ; Fri, 12 Apr 2019 08:47:07 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 44gGP74K6qzDqT7 for ; Fri, 12 Apr 2019 08:47:07 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=linux.ibm.com (client-ip=148.163.158.5; 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 (mx0b-001b2d01.pphosted.com [148.163.158.5]) (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 44gGN142WJzDqSt for ; Fri, 12 Apr 2019 08:46:09 +1000 (AEST) Received: from pps.filterd (m0098420.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x3BMiKHF178768 for ; Thu, 11 Apr 2019 18:46:06 -0400 Received: from e06smtp01.uk.ibm.com (e06smtp01.uk.ibm.com [195.75.94.97]) by mx0b-001b2d01.pphosted.com with ESMTP id 2rtbqmxtf4-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 11 Apr 2019 18:46:06 -0400 Received: from localhost by e06smtp01.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 11 Apr 2019 23:46:04 +0100 Received: from b06cxnps3075.portsmouth.uk.ibm.com (9.149.109.195) by e06smtp01.uk.ibm.com (192.168.101.131) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Thu, 11 Apr 2019 23:46:02 +0100 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps3075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x3BMk13247513798 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 11 Apr 2019 22:46:01 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 509A711C070; Thu, 11 Apr 2019 22:46:01 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C0FFC11C073; Thu, 11 Apr 2019 22:46:00 +0000 (GMT) Received: from yorha.ibmuc.com (unknown [9.80.238.6]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 11 Apr 2019 22:46:00 +0000 (GMT) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Thu, 11 Apr 2019 17:45:47 -0500 X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190411224551.29401-1-erichte@linux.ibm.com> References: <20190411224551.29401-1-erichte@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 19041122-4275-0000-0000-00000326EB0F X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19041122-4276-0000-0000-000038360D46 Message-Id: <20190411224551.29401-5-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-04-11_14:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=4 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-1810050000 definitions=main-1904110145 Subject: [Skiboot] [RFC v2 4/8] libstb: add secure variable internal abstraction 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: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This patch implements a platform-independent abstraction for storing and retrieving secure variables, as required for host OS secure boot. This serves as the main entry point for initializing the in-memory cache of the secure variables, which also kicks off any platform-specific logic that may be needed. This patch also provides core functions for the subsequent patches in this series to utilize. This abstraction utilizes two linked lists ("banks") for storing the variables in memory for other components (such as the runtime service API) to access. v2: - secvar_init() returns opal return codes - changed guid_t to be a single-element struct instead of array - secvar_init() now calls platform hooks, rather than expecting function pointers to be set - secure variable support is determined by presence of platform hooks Signed-off-by: Eric Richter --- libstb/Makefile.inc | 2 +- libstb/secvar.c | 138 ++++++++++++++++++++++++++++++++++++++++++++ libstb/secvar.h | 64 ++++++++++++++++++++ 3 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 libstb/secvar.c create mode 100644 libstb/secvar.h diff --git a/libstb/Makefile.inc b/libstb/Makefile.inc index 6d54c5cd..2bc9e91b 100644 --- a/libstb/Makefile.inc +++ b/libstb/Makefile.inc @@ -4,7 +4,7 @@ LIBSTB_DIR = libstb SUBDIRS += $(LIBSTB_DIR) -LIBSTB_SRCS = container.c tpm_chip.c cvc.c secureboot.c trustedboot.c +LIBSTB_SRCS = container.c tpm_chip.c cvc.c secureboot.c trustedboot.c secvar.c LIBSTB_OBJS = $(LIBSTB_SRCS:%.c=%.o) LIBSTB = $(LIBSTB_DIR)/built-in.a diff --git a/libstb/secvar.c b/libstb/secvar.c new file mode 100644 index 00000000..6ed6a7e8 --- /dev/null +++ b/libstb/secvar.c @@ -0,0 +1,138 @@ +/* Copyright 2019 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef pr_fmt +#define pr_fmt(fmt) "SECVAR: " fmt +#endif + +#include +#include +#include +#include +#include "secvar.h" + +struct list_head variable_bank; +struct list_head update_bank; +int secvar_enabled = 0; + +// Calculate length of a char16_t, with a max possible bytes +// if end of string is not found before max bytes, returns -1 +// otherwise, returns length +int str16nlen(char16_t *str, size_t maxbytes) +{ + int ret = 0; + char16_t *c = str; + + while ((c - str) < maxbytes) { + if (*c == 0) + return ret; + ret++; + c++; + } + + return -1; +} + + +void clear_bank_list(struct list_head *bank) +{ + struct secvar *node, *next; + + if (!bank) + return; + + list_for_each_safe(bank, node, next, link) { + if (node->data) + free(node->data); + list_del(&node->link); + free(node); + } +} + +struct secvar *find_secvar_by_name_vendor(char16_t *name, guid_t *vendor, struct list_head *bank) +{ + struct secvar *var = NULL; + int len; + + len = str16nlen(name, SECVAR_MAX_NAME_SIZE); + if (len <= 0) { + return NULL; + } + + list_for_each(bank, var, link) { + if (!memcmp(name, var->name, len*2) && + !memcmp(vendor, &var->vendor, sizeof(guid_t))) { + return var; + } + } + + return NULL; +} + + +// Returns the packed physical size of a variable +size_t sizeof_secvar(struct secvar *var) +{ + return sizeof(var->name) + + sizeof(var->vendor) + + sizeof(var->attributes) + + sizeof(var->data_size) + + var->data_size; + +} + + +int secvar_init(void) +{ + int ret = OPAL_UNSUPPORTED; + + if ((!platform.secvar_platform_init) + || (!platform.secvar_load_bank) + || (!platform.secvar_write_bank)) { + prlog(PR_DEBUG, "Secure variable support not enabled for platform\n"); + return ret; + } + + prlog(PR_DEBUG, "Initializing secure variables\n"); + + ret = platform.secvar_platform_init(); + if (ret) + return ret; + + list_head_init(&variable_bank); + list_head_init(&update_bank); + + ret = platform.secvar_load_bank(&variable_bank, SECVAR_VARIABLE_BANK); + if (ret) + return ret; + prlog(PR_DEBUG, "Loaded variable bank\n"); + + ret = platform.secvar_load_bank(&update_bank, SECVAR_UPDATE_BANK); + if (ret) + return ret; + prlog(PR_DEBUG, "Loaded updates, "); + if (list_empty(&update_bank)) + prlog(PR_DEBUG, "none to apply.\n"); + else + prlog(PR_DEBUG, "found updates to apply\n"); + + // TODO: Process update queue here + // TODO: Derive SecureMode, etc variables here + + secvar_enabled = 1; + + return OPAL_SUCCESS; +} diff --git a/libstb/secvar.h b/libstb/secvar.h new file mode 100644 index 00000000..f686ce20 --- /dev/null +++ b/libstb/secvar.h @@ -0,0 +1,64 @@ +/* Copyright 2019 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _SECVAR_H_ +#define _SECVAR_H_ + +#include +#include + +typedef uint16_t char16_t; + +#define SECVAR_MAX_NAME_SIZE 1024 +#define SECVAR_MAX_NAME_LEN (SECVAR_MAX_NAME_SIZE/sizeof(char16_t)) +#define SECVAR_MAX_DATA_SIZE 2048 +#define SECVAR_VENDOR_SIZE 16 + + +enum { + SECVAR_VARIABLE_BANK, + SECVAR_UPDATE_BANK, +}; + + +//typedef unsigned char guid_t[SECVAR_VENDOR_SIZE]; +typedef struct { + uint8_t b[16]; +} guid_t; + +struct secvar { + struct list_node link; + char16_t name[SECVAR_MAX_NAME_LEN]; + guid_t vendor; + uint32_t attributes; + uint32_t data_size; + char *data; +}; + +extern struct list_head variable_bank; +extern struct list_head update_bank; +extern int secvar_enabled; + +// Helper functions +int str16nlen(char16_t *str, size_t max); +void clear_bank_list(struct list_head *bank); +struct secvar *find_secvar_by_name_vendor(char16_t *name, guid_t *vendor, struct list_head *bank); +size_t sizeof_secvar(struct secvar *var); + + +int secvar_init(void); + +#endif From patchwork Thu Apr 11 22:45:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 1084347 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (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 44gGPP1H51z9s5c for ; Fri, 12 Apr 2019 08:47:21 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 44gGPP06WkzDqTX for ; Fri, 12 Apr 2019 08:47:21 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=linux.ibm.com (client-ip=148.163.158.5; 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 (mx0b-001b2d01.pphosted.com [148.163.158.5]) (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 44gGN33dbMzDqSq for ; Fri, 12 Apr 2019 08:46:11 +1000 (AEST) Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x3BMitW4136074 for ; Thu, 11 Apr 2019 18:46:09 -0400 Received: from e06smtp04.uk.ibm.com (e06smtp04.uk.ibm.com [195.75.94.100]) by mx0b-001b2d01.pphosted.com with ESMTP id 2rtdcutvpw-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 11 Apr 2019 18:46:08 -0400 Received: from localhost by e06smtp04.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 11 Apr 2019 23:46:07 +0100 Received: from b06cxnps4075.portsmouth.uk.ibm.com (9.149.109.197) by e06smtp04.uk.ibm.com (192.168.101.134) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Thu, 11 Apr 2019 23:46:04 +0100 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x3BMk36c51118302 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 11 Apr 2019 22:46:03 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2290C11C06C; Thu, 11 Apr 2019 22:46:03 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 98E8D11C071; Thu, 11 Apr 2019 22:46:02 +0000 (GMT) Received: from yorha.ibmuc.com (unknown [9.80.238.6]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 11 Apr 2019 22:46:02 +0000 (GMT) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Thu, 11 Apr 2019 17:45:48 -0500 X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190411224551.29401-1-erichte@linux.ibm.com> References: <20190411224551.29401-1-erichte@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 19041122-0016-0000-0000-0000026DE8A5 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19041122-0017-0000-0000-000032CA214E Message-Id: <20190411224551.29401-6-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-04-11_14:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=4 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-1810050000 definitions=main-1904110145 Subject: [Skiboot] [RFC v2 5/8] libstb: add opal runtime services for secure boot key management 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: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This patch provides the OPAL runtime service frontend for the host OS to retrieve secure variables, and append new ones for processing on the next reboot. Included are the four minimum required services for basic manipulation: - opal_secvar_read() - opal_secvar_read_next() - opal_secvar_enqueue() - opal_secvar_info() opal_secvar_read() takes in an name string and a vendor buffer (likely a GUID), and returns the corresponding blob of data if there is a matching name + vendor pair in the variable bank. This runtime service only operates on the variable bank. opal_secvar_read_next() provides a method to iterate through the variables in the variable bank. If provided a name and vendor that match a variable in the variable bank, the function will return the name and vendor of the next variable in the bank in sequence. When provided an empty string, it will begin from the top of the list. This runtime service only operates on the variable bank. opal_secvar_enqueue() provides a method for the host OS to submit a new secure variable for processing on next boot, by appending it to the update bank, or "update queue". As this does not affect the variable bank, appending a variable via this runtime service will not affect the output of the previous two. The update queue will only ever be processed during the initialization of skiboot, and is part of a forthcoming patch series. v2: - removed opal_secvar_info(), not sure if neeeded yet - runtime services return OPAL_UNSUPPORTED if secure variables are not enabled - renamed opal_secvar_enqueue to opal_secvar_enqueue_update - moved list_next to ccan/list.h - updated to use new platform hooks Signed-off-by: Eric Richter --- ccan/list/list.h | 38 +++++++++ include/opal-api.h | 5 +- libstb/Makefile.inc | 2 +- libstb/secvar_api.c | 189 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 232 insertions(+), 2 deletions(-) create mode 100644 libstb/secvar_api.c diff --git a/ccan/list/list.h b/ccan/list/list.h index 7cd3a83e..47ea8b28 100644 --- a/ccan/list/list.h +++ b/ccan/list/list.h @@ -523,4 +523,42 @@ static inline struct list_node *list_node_from_off_(void *ptr, size_t off) (container_off_var(var, member) + \ check_type(var->member, struct list_node)) + +#if HAVE_TYPEOF +#define list_typeof(var) typeof(var) +#else +#define list_typeof(var) void * +#endif + + +/* Returns member, or NULL if at end of list. */ +static inline void *list_entry_or_null(const struct list_head *h, + const struct list_node *n, + size_t off) +{ + if (n == &h->n) + return NULL; + return (char *)n - off; +} + +/** + * list_next - get the next entry in a list + * @h: the list_head + * @i: a pointer to an entry in the list. + * @member: the list_node member of the structure + * + * If @i was the last entry in the list, returns NULL. + * + * Example: + * struct child *second; + * second = list_next(&parent->children, first, list); + * if (!second) + * printf("No second child!\n"); + */ +#define list_next(h, i, member) \ + ((list_typeof(i))list_entry_or_null(list_debug(h), \ + (i)->member.next, \ + list_off_var_((i), member))) + + #endif /* CCAN_LIST_H */ diff --git a/include/opal-api.h b/include/opal-api.h index e461c9d2..83bcb0cc 100644 --- a/include/opal-api.h +++ b/include/opal-api.h @@ -229,7 +229,10 @@ #define OPAL_XIVE_GET_VP_STATE 170 /* Get NVT state */ #define OPAL_NPU_RESERVED1 171 /* LPC Allocate */ #define OPAL_NPU_RESERVED2 172 /* LPC Release */ -#define OPAL_LAST 172 +#define OPAL_SECVAR_GET 173 +#define OPAL_SECVAR_GET_NEXT 174 +#define OPAL_SECVAR_ENQUEUE_UPDATE 175 +#define OPAL_LAST 175 #define QUIESCE_HOLD 1 /* Spin all calls at entry */ #define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */ diff --git a/libstb/Makefile.inc b/libstb/Makefile.inc index 2bc9e91b..f3a7e716 100644 --- a/libstb/Makefile.inc +++ b/libstb/Makefile.inc @@ -4,7 +4,7 @@ LIBSTB_DIR = libstb SUBDIRS += $(LIBSTB_DIR) -LIBSTB_SRCS = container.c tpm_chip.c cvc.c secureboot.c trustedboot.c secvar.c +LIBSTB_SRCS = container.c tpm_chip.c cvc.c secureboot.c trustedboot.c secvar.c secvar_api.c LIBSTB_OBJS = $(LIBSTB_SRCS:%.c=%.o) LIBSTB = $(LIBSTB_DIR)/built-in.a diff --git a/libstb/secvar_api.c b/libstb/secvar_api.c new file mode 100644 index 00000000..651f96c8 --- /dev/null +++ b/libstb/secvar_api.c @@ -0,0 +1,189 @@ +/* Copyright 2019 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef pr_fmt +#define pr_fmt(fmt) "SECVAR_API: " fmt +#endif + +#include +#include "secvar.h" + + +static int64_t opal_secvar_get(uint64_t k_name, uint64_t k_vendor, uint64_t k_attributes, uint64_t k_data_size, uint64_t k_data) +{ + struct secvar *var; + + char16_t *name = (char16_t *) k_name; + guid_t *vendor = (guid_t *) k_vendor; + uint32_t *attributes = (uint32_t *) k_attributes; + size_t *data_size = (size_t *) k_data_size; + void *data = (void *) k_data; + + if (!secvar_enabled) + return OPAL_UNSUPPORTED; + if (!name) + return OPAL_PARAMETER; + if (!vendor) + return OPAL_PARAMETER; + if (!data_size) + return OPAL_PARAMETER; + if ((*data_size == 0) && (data)) // Data should be NULL when size is zero + return OPAL_PARAMETER; + if ((*data_size) && (!data)) + return OPAL_PARAMETER; // Data can't be NULL with nonzero size + if (str16nlen(name, SECVAR_MAX_NAME_SIZE) <= 0) + return OPAL_PARAMETER; // Empty or erroneous name is useless + + var = find_secvar_by_name_vendor(name, vendor, &variable_bank); + + if (!var) + return OPAL_EMPTY; + + if (attributes) + *attributes = var->attributes; + + if (!data) { + *data_size = var->data_size; + return OPAL_SUCCESS; // Size check + } + + if (var->data_size > *data_size) { + *data_size = var->data_size; + return OPAL_PARTIAL; + } + + memcpy(data, var->data, var->data_size); + *data_size = var->data_size; + + + + return OPAL_SUCCESS; +} +opal_call(OPAL_SECVAR_GET, opal_secvar_get, 5); + + +static int64_t opal_secvar_get_next(uint64_t k_name_size, uint64_t k_name, uint64_t k_vendor) +{ + struct secvar *var; + int namelen; + + size_t *name_size = (size_t *) k_name_size; + char16_t *name = (char16_t *) k_name; + guid_t *vendor = (guid_t *) k_vendor; + + if (!secvar_enabled) + return OPAL_UNSUPPORTED; + if (!name_size || (*name_size == 0)) + return OPAL_PARAMETER; + if (!name) + return OPAL_PARAMETER; + if (!vendor) + return OPAL_PARAMETER; + + namelen = str16nlen(name, SECVAR_MAX_NAME_SIZE); + if (namelen < 0) + return OPAL_PARAMETER; // Erroneous name buffer + + if (namelen != 0) { + // Non-empty string + var = find_secvar_by_name_vendor(name, vendor, &variable_bank); + if (!var) + return OPAL_PARAMETER; + + var = list_next(&variable_bank, var, link); + } + else { + // Empty string was found, returning first entry + var = list_top(&variable_bank, struct secvar, link); + } + + if (!var) + return OPAL_EMPTY; + + // Return name buffer is too small + namelen = str16nlen(var->name, SECVAR_MAX_NAME_SIZE); + if (namelen <= 0) + return OPAL_HARDWARE; // This should not be reached + + if ((namelen*2) > *name_size) { + *name_size = namelen*2; + return OPAL_PARTIAL; + } + + + memcpy(name, var->name, namelen*2); + memcpy(vendor, &var->vendor, SECVAR_VENDOR_SIZE); + + return OPAL_SUCCESS; +} +opal_call(OPAL_SECVAR_GET_NEXT, opal_secvar_get_next, 3); + +static int64_t opal_secvar_enqueue_update(uint64_t k_name, uint64_t k_vendor, uint64_t k_attributes, uint64_t k_data_size, uint64_t k_data) +{ + struct secvar *var; + int namelen; + + char16_t *name = (char16_t *) k_name; + guid_t *vendor = (guid_t *) k_vendor; + uint32_t attributes = (uint32_t) k_attributes; + size_t data_size = (size_t) k_data_size; + void *data = (void *) k_data; + + if (!secvar_enabled) + return OPAL_UNSUPPORTED; + if (!name) + return OPAL_PARAMETER; + if (!vendor) + return OPAL_PARAMETER; + if (!data) + return OPAL_PARAMETER; + + if (data_size == 0) + return OPAL_PARAMETER; // we don't support variable deletion this way + if (data_size > SECVAR_MAX_DATA_SIZE) + return OPAL_PARAMETER; + + namelen = str16nlen(name, SECVAR_MAX_NAME_SIZE); + if (namelen <= 0) + return OPAL_PARAMETER; // empty or erroneous name is useless + + var = zalloc(sizeof(struct secvar)); + if (!var) + return OPAL_NO_MEM; + + var->data = malloc(data_size); + if (!var->data) { + free(var); + return OPAL_NO_MEM; + } + + + memcpy(var->name, name, namelen*2); + memcpy(&var->vendor, vendor, SECVAR_VENDOR_SIZE); + var->attributes = attributes; + var->data_size = data_size; + memcpy(var->data, data, data_size); + + list_add_tail(&update_bank, &var->link); + + if (!platform.secvar_write_bank) + return OPAL_HARDWARE; + + platform.secvar_write_bank(&update_bank, SECVAR_UPDATE_BANK); + + return OPAL_SUCCESS; +} +opal_call(OPAL_SECVAR_ENQUEUE_UPDATE, opal_secvar_enqueue_update, 5); From patchwork Thu Apr 11 22:45:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 1084350 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (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 44gGPf4Dpkz9s55 for ; Fri, 12 Apr 2019 08:47:34 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 44gGPf2zSTzDqTR for ; Fri, 12 Apr 2019 08:47:34 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=linux.ibm.com (client-ip=148.163.158.5; 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 (mx0b-001b2d01.pphosted.com [148.163.158.5]) (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 44gGN46wNwzDqT2 for ; Fri, 12 Apr 2019 08:46:12 +1000 (AEST) Received: from pps.filterd (m0098417.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x3BMhmMv031602 for ; Thu, 11 Apr 2019 18:46:10 -0400 Received: from e06smtp05.uk.ibm.com (e06smtp05.uk.ibm.com [195.75.94.101]) by mx0a-001b2d01.pphosted.com with ESMTP id 2rtc2web81-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 11 Apr 2019 18:46:10 -0400 Received: from localhost by e06smtp05.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 11 Apr 2019 23:46:08 +0100 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) Thu, 11 Apr 2019 23:46:06 +0100 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x3BMk59B60227686 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 11 Apr 2019 22:46:05 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E8D6E11C06C; Thu, 11 Apr 2019 22:46:04 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6A86B11C05C; Thu, 11 Apr 2019 22:46:04 +0000 (GMT) Received: from yorha.ibmuc.com (unknown [9.80.238.6]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 11 Apr 2019 22:46:04 +0000 (GMT) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Thu, 11 Apr 2019 17:45:49 -0500 X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190411224551.29401-1-erichte@linux.ibm.com> References: <20190411224551.29401-1-erichte@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 19041122-0020-0000-0000-0000032EE730 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19041122-0021-0000-0000-000021811A0C Message-Id: <20190411224551.29401-7-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-04-11_14:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=4 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-1810050000 definitions=main-1904110145 Subject: [Skiboot] [RFC v2 6/8] libstb: add secvar flash storage implementation for pnor-based p9 platforms 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: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This patch implements the platform specific logic for persisting the secure variable storage banks across reboots via the SECBOOT PNOR partition. This is a base implementation meant to provide the minimal functionality required, and is a work-in-progress. For POWER 9, all secure variables and updates are stored in the in the SECBOOT PNOR partition. The partition is split into three sections: two variable bank sections, and a section for storing updates. For this initial implementation, the second variable bank section is ignored, but later patches will alternate writes between them to provide a back up in the event of a failure. Forthcoming patches will extend this implementation to utilize the TPM NV storage space to protect the PNOR storage from external tampering. v2: - updated for new platform hooks - merged the load and write functions into one Signed-off-by: Eric Richter --- libstb/Makefile.inc | 2 +- libstb/secboot_p9.c | 293 ++++++++++++++++++++++++++++++++++++++++++++ libstb/secboot_p9.h | 8 ++ 3 files changed, 302 insertions(+), 1 deletion(-) create mode 100644 libstb/secboot_p9.c create mode 100644 libstb/secboot_p9.h diff --git a/libstb/Makefile.inc b/libstb/Makefile.inc index f3a7e716..a4da13bb 100644 --- a/libstb/Makefile.inc +++ b/libstb/Makefile.inc @@ -4,7 +4,7 @@ LIBSTB_DIR = libstb SUBDIRS += $(LIBSTB_DIR) -LIBSTB_SRCS = container.c tpm_chip.c cvc.c secureboot.c trustedboot.c secvar.c secvar_api.c +LIBSTB_SRCS = container.c tpm_chip.c cvc.c secureboot.c trustedboot.c secvar.c secvar_api.c secboot_p9.c LIBSTB_OBJS = $(LIBSTB_SRCS:%.c=%.o) LIBSTB = $(LIBSTB_DIR)/built-in.a diff --git a/libstb/secboot_p9.c b/libstb/secboot_p9.c new file mode 100644 index 00000000..20994b8b --- /dev/null +++ b/libstb/secboot_p9.c @@ -0,0 +1,293 @@ +/* Copyright 2019 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef pr_fmt +#define pr_fmt(fmt) "SECBOOT_P9: " fmt +#endif + +#include +#include +#include +#include "secboot_p9.h" +#include "secvar.h" + +// TODO: Determine reasonable values for these +#define SECBOOT_VARIABLE_BANK_SIZE 32000 +#define SECBOOT_UPDATE_BANK_SIZE 32000 + + +/* 0x5053424b = "PSBK" or Power Secure Boot Keystore */ +#define SECBOOT_MAGIC_NUMBER 0x5053424b +#define SECBOOT_VERSION 1 + +struct secboot_header { + uint32_t magic_number; + uint8_t version; + uint8_t reserved[3]; // Fix alignment +} __packed; + + +struct secboot { + struct secboot_header header; + char bank0[SECBOOT_VARIABLE_BANK_SIZE]; + char bank1[SECBOOT_VARIABLE_BANK_SIZE]; + char update[SECBOOT_UPDATE_BANK_SIZE]; +} __attribute__((packed)); + +struct secboot *secboot_image; + + +static int secboot_format(void) +{ + if (!platform.secboot_write) + return -1; + + memset(secboot_image, 0x00, sizeof(struct secboot)); + + secboot_image->header.magic_number = SECBOOT_MAGIC_NUMBER; + secboot_image->header.version = SECBOOT_VERSION; + + return platform.secboot_write(0, secboot_image, sizeof(struct secboot)); +} + + +static int secboot_serialize_bank(struct list_head *bank, char *target, size_t target_size) +{ + struct secvar *var; + char *tmp = target; + + if (!bank) + return -1; + if (!target) + return -1; + + list_for_each(bank, var, link) { + // Bail early if we are out of storage space + if ((tmp - target) + sizeof_secvar(var) > target_size) { + return -1; + } + memcpy(tmp, var->name, sizeof(var->name)); + tmp += sizeof(var->name); + memcpy(tmp, &var->vendor, sizeof(var->vendor)); + tmp += sizeof(var->vendor); + memcpy(tmp, &var->attributes, sizeof(var->attributes)); + tmp += sizeof(var->attributes); + memcpy(tmp, &var->data_size, sizeof(var->data_size)); + tmp += sizeof(var->data_size); + memcpy(tmp, var->data, var->data_size); + tmp += var->data_size; + } + + return 0; +} + + +static int secboot_write_to_pnor(struct list_head *bank, char *target, size_t max_size) +{ + int ret = 0; + + memset(target, 0, max_size); + + ret = secboot_serialize_bank(bank, target, max_size); + if (ret) + return ret; + + if (!platform.secboot_write) { + prlog(PR_ERR, "Failed to write: platform.secboot_write not set\n"); + return -1; + } + + ret = platform.secboot_write(0, secboot_image, sizeof(struct secboot)); + + return ret; +} + + +// Helper function to deserialize a single variable from a PNOR blob +// var should be initialized already +// source should point to the beginning of a variable buffer +// max_size should be how many remaining bytes are in the source buffer +// returns the number of bytes read in +static int secvar_deserialize_variable(struct secvar *var, char *source, size_t max_size) +{ + int size; + char *src = source; + char empty[] = {0,0,0,0}; + + if (!var) + return -1; + + // TODO: Do we want a sequence number, or magic number to signal the start of a variable? + if (!memcmp(source, empty, 4)) { + return 0; + } + + // Ensure the source buffer contains at least the variable header info + size = max_size - + sizeof(var->name) + + sizeof(var->vendor) + + sizeof(var->attributes) + + sizeof(var->data_size); + + if (size < 0) { + return -2; + } + + memcpy(var->name, src, sizeof(var->name)); + src += sizeof(var->name); + memcpy(&var->vendor, src, sizeof(var->vendor)); + src += sizeof(var->vendor); + memcpy(&var->attributes, src, sizeof(var->attributes)); + src += sizeof(var->attributes); + memcpy(&var->data_size, src, sizeof(var->data_size)); + src += sizeof(var->data_size); + + if (var->data_size > SECVAR_MAX_DATA_SIZE) { + return -3; + } + // Ensure the source buffer has the expected data size + if (var->data_size > size) { + return -4; + } + + var->data = malloc(var->data_size); + + memcpy(var->data, src, var->data_size); + src += var->data_size; + + return src - source; +} + + +static int secboot_load_from_pnor(struct list_head *bank, char *source, size_t max_size) +{ + char *src; + struct secvar *tmp; + int ret; + uint64_t empty = 0; + + src = source; + + while (src < (source + max_size)) { + // Peek to see if we are at the end of the bank + if (!memcmp(src, &empty, sizeof(empty))) { + break; + } + + tmp = malloc(sizeof(struct secvar)); + if (!tmp) { + prlog(PR_ERR, "Could not allocate memory for loading secvar from image\n"); + return -1; + } + + ret = secvar_deserialize_variable(tmp, src, (max_size - (src - source))); + if (ret == 0) { + free(tmp); + break; + } + else if (ret < 0) + return ret; + + list_add_tail(bank, &tmp->link); + src += ret; + } + + return 0; +} + +// TODO: support bank0 vs bank1 +int secvar_write_bank_p9(struct list_head *bank, int section) +{ + switch(section) { + case SECVAR_VARIABLE_BANK: + return secboot_write_to_pnor(bank, secboot_image->bank0, SECBOOT_VARIABLE_BANK_SIZE); + case SECVAR_UPDATE_BANK: + return secboot_write_to_pnor(bank, secboot_image->update, SECBOOT_UPDATE_BANK_SIZE); + } + + return OPAL_HARDWARE; +} + +int secvar_load_bank_p9(struct list_head *bank, int section) +{ + switch(section) { + case SECVAR_VARIABLE_BANK: + return secboot_load_from_pnor(bank, secboot_image->bank0, SECBOOT_VARIABLE_BANK_SIZE); + case SECVAR_UPDATE_BANK: + return secboot_load_from_pnor(bank, secboot_image->update, SECBOOT_UPDATE_BANK_SIZE); + } + + return OPAL_HARDWARE; +} + + +int secvar_platform_init_p9(void) +{ + int ret; + unsigned secboot_size; + + /* Already initialized */ + if (secboot_image) + return 0; + + if (!platform.secboot_info) + return -1; + + prlog(PR_DEBUG, "Initializing for pnor-based p9 platform\n"); + + ret = platform.secboot_info(&secboot_size); + if (ret) { + prlog(PR_ERR, "error %d retrieving keystore info\n", ret); + return -1; + } + if (sizeof(struct secboot) > secboot_size) { + prlog(PR_ERR, "secboot partition %d KB too small. min=%ld\n", + secboot_size >> 10, sizeof(struct secboot)); + return -1; + } + + secboot_image = memalign(0x1000, sizeof(struct secboot)); + if (!secboot_image) { + prlog(PR_ERR, "Failed to allocate space for the secboot image\n"); + return -1; + } + + /* Read it in */ + ret = platform.secboot_read(secboot_image, 0, sizeof(struct secboot)); + if (ret) { + prlog(PR_ERR, "failed to read the secboot partition, rc=%d\n", ret); + goto out_free; + } + + if (secboot_image->header.magic_number != SECBOOT_MAGIC_NUMBER) { + prlog(PR_INFO, "Formatting secboot partition...\n"); + ret = secboot_format(); + if (ret) { + prlog(PR_ERR, "Failed to format secboot!\n"); + goto out_free; + } + } + + return 0; + +out_free: + if (secboot_image) { + free(secboot_image); + secboot_image = NULL; + } + + return -1; +} diff --git a/libstb/secboot_p9.h b/libstb/secboot_p9.h new file mode 100644 index 00000000..07527fd8 --- /dev/null +++ b/libstb/secboot_p9.h @@ -0,0 +1,8 @@ +#ifndef _SECBOOT_P9_H_ +#define _SECBOOT_P9_H_ + +int secvar_platform_init_p9(void); +int secvar_load_bank_p9(struct list_head *bank, int section); +int secvar_write_bank_p9(struct list_head *bank, int section); + +#endif From patchwork Thu Apr 11 22:45:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 1084351 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (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 44gGPv3Vjlz9s55 for ; Fri, 12 Apr 2019 08:47:47 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 44gGPv2JXWzDqT6 for ; Fri, 12 Apr 2019 08:47:47 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) 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 44gGN64MWdzDqT7 for ; Fri, 12 Apr 2019 08:46:14 +1000 (AEST) Received: from pps.filterd (m0098399.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x3BMhspb096137 for ; Thu, 11 Apr 2019 18:46:13 -0400 Received: from e06smtp01.uk.ibm.com (e06smtp01.uk.ibm.com [195.75.94.97]) by mx0a-001b2d01.pphosted.com with ESMTP id 2rtcc75bx2-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 11 Apr 2019 18:46:12 -0400 Received: from localhost by e06smtp01.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 11 Apr 2019 23:46:10 +0100 Received: from b06cxnps3075.portsmouth.uk.ibm.com (9.149.109.195) by e06smtp01.uk.ibm.com (192.168.101.131) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Thu, 11 Apr 2019 23:46:08 +0100 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps3075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x3BMk6IG53477564 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 11 Apr 2019 22:46:07 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id CAAE411C070; Thu, 11 Apr 2019 22:46:06 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3CFB411C058; Thu, 11 Apr 2019 22:46:06 +0000 (GMT) Received: from yorha.ibmuc.com (unknown [9.80.238.6]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 11 Apr 2019 22:46:06 +0000 (GMT) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Thu, 11 Apr 2019 17:45:50 -0500 X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190411224551.29401-1-erichte@linux.ibm.com> References: <20190411224551.29401-1-erichte@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 19041122-4275-0000-0000-00000326EB11 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19041122-4276-0000-0000-000038360D48 Message-Id: <20190411224551.29401-8-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-04-11_14:, , 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=416 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904110145 Subject: [Skiboot] [RFC v2 7/8] platforms/witherspoon: enable secvar functions for the witherspoon platform 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: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This is an example patch to add the secvar functions to witherspoon. Most p9 systems will need a similar implementation, so there may be a better solution. Signed-off-by: Eric Richter --- platforms/astbmc/witherspoon.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platforms/astbmc/witherspoon.c b/platforms/astbmc/witherspoon.c index 52971ecf..015c41fc 100644 --- a/platforms/astbmc/witherspoon.c +++ b/platforms/astbmc/witherspoon.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "astbmc.h" #include "ast.h" @@ -512,4 +513,8 @@ DECLARE_PLATFORM(witherspoon) = { .pci_get_slot_info = dt_slot_get_slot_info, .ocapi = &witherspoon_ocapi, .npu2_device_detect = witherspoon_npu2_device_detect, + + .secvar_platform_init = secvar_platform_init_p9, + .secvar_load_bank = secvar_load_bank_p9, + .secvar_write_bank = secvar_write_bank_p9, }; From patchwork Thu Apr 11 22:45:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 1084352 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 44gGQC3FJ3z9s71 for ; Fri, 12 Apr 2019 08:48:03 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 44gGQC1qBrzDqTL for ; Fri, 12 Apr 2019 08:48:03 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=linux.ibm.com (client-ip=148.163.158.5; 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 (mx0b-001b2d01.pphosted.com [148.163.158.5]) (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 44gGN81tPBzDqTY for ; Fri, 12 Apr 2019 08:46:16 +1000 (AEST) Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x3BMit3I136092 for ; Thu, 11 Apr 2019 18:46:14 -0400 Received: from e06smtp04.uk.ibm.com (e06smtp04.uk.ibm.com [195.75.94.100]) by mx0b-001b2d01.pphosted.com with ESMTP id 2rtdcutvtb-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 11 Apr 2019 18:46:14 -0400 Received: from localhost by e06smtp04.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 11 Apr 2019 23:46:12 +0100 Received: from b06cxnps4075.portsmouth.uk.ibm.com (9.149.109.197) by e06smtp04.uk.ibm.com (192.168.101.134) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Thu, 11 Apr 2019 23:46:10 +0100 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x3BMk8h246465048 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 11 Apr 2019 22:46:08 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A715A11C058; Thu, 11 Apr 2019 22:46:08 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1E28F11C070; Thu, 11 Apr 2019 22:46:08 +0000 (GMT) Received: from yorha.ibmuc.com (unknown [9.80.238.6]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 11 Apr 2019 22:46:07 +0000 (GMT) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Thu, 11 Apr 2019 17:45:51 -0500 X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190411224551.29401-1-erichte@linux.ibm.com> References: <20190411224551.29401-1-erichte@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 19041122-0016-0000-0000-0000026DE8A6 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19041122-0017-0000-0000-000032CA214F Message-Id: <20190411224551.29401-9-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-04-11_14:, , 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=868 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904110145 Subject: [Skiboot] [RFC v2 8/8] secureboot: initialize secure variables on secureboot init 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: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" The secure variable storage needs to be loaded on boot, as the kernel or sysadmins may need to access the secure variables. This is a somewhat temporary initialization spot; it may be better initialized somewhere else. Secure variable access should be independent of firmware secure boot. Signed-off-by: Eric Richter --- libstb/secureboot.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libstb/secureboot.c b/libstb/secureboot.c index 4f6a301d..a6bc1712 100644 --- a/libstb/secureboot.c +++ b/libstb/secureboot.c @@ -24,6 +24,7 @@ #include #include #include "secureboot.h" +#include "secvar.h" static const void* hw_key_hash = NULL; static size_t hw_key_hash_size; @@ -83,6 +84,8 @@ void secureboot_init(void) int version; size_t size; + secvar_init(); + node = dt_find_by_path(dt_root, "/ibm,secureboot"); if (!node) { prlog(PR_NOTICE, "secure boot not supported\n");