From patchwork Wed Aug 1 23:40: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: 952485 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 41gqd12y9fz9s4s for ; Thu, 2 Aug 2018 09:43:33 +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 41gqd11jqqzF1s5 for ; Thu, 2 Aug 2018 09:43:33 +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 41gqZD0XR0zF1Qn for ; Thu, 2 Aug 2018 09:41:07 +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 w71Ndhgr115901 for ; Wed, 1 Aug 2018 19:41:05 -0400 Received: from e06smtp03.uk.ibm.com (e06smtp03.uk.ibm.com [195.75.94.99]) by mx0b-001b2d01.pphosted.com with ESMTP id 2kkjaj14dc-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 01 Aug 2018 19:41:05 -0400 Received: from localhost by e06smtp03.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 2 Aug 2018 00:41:03 +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) Thu, 2 Aug 2018 00:41:02 +0100 Received: from d06av23.portsmouth.uk.ibm.com (d06av23.portsmouth.uk.ibm.com [9.149.105.59]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w71Nf0Qf44237022 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 1 Aug 2018 23:41:00 GMT Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1B7DEA4051; Thu, 2 Aug 2018 02:41:11 +0100 (BST) Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9B0A5A4040; Thu, 2 Aug 2018 02:41:10 +0100 (BST) Received: from boston-1.rtp.stglabs.ibm.com (unknown [9.27.30.60]) by d06av23.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 2 Aug 2018 02:41:10 +0100 (BST) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Wed, 1 Aug 2018 19:40:41 -0400 X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180801234042.6740-1-erichte@linux.ibm.com> References: <20180801234042.6740-1-erichte@linux.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18080123-0012-0000-0000-000002927035 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18080123-0013-0000-0000-000020C47A22 Message-Id: <20180801234042.6740-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-1808010240 Subject: [Skiboot] [RFC PATCH RESEND 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 */