From patchwork Wed Aug 1 22:53:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 952538 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.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41gwZf1wYjz9s2g for ; Thu, 2 Aug 2018 13:26:50 +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 41gwZf0dwxzF1S7 for ; Thu, 2 Aug 2018 13:26:50 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com 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 41gpWy4kMVzF1RB for ; Thu, 2 Aug 2018 08:54:03 +1000 (AEST) Received: from pps.filterd (m0098421.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w71Mn7Tn060232 for ; Wed, 1 Aug 2018 18:54:00 -0400 Received: from e06smtp01.uk.ibm.com (e06smtp01.uk.ibm.com [195.75.94.97]) by mx0a-001b2d01.pphosted.com with ESMTP id 2kkms2agsa-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 01 Aug 2018 18:54:00 -0400 Received: from localhost by e06smtp01.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 1 Aug 2018 23:53:59 +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) Wed, 1 Aug 2018 23:53:57 +0100 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06cxnps3075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w71MruI135782810 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 1 Aug 2018 22:53:56 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A79C14C040; Thu, 2 Aug 2018 01:54:07 +0100 (BST) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 344C64C044; Thu, 2 Aug 2018 01:54:07 +0100 (BST) Received: from boston-1.rtp.stglabs.ibm.com (unknown [9.27.30.60]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 2 Aug 2018 01:54:07 +0100 (BST) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Wed, 1 Aug 2018 18:53:40 -0400 X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180801225349.6535-1-erichte@linux.ibm.com> References: <20180801225349.6535-1-erichte@linux.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18080122-4275-0000-0000-000002A22815 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18080122-4276-0000-0000-000037AA3F0B Message-Id: <20180801225349.6535-2-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-08-01_08:, , 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=882 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1806210000 definitions=main-1808010231 X-Mailman-Approved-At: Thu, 02 Aug 2018 13:26:14 +1000 Subject: [Skiboot] [RFC PATCH 01/10] libstb/container.h: add stdbool.h and short_types.h headers X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Claudio Carvalho MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" From: Claudio Carvalho This adds the stdbool.h and short_types.h headers. The container.h file uses some of the types defined in those headers. Signed-off-by: Claudio Carvalho --- libstb/container.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libstb/container.h b/libstb/container.h index 0d0acb23..e56e08b5 100644 --- a/libstb/container.h +++ b/libstb/container.h @@ -17,8 +17,10 @@ #ifndef __STB_CONTAINER_H #define __STB_CONTAINER_H +#include #include #include +#include #include #define SECURE_BOOT_HEADERS_SIZE 4096 From patchwork Wed Aug 1 22:53:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 952539 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.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41gwZx2vMZz9s2g for ; Thu, 2 Aug 2018 13:27:05 +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 41gwZw5CCdzF1Qn for ; Thu, 2 Aug 2018 13:27:04 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com 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 41gpWz4rlSzF1Qn for ; Thu, 2 Aug 2018 08:54:04 +1000 (AEST) Received: from pps.filterd (m0098421.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w71Mn8Sd060308 for ; Wed, 1 Aug 2018 18:54:02 -0400 Received: from e06smtp04.uk.ibm.com (e06smtp04.uk.ibm.com [195.75.94.100]) by mx0a-001b2d01.pphosted.com with ESMTP id 2kkms2agtv-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 01 Aug 2018 18:54:02 -0400 Received: from localhost by e06smtp04.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 1 Aug 2018 23:54:00 +0100 Received: from b06cxnps3074.portsmouth.uk.ibm.com (9.149.109.194) 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) Wed, 1 Aug 2018 23:53:59 +0100 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w71Mrvlc42926230 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 1 Aug 2018 22:53:57 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 640894C04A; Thu, 2 Aug 2018 01:54:09 +0100 (BST) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D6DD54C044; Thu, 2 Aug 2018 01:54:08 +0100 (BST) Received: from boston-1.rtp.stglabs.ibm.com (unknown [9.27.30.60]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 2 Aug 2018 01:54:08 +0100 (BST) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Wed, 1 Aug 2018 18:53:41 -0400 X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180801225349.6535-1-erichte@linux.ibm.com> References: <20180801225349.6535-1-erichte@linux.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18080122-0016-0000-0000-000001EF9D80 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18080122-0017-0000-0000-00003244C660 Message-Id: <20180801225349.6535-3-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-08-01_08:, , 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-1806210000 definitions=main-1808010231 X-Mailman-Approved-At: Thu, 02 Aug 2018 13:26:14 +1000 Subject: [Skiboot] [RFC PATCH 02/10] core/flash.c: add SECBOOT read and write support X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Claudio Carvalho MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" From: Claudio Carvalho The SECBOOT partition is used to store secure boot variables and variable updates. A variable/update can store several data types, including a x509 certificate, but for skiboot the variable/update data is a blob that can be handled by the linux kernel via secure boot runtime services (added by other patches in this series). This implements the SECBOOT API required to provide the aforementioned runtime services. This implementation is based on the NVRAM API implementation. NOTE: There are other ways to implement the SECBOOT API, for example extending the current resource load framework (flash API). Issues: (1) Looking at the NVRAM code, it seems that the flash API should be used only for boot services. (2) The flash API spend some space with partition and subpartition headers, but the SECBOOT space is very limited for the purpose. (3) The flash API doesn't support partial writes to a partition or subpartition. The SECBOOT API can also be implemented extending the NVRAM API. The same platform hooks could be used if a new parameter is added to determine the partition. CC: Jeremy Kerr Signed-off-by: Claudio Carvalho --- core/flash.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++ include/platform.h | 4 ++ 2 files changed, 122 insertions(+) diff --git a/core/flash.c b/core/flash.c index 8f00d85e..4e952cb0 100644 --- a/core/flash.c +++ b/core/flash.c @@ -49,6 +49,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; + /* ibm,firmware-versions support */ static char *version_buf; static size_t version_buf_size = 0x2000; @@ -76,6 +80,80 @@ 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; + } + + rc = blocklevel_read(secboot_flash->bl, secboot_offset + src, dst, len); + +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; + } + rc = blocklevel_write(secboot_flash->bl, secboot_offset + dst, src, len); + +out: + unlock(&flash_lock); + return rc; +} + static int flash_nvram_info(uint32_t *total_size) { int rc; @@ -283,6 +361,45 @@ void flash_fw_version_preload(void) } } +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; @@ -376,6 +493,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 1a35a86a..1ecafe74 100644 --- a/include/platform.h +++ b/include/platform.h @@ -161,6 +161,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 Wed Aug 1 22:53:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 952537 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.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41gwZM3W5xz9s2g for ; Thu, 2 Aug 2018 13:26:35 +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 41gwZM25WlzF1pk for ; Thu, 2 Aug 2018 13:26:35 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com 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 41gpWy0sfSzF1Qn for ; Thu, 2 Aug 2018 08:54:05 +1000 (AEST) Received: from pps.filterd (m0098421.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w71MnB4E060538 for ; Wed, 1 Aug 2018 18:54:04 -0400 Received: from e06smtp07.uk.ibm.com (e06smtp07.uk.ibm.com [195.75.94.103]) by mx0a-001b2d01.pphosted.com with ESMTP id 2kkms2agvh-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 01 Aug 2018 18:54:03 -0400 Received: from localhost by e06smtp07.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 1 Aug 2018 23:54:02 +0100 Received: from b06cxnps3074.portsmouth.uk.ibm.com (9.149.109.194) 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) Wed, 1 Aug 2018 23:54:00 +0100 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w71Mrx4B7143456 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 1 Aug 2018 22:53:59 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 298284C04E; Thu, 2 Aug 2018 01:54:11 +0100 (BST) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 937634C044; Thu, 2 Aug 2018 01:54:10 +0100 (BST) Received: from boston-1.rtp.stglabs.ibm.com (unknown [9.27.30.60]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 2 Aug 2018 01:54:10 +0100 (BST) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Wed, 1 Aug 2018 18:53:42 -0400 X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180801225349.6535-1-erichte@linux.ibm.com> References: <20180801225349.6535-1-erichte@linux.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18080122-0028-0000-0000-000002E3DC00 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18080122-0029-0000-0000-0000239BEA75 Message-Id: <20180801225349.6535-4-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-08-01_08:, , 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=989 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1806210000 definitions=main-1808010231 X-Mailman-Approved-At: Thu, 02 Aug 2018 13:26:14 +1000 Subject: [Skiboot] [RFC PATCH 03/10] opal-api: add values for secboot keystore management X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Claudio Carvalho MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This patch reserves the tokens for the key management Opal runtime services to be implemented in the following commits. This is currently separate to make rebasing and merging simpler, and each line can be merged into their respective implementation patch if necessary. Signed-off-by: Eric Richter --- include/opal-api.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/opal-api.h b/include/opal-api.h index f766dce9..562d4143 100644 --- a/include/opal-api.h +++ b/include/opal-api.h @@ -224,7 +224,12 @@ #define OPAL_PCI_SET_PBCQ_TUNNEL_BAR 165 #define OPAL_HANDLE_HMI2 166 #define OPAL_NX_COPROC_INIT 167 -#define OPAL_LAST 167 +#define OPAL_GET_VARIABLE 168 +#define OPAL_SET_VARIABLE 169 +#define OPAL_GET_NEXT_VARIABLE 170 +#define OPAL_SECBOOT_COMMIT 171 +#define OPAL_LOCK_VARIABLES 172 +#define OPAL_LAST 172 #define QUIESCE_HOLD 1 /* Spin all calls at entry */ #define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */ From patchwork Wed Aug 1 22:53:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 952540 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.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41gwbC2hzPz9s2g for ; Thu, 2 Aug 2018 13:27:19 +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 41gwbC18zmzF1s5 for ; Thu, 2 Aug 2018 13:27:19 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com 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 41gpX12rDjzF1Qn for ; Thu, 2 Aug 2018 08:54:09 +1000 (AEST) Received: from pps.filterd (m0098420.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w71MnWON142015 for ; Wed, 1 Aug 2018 18:54:06 -0400 Received: from e06smtp01.uk.ibm.com (e06smtp01.uk.ibm.com [195.75.94.97]) by mx0b-001b2d01.pphosted.com with ESMTP id 2kkjahyuuq-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 01 Aug 2018 18:54:06 -0400 Received: from localhost by e06smtp01.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 1 Aug 2018 23:54:04 +0100 Received: from b06cxnps3074.portsmouth.uk.ibm.com (9.149.109.194) 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) Wed, 1 Aug 2018 23:54:02 +0100 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w71Ms1Dt42926236 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 1 Aug 2018 22:54:01 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C351B4C044; Thu, 2 Aug 2018 01:54:12 +0100 (BST) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 593664C040; Thu, 2 Aug 2018 01:54:12 +0100 (BST) Received: from boston-1.rtp.stglabs.ibm.com (unknown [9.27.30.60]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 2 Aug 2018 01:54:12 +0100 (BST) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Wed, 1 Aug 2018 18:53:43 -0400 X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180801225349.6535-1-erichte@linux.ibm.com> References: <20180801225349.6535-1-erichte@linux.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18080122-4275-0000-0000-000002A2281A X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18080122-4276-0000-0000-000037AA3F10 Message-Id: <20180801225349.6535-5-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-08-01_08:, , 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-1806210000 definitions=main-1808010231 X-Mailman-Approved-At: Thu, 02 Aug 2018 13:26:14 +1000 Subject: [Skiboot] [RFC PATCH 04/10] libstb: initialize and format pnor secboot partition X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Claudio Carvalho MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" From: Claudio Carvalho The SECBOOT partition layout has three subsections of the same type. The first one stores active variables. The second stores staging variables, those that will become active in the next full reboot. Lastly, the third stores updates for the active variables, which are processed by the skiroot kernel at boot time. This defines the SECBOOT partition layout and also formats the partition with default values if it hasn't been formatted yet. NOTE1: In order to determine the subsections size, this assumes that the SECBOOT partition has the same size in all platforms that supports OS secure boot. NOTE2: The first two sub-sections are used to store variable blobs (a.k.a variable banks). Sometimes one bank acts as the active, sometimes it acts as the staging. Currently, the active and staging pointers point to the same bank, but in future there should be a selector bit in TPM NV to indicate which bank is the active. NOTE3: For simplicity, this loads the SECBOOT partition as a whole at boot time, although the staging bank is not consumed. Signed-off-by: Claudio Carvalho --- libstb/Makefile.inc | 2 +- libstb/secboot_part.c | 249 ++++++++++++++++++++++++++++++++++++++++++++++++++ libstb/secboot_part.h | 22 +++++ 3 files changed, 272 insertions(+), 1 deletion(-) create mode 100644 libstb/secboot_part.c create mode 100644 libstb/secboot_part.h diff --git a/libstb/Makefile.inc b/libstb/Makefile.inc index 6d54c5cd..5cd6c2ee 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 secboot_part.c LIBSTB_OBJS = $(LIBSTB_SRCS:%.c=%.o) LIBSTB = $(LIBSTB_DIR)/built-in.a diff --git a/libstb/secboot_part.c b/libstb/secboot_part.c new file mode 100644 index 00000000..e6558166 --- /dev/null +++ b/libstb/secboot_part.c @@ -0,0 +1,249 @@ +/* Copyright 2013-2018 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_PART: " fmt +#endif + +#include +#include "secboot_part.h" + +struct secboot_section_item { + const char *name; /* null terminated string */ + uint32_t size; + char data[0]; +} __packed; + +struct secboot_section_header { + uint8_t version; + uint32_t reserved; + uint32_t size; +} __packed; + +struct secboot_section { + struct secboot_section_header header; + struct secboot_section_item item[0]; // section_item place holder + // followed by other section items up to section size: + // SECBOOT_BANK_SIZE if it is bank section; or + // SECBOOT_QUEUE_SIZE if it is an update queue section +} __packed; + +struct secboot_header { + uint32_t magic_number; + uint8_t version; +} __packed; + +struct secboot_part { + struct secboot_header header; + struct secboot_section bank[0]; // section_header place holder + // followed by bank1 section + // followed by update queue section +} __packed; + +//#define SECBOOT_SECTION_SIZE(p) (sizeof(section_header) + p->size) +/* 0x5053424b = "PSBK" or Power Secure Boot Keystore */ +#define SECBOOT_MAGIC_NUMBER 0x5053424b +#define SECBOOT_VERSION 1 +#define SECBOOT_MINIMUM_SIZE (sizeof(struct secboot_header) + SECBOOT_BANK_SIZE*2 + SECBOOT_QUEUE_SIZE) + +#define SECBOOT_BANK_VERSION 1 +#define SECBOOT_BANK_SIZE 0xb400 // 45 KB + +#define SECBOOT_QUEUE_VERSION 1 +#define SECBOOT_QUEUE_SIZE 0x7800 // 30 KB + +static struct secboot_part *secboot = NULL; +static uint32_t secboot_size = 0; + +/* Indicates if the secboot partition data can be consumed */ +static bool secboot_valid = false; + +static struct secboot_section *active_bank = NULL; +static struct secboot_section *staging_bank = NULL; +static struct secboot_section *update_queue = NULL; + +static int secboot_part_format(void) +{ + struct secboot_section *section; + int rc; + + if (!platform.secboot_write) + return -1; + + memset(secboot, 0, secboot_size); + + /* INITIALIZE THE HEADERS */ + + /* secboot header */ + secboot->header.magic_number = SECBOOT_MAGIC_NUMBER; + secboot->header.version = SECBOOT_VERSION; + + /* bank0 section header */ + section = secboot->bank; + section->header.version = SECBOOT_BANK_VERSION; + section->header.reserved = 0; + section->header.size = SECBOOT_BANK_SIZE; + + /* bank1 section header */ + section = (struct secboot_section*)((uint8_t*) section + SECBOOT_BANK_SIZE); + section->header.version = SECBOOT_BANK_VERSION; + section->header.reserved = 0; + section->header.size = SECBOOT_BANK_SIZE; + + /* update queue section header */ + section = (struct secboot_section*)((uint8_t*) section + SECBOOT_BANK_SIZE); + section->header.version = SECBOOT_QUEUE_VERSION; + section->header.reserved = 0; + section->header.size = SECBOOT_QUEUE_SIZE; + + /* write the whole thing back to PNOR */ + rc = platform.secboot_write(0, secboot, secboot_size); + if (rc) + return -1; + + prlog(PR_INFO, "formatted\n"); + secboot_valid = true; + + return 0; +} + +/* + * Check that the keystore layout is sane. If not, we re-format the lot of it + */ +static int secboot_part_validate(void) +{ + if (secboot->header.magic_number != SECBOOT_MAGIC_NUMBER) { + prlog(PR_ERR, "magic number 0x%x mismatch, expected 0x%x\n", + secboot->header.magic_number, SECBOOT_MAGIC_NUMBER); + return -1; + } + if (secboot->header.version != SECBOOT_VERSION) { + prlog(PR_ERR, "secboot version %d not supported, expected %d\n", + secboot->header.version, SECBOOT_VERSION); + return -1; + } + + /* + * No need to check the staging bank version, we may overwrite it at + * runtime but we don't consume it + */ + + active_bank = secboot->bank; + if (active_bank->header.version != SECBOOT_BANK_VERSION) { + prlog(PR_ERR, "active bank version %d not supported, expected %d\n", + active_bank->header.version, SECBOOT_BANK_VERSION); + return -1; + } + + staging_bank = active_bank; + update_queue = (struct secboot_section*)((uint8_t*) secboot->bank + secboot->bank->header.size); + update_queue = (struct secboot_section*)((uint8_t*) update_queue + update_queue->header.size); + + if (update_queue->header.version != SECBOOT_QUEUE_VERSION) { + prlog(PR_ERR, "update queue version %d not supported, expected %d\n", + update_queue->header.version, SECBOOT_QUEUE_VERSION); + return -1; + } + + prlog(PR_INFO, "secboot partition valid\n"); + secboot_valid = true; + return 0; +} + + +int secboot_part_init() +{ + int rc; + + /* Already initialized */ + if (secboot) + return 0; + + if (!platform.secboot_info) + return -1; + rc = platform.secboot_info(&secboot_size); + if (rc) { + prlog(PR_ERR, "error %d retrieving keystore info\n", rc); + return -1; + } + if (SECBOOT_MINIMUM_SIZE > secboot_size) { + prlog(PR_ERR, "secboot partition %d KB too small. min=%ld\n", + secboot_size >> 10, SECBOOT_MINIMUM_SIZE); + return -1; + } + + prlog(PR_INFO, "size is %d KB\n", secboot_size >> 10); + + /* + * We allocate the pnor secboot image with 4k alignment to make the + * FSP backend job's easier + */ + secboot = memalign(0x1000, secboot_size); + if (!secboot) { + prlog(PR_ERR, "failed to allocate the secboot partition buffer\n"); + secboot_size = 0; + return -1; + } + + /* Read it in */ + rc = platform.secboot_read(secboot, 0, secboot_size); + if (rc) { + prlog(PR_ERR, "failed to read the secboot partition, rc=%d\n", rc); + goto out_free; + } + + /* + * TODO: + * 1. Can we assume that the secboot partition is zeroed out in MFG? + */ + if (secboot->header.magic_number == 0xffffffff || + secboot->header.version == 0xff || + secboot->header.magic_number == 0x00000000) { + rc = secboot_part_format(); + if (rc) + goto out_free; + } + + rc = secboot_part_validate(); + if (rc) + goto out_free; + + /* secboot header */ + prlog(PR_INFO, "secboot->magic_number 0x%x\n", secboot->header.magic_number); + prlog(PR_INFO, "secboot->version %d\n", secboot->header.version); + /* active bank header */ + prlog(PR_INFO, "active->version %d\n", active_bank->header.version); + prlog(PR_INFO, "active->reserved 0x%x\n", active_bank->header.reserved); + prlog(PR_INFO, "active->size %d KB\n", active_bank->header.size >> 10); + /* staging bank header */ + prlog(PR_INFO, "staging->version %d\n", staging_bank->header.version); + prlog(PR_INFO, "staging->reserved 0x%x\n", staging_bank->header.reserved); + prlog(PR_INFO, "staging->size %d KB\n", staging_bank->header.size >> 10); + /* update queue header */ + prlog(PR_INFO, "queue->version %d\n", update_queue->header.version); + prlog(PR_INFO, "queue->reserved 0x%x\n", update_queue->header.reserved); + prlog(PR_INFO, "queue->size %d KB\n", update_queue->header.size >> 10); + + return 0; + +out_free: + if (secboot) { + free(secboot); + secboot = NULL; + secboot_size = 0; + } + return -1; +} diff --git a/libstb/secboot_part.h b/libstb/secboot_part.h new file mode 100644 index 00000000..7f29183b --- /dev/null +++ b/libstb/secboot_part.h @@ -0,0 +1,22 @@ +/* Copyright 2013-2014 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 __SECBOOT_PART_H +#define __SECBOOT_PART_H + +int secboot_part_init(void); + +#endif /* __SECBOOT_PART_H */ From patchwork Wed Aug 1 22:53:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 952541 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.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41gwbW36znz9s2g for ; Thu, 2 Aug 2018 13:27:35 +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 41gwbV5mCRzF1jP for ; Thu, 2 Aug 2018 13:27:34 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com 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 41gpX13pX9zF1R6 for ; Thu, 2 Aug 2018 08:54:09 +1000 (AEST) Received: from pps.filterd (m0098421.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w71Mn7Eq060246 for ; Wed, 1 Aug 2018 18:54:07 -0400 Received: from e06smtp03.uk.ibm.com (e06smtp03.uk.ibm.com [195.75.94.99]) by mx0a-001b2d01.pphosted.com with ESMTP id 2kkms2agwn-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 01 Aug 2018 18:54:07 -0400 Received: from localhost by e06smtp03.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 1 Aug 2018 23:54:05 +0100 Received: from b06cxnps3074.portsmouth.uk.ibm.com (9.149.109.194) by e06smtp03.uk.ibm.com (192.168.101.133) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Wed, 1 Aug 2018 23:54:04 +0100 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w71Ms29N42795260 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 1 Aug 2018 22:54:03 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 803194C046; Thu, 2 Aug 2018 01:54:14 +0100 (BST) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id F2C2E4C040; Thu, 2 Aug 2018 01:54:13 +0100 (BST) Received: from boston-1.rtp.stglabs.ibm.com (unknown [9.27.30.60]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 2 Aug 2018 01:54:13 +0100 (BST) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Wed, 1 Aug 2018 18:53:44 -0400 X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180801225349.6535-1-erichte@linux.ibm.com> References: <20180801225349.6535-1-erichte@linux.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18080122-0012-0000-0000-000002926C02 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18080122-0013-0000-0000-000020C475E5 Message-Id: <20180801225349.6535-6-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-08-01_08:, , 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-1806210000 definitions=main-1808010231 X-Mailman-Approved-At: Thu, 02 Aug 2018 13:26:15 +1000 Subject: [Skiboot] [RFC PATCH 05/10] keystore: initialize the base keystore structure X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Claudio Carvalho MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This patch introduces and initializes the structures for representing the keystore in memory. Also included is the logic for parsing the secboot partition data into the in-memory keystore. The keystore is kept in-memory for a few reasons. First, we don't want to be reloading from PNOR whenever we want to retrieve a key, as the underlying PNOR section may have been overwritten without validation. The second point is a matter of performance -- by keeping things in memory it reduces the amount of slow I/O operations on the chip, as well as reducing the amount of wear. Finally, it is much simpler from a programming perspective to manipulate a list in-memory than to be constantly operating on a blob of binary data that would need to be reparsed each time, although this does consume more memory. There are two parts to the in-memory keystore: the Active Bank, and the Update Queue. The Active Bank is the list of keys to be operated on. As the name implies, the Update Queue is a queue of updates to be applied to the Active Bank (though the actual processing of this is left to the kernel[1]). For simplicity and sake of code reuse, the Active Bank and the Update Queue use the exact same format, and therefore can be loaded in the exact same manner -- the only difference is the offset that they are loaded from in the secboot partition. [1] Implementations of the update queue processing code in the kernel are forthcoming, we have an internal version that is not quite ready for upstream. Signed-off-by: Eric Richter --- libstb/Makefile.inc | 2 +- libstb/keystore.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++ libstb/keystore.h | 38 +++++++++++++++++++++++++++ libstb/secboot_part.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ libstb/secboot_part.h | 1 + libstb/secureboot.c | 4 +++ 6 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 libstb/keystore.c create mode 100644 libstb/keystore.h diff --git a/libstb/Makefile.inc b/libstb/Makefile.inc index 5cd6c2ee..6cc30134 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 secboot_part.c +LIBSTB_SRCS = container.c tpm_chip.c cvc.c secureboot.c trustedboot.c secboot_part.c keystore.c LIBSTB_OBJS = $(LIBSTB_SRCS:%.c=%.o) LIBSTB = $(LIBSTB_DIR)/built-in.a diff --git a/libstb/keystore.c b/libstb/keystore.c new file mode 100644 index 00000000..7d6027ef --- /dev/null +++ b/libstb/keystore.c @@ -0,0 +1,71 @@ +/* Copyright 2013-2017 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) "KEYSTORE: " fmt +#endif + +#include +#include +#include +#include "container.h" +#include "cvc.h" +#include "keystore.h" +#include "secboot_part.h" + +static struct list_head active_bank_list = LIST_HEAD_INIT(active_bank_list); +static struct list_head update_queue_list = LIST_HEAD_INIT(update_queue_list); + +static bool keystore_ready = false; /* has the keystore been loaded? */ + +// TODO: OPAL_UNSUPPORTED? +#define CHECK_KEYSTORE_READY if(!keystore_ready) {prlog(PR_ERR, "Ignoring call, keystore not ready\n"); return OPAL_RESOURCE; } + + + +int keystore_init(void) +{ + int rc; + + /* software secure boot supported only on p9 and above */ + if (proc_gen != proc_gen_p9) { + prlog(PR_INFO, "Secureboot is not supported on this platform\n"); + return 0; + } + + /* API init */ + list_head_init(&active_bank_list); + list_head_init(&update_queue_list); + + rc = secboot_part_init(); + if (rc) { + prlog(PR_ERR, "Failed to initialize the secboot partition\n"); + return -1; + } + + /* add variables we have in pnor secboot */ + rc = secboot_part_build_keystore(&active_bank_list, &update_queue_list); + if (rc) { + prlog(PR_ERR, "Failed to build the keystore\n"); + return -1; + } + + keystore_ready = true; + + prlog(PR_INFO, "Keystore initialized successfully\n"); + + return 0; +} diff --git a/libstb/keystore.h b/libstb/keystore.h new file mode 100644 index 00000000..e2eb296c --- /dev/null +++ b/libstb/keystore.h @@ -0,0 +1,38 @@ +/* Copyright 2013-2014 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 __KEYSTORE_H +#define __KEYSTORE_H + +// TODO: Assign these constants more intelligently +#define ACTIVE_BANK 0x1 +#define UPDATE_QUEUE 0x2 +#define CLEAR_QUEUE 0x4 +#define START_OVER 0x8 + +int keystore_init(void); + +// TODO: figure out how this differs from secboot_section_item +// Struct for bank lists +struct keystore_variable { + struct list_node link; + uint64_t name_size; + uint64_t data_size; + char *name; + char *data; +}; + +#endif /* __KEYSTORE_H */ diff --git a/libstb/secboot_part.c b/libstb/secboot_part.c index e6558166..9a2c8ac0 100644 --- a/libstb/secboot_part.c +++ b/libstb/secboot_part.c @@ -20,6 +20,7 @@ #include #include "secboot_part.h" +#include "keystore.h" struct secboot_section_item { const char *name; /* null terminated string */ @@ -164,6 +165,72 @@ static int secboot_part_validate(void) } +static int read_section(struct list_head *bank, char *cur, char *end) +{ + struct keystore_variable *var; + + while (cur < end) { + // Bail if variable name size is empty -- end of list + if (*((uint64_t*) cur) == 0llu) { + prlog(PR_INFO, "variable name size is empty, bailing\n"); + break; + } + + var = (struct keystore_variable*) malloc(sizeof(struct keystore_variable)); + if (!var) { + return -1; + } + + var->name_size = *((uint64_t*) cur); cur += sizeof(uint64_t); + var->data_size = *((uint64_t*) cur); cur += sizeof(uint64_t); + var->name = malloc(var->name_size); + if (!var->name) { + free(var); + return -2; + } + var->data = malloc(var->data_size); + if (!var->data) { + free(var->name); + free(var); + return -3; + } + + memcpy(var->name, cur, var->name_size); + cur += var->name_size; + memcpy(var->data, cur, var->data_size); + cur += var->data_size; + + prlog(PR_INFO, "loaded: '%s'\n", var->name); + + list_add_tail(bank, &var->link); + } + + return 0; +} + + +int secboot_part_build_keystore(struct list_head *active, struct list_head *uqueue) +{ + int ret = -1; + + if (!secboot_valid) + return -1; + + ret = read_section(active, (char*) active_bank->item, ((char*) active_bank) + SECBOOT_BANK_SIZE); + if (ret) { + prlog(PR_ERR, "Error loading Active Bank: %d\n", ret); + } + + ret = read_section(uqueue, (char*) update_queue->item, ((char*) update_queue) + SECBOOT_QUEUE_SIZE); + if (ret) { + prlog(PR_ERR, "Error loading update queue: %d\n", ret); + } + + return ret; + +} + + int secboot_part_init() { int rc; diff --git a/libstb/secboot_part.h b/libstb/secboot_part.h index 7f29183b..66e71561 100644 --- a/libstb/secboot_part.h +++ b/libstb/secboot_part.h @@ -18,5 +18,6 @@ #define __SECBOOT_PART_H int secboot_part_init(void); +int secboot_part_build_keystore(struct list_head* active, struct list_head* uqueue); #endif /* __SECBOOT_PART_H */ diff --git a/libstb/secureboot.c b/libstb/secureboot.c index 4f6a301d..c6b72b5d 100644 --- a/libstb/secureboot.c +++ b/libstb/secureboot.c @@ -24,6 +24,7 @@ #include #include #include "secureboot.h" +#include "keystore.h" static const void* hw_key_hash = NULL; static size_t hw_key_hash_size; @@ -171,6 +172,9 @@ void secureboot_init(void) secureboot_enforce(); secure_init = true; + + keystore_init(); + } int secureboot_verify(enum resource_id id, void *buf, size_t len) From patchwork Wed Aug 1 22:53:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 952542 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.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41gwbn3TBHz9s2g for ; Thu, 2 Aug 2018 13:27:49 +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 41gwbn2D9RzF1pH for ; Thu, 2 Aug 2018 13:27:49 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com 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 41gpX41l2ZzF1Qn for ; Thu, 2 Aug 2018 08:54:12 +1000 (AEST) Received: from pps.filterd (m0098417.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w71Mn8pH134161 for ; Wed, 1 Aug 2018 18:54:09 -0400 Received: from e06smtp02.uk.ibm.com (e06smtp02.uk.ibm.com [195.75.94.98]) by mx0a-001b2d01.pphosted.com with ESMTP id 2kknjxgvhn-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 01 Aug 2018 18:54:09 -0400 Received: from localhost by e06smtp02.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 1 Aug 2018 23:54:08 +0100 Received: from b06cxnps4076.portsmouth.uk.ibm.com (9.149.109.198) by e06smtp02.uk.ibm.com (192.168.101.132) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Wed, 1 Aug 2018 23:54:06 +0100 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w71Ms48239321688 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 1 Aug 2018 22:54:04 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3C8334C044; Thu, 2 Aug 2018 01:54:16 +0100 (BST) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id AFA8C4C040; Thu, 2 Aug 2018 01:54:15 +0100 (BST) Received: from boston-1.rtp.stglabs.ibm.com (unknown [9.27.30.60]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 2 Aug 2018 01:54:15 +0100 (BST) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Wed, 1 Aug 2018 18:53:45 -0400 X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180801225349.6535-1-erichte@linux.ibm.com> References: <20180801225349.6535-1-erichte@linux.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18080122-0008-0000-0000-0000025B59A1 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18080122-0009-0000-0000-000021C1F5BC Message-Id: <20180801225349.6535-7-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-08-01_08:, , 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-1806210000 definitions=main-1808010231 X-Mailman-Approved-At: Thu, 02 Aug 2018 13:26:15 +1000 Subject: [Skiboot] [RFC PATCH 06/10] keystore: add opal_get_variable runtime service X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Claudio Carvalho MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" The opal_get_variable runtime service retrieves a variable's data from the keystore list if the requested name (as a NULL-terminated string) exists in the requested section (enum for ACTIVE_BANK vs UPDATE_QUEUE). The kernel may query the size of a variable by calling this service by passing a NULL buffer parameter, and the by-reference varsize parameter will be set to the variable's data size if found. This will also occur if the varsize parameter is smaller than the requested data's size, to prevent overflows. NOTE: Included in this patch is a hacky macro to switch on the section enum, which is a behavior common to each of these runtime services. It should probably be changed to a static or inline function in the future. Signed-off-by: Eric Richter --- libstb/keystore.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/libstb/keystore.c b/libstb/keystore.c index 7d6027ef..8e19dbb6 100644 --- a/libstb/keystore.c +++ b/libstb/keystore.c @@ -34,6 +34,57 @@ static bool keystore_ready = false; /* has the keystore been loaded? */ // TODO: OPAL_UNSUPPORTED? #define CHECK_KEYSTORE_READY if(!keystore_ready) {prlog(PR_ERR, "Ignoring call, keystore not ready\n"); return OPAL_RESOURCE; } +// Translate the enum into a bank list pointer +#define GET_BANK(a) ((a&ACTIVE_BANK)?&active_bank_list:(((a&UPDATE_QUEUE)?&update_queue_list:NULL))) + + +static int64_t opal_get_variable(uint64_t k_buffer, uint64_t k_varsize, uint64_t k_varname, uint64_t section) +{ + // Outputs + char *buffer = (char*) k_buffer; + uint64_t *varsize = (uint64_t*) k_varsize; + // Inputs + char *varname = (char*) k_varname; + struct list_head *bank; + + struct keystore_variable *var = NULL; + + CHECK_KEYSTORE_READY; + + if (!varsize) { + prlog(PR_INFO, "Variable size parameter is NULL\n"); + return OPAL_PARAMETER; + } + + bank = GET_BANK(section); + if (!bank) { + prlog(PR_INFO, "Invalid section '%lld'\n", section); + return OPAL_PARAMETER; + } + + list_for_each(bank, var, link) { + if (!strcmp(varname, var->name)) { + goto found; + } + } + + prlog(PR_DEBUG, "No matching variable found for name '%s' in bank %lld\n", varname, section); + return OPAL_EMPTY; + +found: + // Check if this is a size query, or buffer is too small + if ((NULL == buffer) || (*varsize < var->data_size)) { + prlog(PR_DEBUG, "NULL/insufficient size check, returning varsize = %llu\n", var->data_size); + *varsize = var->data_size; + return OPAL_PARTIAL; + } + + memcpy(buffer, var->data, var->data_size); + *varsize = var->data_size; + + return OPAL_SUCCESS; +} +opal_call(OPAL_GET_VARIABLE, opal_get_variable, 4); int keystore_init(void) From patchwork Wed Aug 1 22:53:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 952543 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.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41gwc45x4vz9s2g for ; Thu, 2 Aug 2018 13:28:04 +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 41gwc44bPyzF1s5 for ; Thu, 2 Aug 2018 13:28:04 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com 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 41gpX54NdSzF1Qn for ; Thu, 2 Aug 2018 08:54:13 +1000 (AEST) Received: from pps.filterd (m0098396.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w71Mn9iZ017266 for ; Wed, 1 Aug 2018 18:54:11 -0400 Received: from e06smtp02.uk.ibm.com (e06smtp02.uk.ibm.com [195.75.94.98]) by mx0a-001b2d01.pphosted.com with ESMTP id 2kkfgf7p7e-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 01 Aug 2018 18:54:10 -0400 Received: from localhost by e06smtp02.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 1 Aug 2018 23:54:08 +0100 Received: from b06cxnps3074.portsmouth.uk.ibm.com (9.149.109.194) by e06smtp02.uk.ibm.com (192.168.101.132) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Wed, 1 Aug 2018 23:54:07 +0100 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w71Ms6HD42401858 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 1 Aug 2018 22:54:06 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id EDA8B4C040; Thu, 2 Aug 2018 01:54:17 +0100 (BST) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6C41B4C044; Thu, 2 Aug 2018 01:54:17 +0100 (BST) Received: from boston-1.rtp.stglabs.ibm.com (unknown [9.27.30.60]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 2 Aug 2018 01:54:17 +0100 (BST) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Wed, 1 Aug 2018 18:53:46 -0400 X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180801225349.6535-1-erichte@linux.ibm.com> References: <20180801225349.6535-1-erichte@linux.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18080122-0008-0000-0000-0000025B59A2 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18080122-0009-0000-0000-000021C1F5BD Message-Id: <20180801225349.6535-8-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-08-01_08:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=3 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-1806210000 definitions=main-1808010231 X-Mailman-Approved-At: Thu, 02 Aug 2018 13:26:15 +1000 Subject: [Skiboot] [RFC PATCH 07/10] keystore: add opal_set_variable runtime service X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Claudio Carvalho MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" The opal_set_variable runtime service operates the same way for the active bank and update queue; it updates an existing variable name's associated data with the supplied data blob if the requested name exists. If the requested name does not exist, it appends a new entry in the list. NOTE: This runtime service does not do any size checks, and is the likely candidate to do some form of size checking. Since we are holding the keys in a sparse structure in memory, this service should probably either use a routine to calculate the current total size, or a total size value should be maintained either in the list head or globally. Signed-off-by: Eric Richter --- libstb/keystore.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/libstb/keystore.c b/libstb/keystore.c index 8e19dbb6..8f825f8e 100644 --- a/libstb/keystore.c +++ b/libstb/keystore.c @@ -87,6 +87,66 @@ found: opal_call(OPAL_GET_VARIABLE, opal_get_variable, 4); +static int64_t opal_set_variable(uint64_t k_varname, uint64_t k_vardata, uint64_t varsize, uint64_t section) +{ + char *varname = (char*) k_varname; + char *vardata = (char*) k_vardata; + + struct keystore_variable *var = NULL; + + struct list_head *bank; + + CHECK_KEYSTORE_READY; + + bank = GET_BANK(section); + + list_for_each(bank, var, link) { + if (!strcmp(varname, var->name)) { + goto found; + } + } + + var = (struct keystore_variable *) malloc(sizeof(struct keystore_variable)); + if (!var) { + prlog(PR_ERR, "Failed to allocate new variable\n"); + return OPAL_NO_MEM; + } + + var->name_size = strlen(varname) + 1; + var->name = malloc(var->name_size); + var->name[var->name_size] = '\0'; // Ensure print-friendly NULL terminator + if (!var->name) { + prlog(PR_ERR, "Failed to allocate new variable's name\n"); + return OPAL_NO_MEM; + } + + memcpy(var->name, varname, var->name_size); + var->data = NULL; + + // Add to the list before moving to the shared behavior portion + list_add_tail(bank, &var->link); + +found: + // Clear old data if this is not a new variable. + if (var->data) + free(var->data); + + var->data_size = varsize; + var->data = malloc(var->data_size); + if (!var->data) { + prlog(PR_ERR, "Failed to allocate new variable's data\n"); + // TODO: we should probably clean up the linked list node if there is an error + // maybe we should try allocating data before freeing the old? + return OPAL_NO_MEM; + } + + memcpy(var->data, vardata, var->data_size); + + return OPAL_SUCCESS; +} +opal_call(OPAL_SET_VARIABLE, opal_set_variable, 4); + + int keystore_init(void) { int rc; From patchwork Wed Aug 1 22:53:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 952468 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.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41gpf232t4z9s3Z for ; Thu, 2 Aug 2018 08:59:22 +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 41gpf13BXfzF1Rb for ; Thu, 2 Aug 2018 08:59:21 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com 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 41gpdw0d4VzF1Qn for ; Thu, 2 Aug 2018 08:59:15 +1000 (AEST) Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w71Mx4rl021699 for ; Wed, 1 Aug 2018 18:59:13 -0400 Received: from e06smtp05.uk.ibm.com (e06smtp05.uk.ibm.com [195.75.94.101]) by mx0b-001b2d01.pphosted.com with ESMTP id 2kkmwujf8v-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 01 Aug 2018 18:59:13 -0400 Received: from localhost by e06smtp05.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 1 Aug 2018 23:54:11 +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) Wed, 1 Aug 2018 23:54:09 +0100 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w71Ms83K42401864 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 1 Aug 2018 22:54:08 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id AA2F74C040; Thu, 2 Aug 2018 01:54:19 +0100 (BST) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 28CCF4C044; Thu, 2 Aug 2018 01:54:19 +0100 (BST) Received: from boston-1.rtp.stglabs.ibm.com (unknown [9.27.30.60]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 2 Aug 2018 01:54:19 +0100 (BST) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Wed, 1 Aug 2018 18:53:47 -0400 X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180801225349.6535-1-erichte@linux.ibm.com> References: <20180801225349.6535-1-erichte@linux.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18080122-0020-0000-0000-000002AF9BEA X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18080122-0021-0000-0000-000020FBC47A Message-Id: <20180801225349.6535-9-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-08-01_08:, , 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-1806210000 definitions=main-1808010233 Subject: [Skiboot] [RFC PATCH 08/10] keystore: add opal_get_next_variable runtime service X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Claudio Carvalho MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" The opal_get_next_variable runtime service allows the caller to iterate through a bank, and receive the name and optionally the size of the variable. Each call to opal_get_next_variable will return the next item in the list until the end is reached, where the varname will be set to NULL, and OPAL_EMPTY is returned. Since this runtime service maintains its own state, the caller must be aware of when this function is called, and to OR the section with START_OVER if they wish to reset. NOTE: This runtime service is already slated for a rewrite! I kept this version here since it is a perfect example of reacting to unforseen implementation issues. An alternate implementation has been proposed that takes an additional argument: the name of the previous. This allows for the the caller to maintain the state instead, allowing multiple calls to this service from multiple threads/locations without requiring synchronization. NOTE #2: This commit also introduces a few macros from upstream ccan that are not in the version included in skiboot. Since the proposed rewrite of this function would no longer need the macros, consider them irrelevant to this commit other than to make it compile. Signed-off-by: Eric Richter --- libstb/keystore.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ libstb/keystore.h | 19 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/libstb/keystore.c b/libstb/keystore.c index 8f825f8e..0ddabf5f 100644 --- a/libstb/keystore.c +++ b/libstb/keystore.c @@ -147,6 +147,57 @@ found: opal_call(OPAL_SET_VARIABLE, opal_set_variable, 4); +static int64_t opal_get_next_variable(uint64_t k_varname, uint64_t k_size, uint64_t section) +{ + static struct keystore_variable *active_prev = NULL; + static struct keystore_variable *update_prev = NULL; + struct keystore_variable **prev; // TODO: replace this with a switching macro? + struct list_head *bank; + + uint64_t *size = (uint64_t *) k_size; + + CHECK_KEYSTORE_READY; + + // Operate on each bank separately, but we can alias the value to make it easier + switch(section & (~START_OVER)) { + case ACTIVE_BANK: prev = &active_prev; break; + case UPDATE_QUEUE: prev = &update_prev; break; + default: return OPAL_PARAMETER; + } + + if (section & START_OVER) { + *prev = NULL; + } + + // TODO: This may not be needed anymore if the above is doing the check + bank = GET_BANK(section); + if (!bank) { + return OPAL_PARAMETER; + } + + // If this is the first (fresh) call + if (!(*prev)) { + *prev = list_top(bank, struct keystore_variable, link); + } + // Catch subsequent calls, and incremenet the pointer + else { + *prev = list_next(bank, *prev, link); + } + + // End of the list, or list is empty + if (!(*prev)) { + return OPAL_EMPTY; + } + + strcpy((char*) k_varname, (*prev)->name); + if (size) + *size = (*prev)->data_size; + + return OPAL_SUCCESS; +} +opal_call(OPAL_GET_NEXT_VARIABLE, opal_get_next_variable, 3); + + int keystore_init(void) { int rc; diff --git a/libstb/keystore.h b/libstb/keystore.h index e2eb296c..eaaeb1dd 100644 --- a/libstb/keystore.h +++ b/libstb/keystore.h @@ -35,4 +35,23 @@ struct keystore_variable { char *data; }; + +// TODO: Eventually not depend on these macros here +#define list_typeof(var) typeof(var) + +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; +} + +#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 /* __KEYSTORE_H */ From patchwork Wed Aug 1 22:53:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 952469 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.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41gpfL0Vzjz9s3Z for ; Thu, 2 Aug 2018 08:59:38 +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 41gpfK4bhLzF1wB for ; Thu, 2 Aug 2018 08:59:37 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com 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 41gpdw6Zh1zF1R6 for ; Thu, 2 Aug 2018 08:59:16 +1000 (AEST) Received: from pps.filterd (m0098421.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w71Mx5Kc085146 for ; Wed, 1 Aug 2018 18:59:14 -0400 Received: from e06smtp02.uk.ibm.com (e06smtp02.uk.ibm.com [195.75.94.98]) by mx0a-001b2d01.pphosted.com with ESMTP id 2kkms2andm-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 01 Aug 2018 18:59:14 -0400 Received: from localhost by e06smtp02.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 1 Aug 2018 23:54:12 +0100 Received: from b06cxnps3075.portsmouth.uk.ibm.com (9.149.109.195) by e06smtp02.uk.ibm.com (192.168.101.132) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Wed, 1 Aug 2018 23:54:11 +0100 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06cxnps3075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w71Ms9Pg37879946 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 1 Aug 2018 22:54:09 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6731A4C040; Thu, 2 Aug 2018 01:54:21 +0100 (BST) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D9CD24C046; Thu, 2 Aug 2018 01:54:20 +0100 (BST) Received: from boston-1.rtp.stglabs.ibm.com (unknown [9.27.30.60]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 2 Aug 2018 01:54:20 +0100 (BST) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Wed, 1 Aug 2018 18:53:48 -0400 X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180801225349.6535-1-erichte@linux.ibm.com> References: <20180801225349.6535-1-erichte@linux.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18080122-0008-0000-0000-0000025B59A3 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18080122-0009-0000-0000-000021C1F5BE Message-Id: <20180801225349.6535-10-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-08-01_08:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=3 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-1806210000 definitions=main-1808010233 Subject: [Skiboot] [RFC PATCH 09/10] keystore: add opal_secboot_commit runtime service X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Claudio Carvalho MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" The opal_secboot_commit runtime service serializes an in-memory keystore bank and writes it out to the appropriate offset in the secboot partition. There are three options for the section flag: the two in-memory keystore banks ACTIVE_BANK and UPDATE_QUEUE, and a third option CLEAR_QUEUE. The first two flags function almost the same, serialize their respective list and write the blob to PNOR. CLEAR_QUEUE is a special case for use after the update queue has been processed by the kernel and no longer needed, therefore flushing the list and zeroing out the region in the secboot partition. This patch also introduces the secboot_serialize_and_write operation, which takes in a keystore bank list and handles the appropriate serialization logic. This function may be tweaked in the future to accomodate platform specific changes. For example, p9 may implement this function to write variables or other bits of data to the TPM, whereas platforms with lockable flash may not need to do this. NOTE: Right now, this is written to allow for a composite flag to allow for multiple operations to be handled by a single Opal call, however the call itself does not intelligently handle multiple operations -- that is, the call will not lump the serialized blobs into a single PNOR write. This is partially due to the nature of the secboot partition, as this may not all be one contiguous blob Signed-off-by: Eric Richter --- libstb/keystore.c | 39 +++++++++++++++++++++++++++++++++++ libstb/secboot_part.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ libstb/secboot_part.h | 1 + 3 files changed, 97 insertions(+) diff --git a/libstb/keystore.c b/libstb/keystore.c index 0ddabf5f..1c853380 100644 --- a/libstb/keystore.c +++ b/libstb/keystore.c @@ -198,6 +198,45 @@ static int64_t opal_get_next_variable(uint64_t k_varname, uint64_t k_size, uint6 opal_call(OPAL_GET_NEXT_VARIABLE, opal_get_next_variable, 3); +// Cleanup function to empty out a bank list +static void clear_bank_list(struct list_head *head) +{ + struct keystore_variable *node, *next; + + list_for_each_safe(head, node, next, link) { + free(node->name); + free(node->data); + list_del(&node->link); + free(node); + } +} + + +static int64_t opal_secboot_commit(uint64_t section) +{ + int ret = OPAL_SUCCESS; + + CHECK_KEYSTORE_READY; + + if (section & ACTIVE_BANK) { + ret = secboot_part_serialize_and_write(&active_bank_list, ACTIVE_BANK); + } + + if (section & UPDATE_QUEUE) { + ret = secboot_part_serialize_and_write(&update_queue_list, UPDATE_QUEUE); + } + + if (section & CLEAR_QUEUE) { + ret = secboot_part_serialize_and_write(NULL, CLEAR_QUEUE); + // Do we want to clear the in-memory queue even if the above fails? + clear_bank_list(&update_queue_list); + } + + return (ret) ? OPAL_RESOURCE : OPAL_SUCCESS; +} +opal_call(OPAL_SECBOOT_COMMIT, opal_secboot_commit, 1); + + int keystore_init(void) { int rc; diff --git a/libstb/secboot_part.c b/libstb/secboot_part.c index 9a2c8ac0..81b359bf 100644 --- a/libstb/secboot_part.c +++ b/libstb/secboot_part.c @@ -231,6 +231,63 @@ int secboot_part_build_keystore(struct list_head *active, struct list_head *uque } +static int write_variable(char *target, struct keystore_variable *var) +{ + char *cur = target; + + prlog(PR_INFO, "Writing variable '%s'\n", var->name); + + *((uint64_t*) cur) = var->name_size; cur += sizeof(uint64_t); + *((uint64_t*) cur) = var->data_size; cur += sizeof(uint64_t); + memcpy(cur, var->name, var->name_size); + cur += var->name_size; + memcpy(cur, var->data, var->data_size); + cur += var->data_size; + + return cur - target; +} + + +int secboot_part_serialize_and_write(struct list_head *head, int section) +{ + struct keystore_variable *var; + char *cur = NULL, *end = NULL; + + switch(section) { + case ACTIVE_BANK: + cur = (char*) active_bank->item; + end = ((char*) active_bank) + SECBOOT_BANK_SIZE; + break; + case UPDATE_QUEUE: + cur = (char*) update_queue->item; + end = ((char*) update_queue) + SECBOOT_QUEUE_SIZE;; + break; + + case CLEAR_QUEUE: + memset(update_queue->item, 0x00, SECBOOT_QUEUE_SIZE - sizeof(struct secboot_section)); // header? + goto out; // Skip the serialization of variables + + default: return -1; + } + + if (!head) return -1; // head should not be NULL with section != CLEAR_QUEUE + + prlog(PR_INFO, "cur = %p\n", cur); + list_for_each(head, var, link) { + cur += write_variable(cur, var); + } + prlog(PR_INFO, "cur = %p\n", cur); + + memset(cur, 0x00, end-cur); // Clear the rest of the bank + +out: + prlog(PR_INFO,"performing write\n"); + platform.secboot_write(0, secboot, secboot_size); + + return 0; +} + + int secboot_part_init() { int rc; diff --git a/libstb/secboot_part.h b/libstb/secboot_part.h index 66e71561..a853f8c6 100644 --- a/libstb/secboot_part.h +++ b/libstb/secboot_part.h @@ -19,5 +19,6 @@ int secboot_part_init(void); int secboot_part_build_keystore(struct list_head* active, struct list_head* uqueue); +int secboot_part_serialize_and_write(struct list_head *head, int section); #endif /* __SECBOOT_PART_H */ From patchwork Wed Aug 1 22:53:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 952470 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.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41gpfb6M1Vz9s4c for ; Thu, 2 Aug 2018 08:59:51 +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 41gpfb58kczF1pH for ; Thu, 2 Aug 2018 08:59:51 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com 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 41gpdz6HzGzF1Qn for ; Thu, 2 Aug 2018 08:59:19 +1000 (AEST) Received: from pps.filterd (m0098396.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w71Mx4BM044912 for ; Wed, 1 Aug 2018 18:59:17 -0400 Received: from e06smtp03.uk.ibm.com (e06smtp03.uk.ibm.com [195.75.94.99]) by mx0a-001b2d01.pphosted.com with ESMTP id 2kkfgf7tf2-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 01 Aug 2018 18:59:17 -0400 Received: from localhost by e06smtp03.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 1 Aug 2018 23:54:15 +0100 Received: from b06cxnps4075.portsmouth.uk.ibm.com (9.149.109.197) by e06smtp03.uk.ibm.com (192.168.101.133) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Wed, 1 Aug 2018 23:54:13 +0100 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w71MsBdA28180652 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 1 Aug 2018 22:54:11 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 23A054C040; Thu, 2 Aug 2018 01:54:23 +0100 (BST) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 967C64C04A; Thu, 2 Aug 2018 01:54:22 +0100 (BST) Received: from boston-1.rtp.stglabs.ibm.com (unknown [9.27.30.60]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 2 Aug 2018 01:54:22 +0100 (BST) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Wed, 1 Aug 2018 18:53:49 -0400 X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180801225349.6535-1-erichte@linux.ibm.com> References: <20180801225349.6535-1-erichte@linux.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18080122-0012-0000-0000-000002926C06 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18080122-0013-0000-0000-000020C475E9 Message-Id: <20180801225349.6535-11-erichte@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-08-01_08:, , 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-1806210000 definitions=main-1808010233 Subject: [Skiboot] [RFC PATCH 10/10] keystore: add experimental opal_lock_variables runtime service X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Claudio Carvalho MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" The opal_lock_variables runtime service can be called to lock specific operations until the next full reboot. For example, it could be called to write lock the keystore in-memory copy until the next full reboot. Currently, only opal_set_variable and opal_secboot_commit are able to write-locked. NOTE: This is a very drafty patch. It is currently unknown if this feature is even necessary, or if it even protects anything. The intended use is to lock down the in-memory keystore after the update queue has been processed in early skiroot, so that subsequent kernels can no longer manipulate the in-memory keystore or secboot partition beyond writes to the update queue. Signed-off-by: Eric Richter --- libstb/keystore.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/libstb/keystore.c b/libstb/keystore.c index 1c853380..34e5b72e 100644 --- a/libstb/keystore.c +++ b/libstb/keystore.c @@ -30,6 +30,7 @@ static struct list_head active_bank_list = LIST_HEAD_INIT(active_bank_list); static struct list_head update_queue_list = LIST_HEAD_INIT(update_queue_list); static bool keystore_ready = false; /* has the keystore been loaded? */ +static int active_lock = 0; // TODO: OPAL_UNSUPPORTED? #define CHECK_KEYSTORE_READY if(!keystore_ready) {prlog(PR_ERR, "Ignoring call, keystore not ready\n"); return OPAL_RESOURCE; } @@ -100,6 +101,11 @@ static int64_t opal_set_variable(uint64_t k_varname, uint64_t k_vardata, uint64_ bank = GET_BANK(section); + if ((section == ACTIVE_BANK) && (active_lock)) { + prlog(PR_ERR, "Variable Bank has been locked, refusing to update variable\n"); + return OPAL_RESOURCE; + } + list_for_each(bank, var, link) { if (!strcmp(varname, var->name)) { goto found; @@ -197,7 +203,6 @@ static int64_t opal_get_next_variable(uint64_t k_varname, uint64_t k_size, uint6 } opal_call(OPAL_GET_NEXT_VARIABLE, opal_get_next_variable, 3); - // Cleanup function to empty out a bank list static void clear_bank_list(struct list_head *head) { @@ -218,7 +223,7 @@ static int64_t opal_secboot_commit(uint64_t section) CHECK_KEYSTORE_READY; - if (section & ACTIVE_BANK) { + if ((section & ACTIVE_BANK) && (!active_lock)) { ret = secboot_part_serialize_and_write(&active_bank_list, ACTIVE_BANK); } @@ -237,6 +242,24 @@ static int64_t opal_secboot_commit(uint64_t section) opal_call(OPAL_SECBOOT_COMMIT, opal_secboot_commit, 1); + +// TODO: Determine and implement actual R/W mode locks +static int64_t opal_lock_variables(uint64_t section, uint64_t mode) +{ + (void) mode; + + CHECK_KEYSTORE_READY; + + if (section == ACTIVE_BANK) { + active_lock = 1; + } + + return OPAL_SUCCESS; +} +opal_call(OPAL_LOCK_VARIABLES, opal_lock_variables, 2); + + + int keystore_init(void) { int rc; @@ -265,6 +288,7 @@ int keystore_init(void) } keystore_ready = true; + active_lock = 0; prlog(PR_INFO, "Keystore initialized successfully\n");