From patchwork Fri Jan 12 11:52:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Storm, Christian" X-Patchwork-Id: 859812 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=googlegroups.com (client-ip=2a00:1450:400c:c09::239; helo=mail-wm0-x239.google.com; envelope-from=swupdate+bncbdd6bwv65qpbbboe4ljakgqejk7rwsi@googlegroups.com; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=googlegroups.com header.i=@googlegroups.com header.b="bQyiRSbG"; dkim-atps=neutral Received: from mail-wm0-x239.google.com (mail-wm0-x239.google.com [IPv6:2a00:1450:400c:c09::239]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zJ1Q14j5Wz9sNw for ; Fri, 12 Jan 2018 22:54:47 +1100 (AEDT) Received: by mail-wm0-x239.google.com with SMTP id o16sf3073704wmf.4 for ; Fri, 12 Jan 2018 03:54:47 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1515758085; cv=pass; d=google.com; s=arc-20160816; b=M3DeexeB8plfEb5GqCWcI4zIwSyeAukQnCmkvVkCrLEoA45vFGNNsywHr0dalrrt5N 8HP6wo/aT3O+KV7lgMtcKf4/MlsofyI43Kr+tlFQab0B2XB6g84tK7PyU78p/YAtfO0m BhWafjDaJkirpbtPaPh9whb8yaHpfBDYJQniaCrqDVZmtWHTBlEK7l3kQhPvvnQeeKxq UYBwpj3jn3TWEpnVW+JLtwM8tAUtV/woGl8CCNFQqur0Dy6AJ0kJquBkF7XQ0cwcdm3v yurMWyy5uj1iNFQ7ZLiWeDuhS/VXGglmk4kWbPVZNO5Trj+Nv+CjBVGdLrwOaxJr8FhJ 4uUw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:message-id:date:subject:cc:to:from :arc-authentication-results:arc-message-signature:mime-version :sender:dkim-signature:arc-authentication-results; bh=3mtKEDQ5PZbCfcpliO/7j2qJzn+WGRqRsr1zp52UESw=; b=gPAQ6yr8QCrrQTG1+2jQJAMszKqYN58HBWzllW/zpqL6r6pIjraisQhF2VCQ1gk6gZ dzqMDuJfWmVbsb+GbdH9JHmknkUgxZQ1U0Kk8OI1nOI66VwVQ/SsqqLKGOl0xgIIfaIN GpZ9/MM5Y6WVzq5U76+wjj5FFn89LNDenAb/aryKHc23r2Pjh3te9rtWtdrvlHKM3yRr oh1gJTBEaOQev8smCjwH6xbl1i/ZrS5WAWPTxduLw973V24vNKPRTndW0OVie7CT1yvx zYu6ubCw48+TY+pJS3QxIPtbp6W2+55wME/O0yqtDNzhb4z2aG03fGqvFVZ9EzlZPsBO GKYg== ARC-Authentication-Results: i=2; gmr-mx.google.com; spf=pass (google.com: domain of christian.storm@siemens.com designates 192.35.17.28 as permitted sender) smtp.mailfrom=christian.storm@siemens.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20161025; h=sender:mime-version:from:to:cc:subject:date:message-id :x-original-sender:x-original-authentication-results:precedence :mailing-list:list-id:list-post:list-help:list-archive :list-subscribe:list-unsubscribe; bh=3mtKEDQ5PZbCfcpliO/7j2qJzn+WGRqRsr1zp52UESw=; b=bQyiRSbG4iDz3VlNPFxwEplxM6fi3j0tA8Bjtqg0o63YScQUpwGV39o05LaBR3QwBV UTQ0g24PDawx5s3vZiBDvWimwfxMosYwsZ0hgdJS0w9qnyXr2eIpHH+7MvIuHRqfZXyy esUt3Oqe3SZQFR8edKXq/mgsWLvpupz/qSzNLn71iM3+QCb4tHvGudhpD+ZCvX/7rJdx l490MmKUcSz/SaxJydshNt67x7HCvItj01y4kHRfusp+5Xzw6XMmPKuDdMCazeYfQEC3 UKfju1/6pIIeGZ9/Vv9mvHIaA23DDxWiKWPN7IWLofLubvS9vl9xO8pDonaHdE/vYm9F 765A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=sender:x-gm-message-state:mime-version:from:to:cc:subject:date :message-id:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post :list-help:list-archive:list-subscribe:list-unsubscribe; bh=3mtKEDQ5PZbCfcpliO/7j2qJzn+WGRqRsr1zp52UESw=; b=tlHagRI4HiIuzO77FxqcRe1kXgjYXgsPbyiG3/fZirHH3uPyw/1nni1Wm5zeO78ROW yH/CdeUNPKcC6MGTvIZ6tZ63GBmP4odO4kyrVVeLw/Mx1jDWTuFpmm6KVD05iIGXaVuq C3DXaza2OLhXK8YSptoXPabLHG6pbUVmQvuJjj75wFk4iYer4IHWqVzb+SLv3C57Nvsb 8z5bM1O1CBZCpi0v3jqCHkYx9DZm3j5oqPe0z1/falj3vrl2eZaVhmcuuKpwwWQbWRF3 5ZvN9KpcCgyv1h3v7a8mAKZaV6B1qAxZi3yYyvlq6s9dEADyKuk51ln6R0cA/zbYmGrV JiKg== Sender: swupdate@googlegroups.com X-Gm-Message-State: AKwxytfl7j8QMOmymfFZwPTV5g6VlFgJSEoZ00+k7C5nNtikdMa0Fl8k dedxXY2nVlxHLZ+PEhqg2L8= X-Google-Smtp-Source: ACJfBovWPza81cOZIIRrejSbvExU1sKMkX8jUYCH3EH9ONa0hgTxjh8szT92vP3PsXwyztj4LMhssQ== X-Received: by 10.28.54.133 with SMTP id y5mr45439wmh.7.1515758085343; Fri, 12 Jan 2018 03:54:45 -0800 (PST) MIME-Version: 1.0 X-BeenThere: swupdate@googlegroups.com Received: by 10.28.14.134 with SMTP id 128ls148623wmo.4.canary-gmail; Fri, 12 Jan 2018 03:54:44 -0800 (PST) X-Received: by 10.28.239.5 with SMTP id n5mr508523wmh.10.1515758084695; Fri, 12 Jan 2018 03:54:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515758084; cv=none; d=google.com; s=arc-20160816; b=OCN2/+rsh3WQRS07zur2RKu24V7ocQoaXLa8bbJn7mU+ffEbs9/ExjS/Zuwc77UhfV aJ1uglPqYrZa81XI9TSz12D33GkDCjSBeqMsOWIpKGePBwN8ZXCbj+GNXqLHAcjEukgl phThaCDoBDp0w/wpaUrwaSeuVnVYnqKbS5ehzinUnk5055XIflD7TuYOAmkjg0ZK+H8r TYAPDaWwNV7ubBNI9Q2bNkaonWBheBsve0FgL/CA6j2RuH7kYSI1yH00q58sLj5JIYA7 6vYbwlV3Dfo9aS2j1t2MbuwUsRV8sEwke1QwCXYeX0gkS7bFH0kHbnaAcD44fLsLN+N7 UiEw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=message-id:date:subject:cc:to:from:arc-authentication-results; bh=HokFhVmwoY3A2hkvwFyPBGpqENWoDV/lp1nmkOWnIak=; b=l+bzmWT4nLfkPYA49NbyAEvObVQZsgBHs5RLbSy5yV32A/f1UJonbWzayWOZQ/cjjW DhW9FYvdFaTJsmvj24RLuubIWRjrpBrrVmh+uXMhGRvEUsl2o8NAkQAp03MCNkiT18Na H8e4LUqoVVGvBxM1W2t7ZRP11dtXuh1Cmj5mKhoT/ijF0ux1g0jbGTKsUo6DHju25Hbt 9xwWSUdYdEVpn/Hrc0a1rgFb/eAuuqAEVT+8NCIRXYviLthFK9i6HyG/RSODJXmnTXC9 CJPHqtf4xrt6i/Jm4yQDMnl9fv6O0tyN0pqkx6yPHsSkSqlYdL4Psr13VBcV+cJ+37fD JIsg== ARC-Authentication-Results: i=1; gmr-mx.google.com; spf=pass (google.com: domain of christian.storm@siemens.com designates 192.35.17.28 as permitted sender) smtp.mailfrom=christian.storm@siemens.com Received: from goliath.siemens.de (goliath.siemens.de. [192.35.17.28]) by gmr-mx.google.com with ESMTPS id i17si167735wmh.4.2018.01.12.03.54.44 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 12 Jan 2018 03:54:44 -0800 (PST) Received-SPF: pass (google.com: domain of christian.storm@siemens.com designates 192.35.17.28 as permitted sender) client-ip=192.35.17.28; Received: from mail3.siemens.de (mail3.siemens.de [139.25.208.14]) by goliath.siemens.de (8.15.2/8.15.2) with ESMTPS id w0CBsi4R014917 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Jan 2018 12:54:44 +0100 Received: from MD1KR9XC.ww002.siemens.net ([139.25.69.251]) by mail3.siemens.de (8.15.2/8.15.2) with ESMTP id w0CBsiQe029541; Fri, 12 Jan 2018 12:54:44 +0100 From: Christian Storm To: swupdate@googlegroups.com Cc: Christian Storm , Andreas Reichel Subject: [swupdate] [PATCH] bootloader: EFI Boot Guard support Date: Fri, 12 Jan 2018 12:52:12 +0100 Message-Id: <20180112115212.11430-1-christian.storm@siemens.com> X-Mailer: git-send-email 2.15.1 X-Original-Sender: christian.storm@siemens.com X-Original-Authentication-Results: gmr-mx.google.com; spf=pass (google.com: domain of christian.storm@siemens.com designates 192.35.17.28 as permitted sender) smtp.mailfrom=christian.storm@siemens.com Precedence: list Mailing-list: list swupdate@googlegroups.com; contact swupdate+owners@googlegroups.com List-ID: X-Spam-Checked-In-Group: swupdate@googlegroups.com X-Google-Group-Id: 605343134186 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , Add support for EFI Boot Guard to SWUpdate. See: https://github.com/siemens/efibootguard Signed-off-by: Christian Storm Signed-off-by: Andreas Reichel Reviewed-by: Stefano Babic --- Kconfig | 4 ++ Makefile.deps | 4 ++ Makefile.flags | 4 ++ bootloader/Config.in | 11 +++ bootloader/Makefile | 1 + bootloader/ebg.c | 193 +++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 217 insertions(+) create mode 100644 bootloader/ebg.c diff --git a/Kconfig b/Kconfig index e46ff05..4469096 100644 --- a/Kconfig +++ b/Kconfig @@ -37,6 +37,10 @@ config HAVE_LIBUBOOTENV bool option env="HAVE_LIBUBOOTENV" +config HAVE_LIBEBGENV + bool + option env="HAVE_LIBEBGENV" + config HAVE_LIBZEROMQ bool option env="HAVE_LIBZEROMQ" diff --git a/Makefile.deps b/Makefile.deps index d06b42c..1a01ca0 100644 --- a/Makefile.deps +++ b/Makefile.deps @@ -34,6 +34,10 @@ ifeq ($(HAVE_LIBUBOOTENV),) export HAVE_LIBUBOOTENV = y endif +ifeq ($(HAVE_LIBEBGENV),) +export HAVE_LIBEBGENV = y +endif + ifeq ($(HAVE_LIBSSL),) export HAVE_LIBSSL = y endif diff --git a/Makefile.flags b/Makefile.flags index 041a08e..08990a6 100644 --- a/Makefile.flags +++ b/Makefile.flags @@ -179,6 +179,10 @@ ifeq ($(CONFIG_SYSTEMD),y) LDLIBS += systemd endif +ifeq ($(CONFIG_BOOTLOADER_EBG),y) +LDLIBS += ebgenv z +endif + # suricatta ifneq ($(CONFIG_SURICATTA),) ifneq ($(CONFIG_SURICATTA_SSL),) diff --git a/bootloader/Config.in b/bootloader/Config.in index 3b2d73b..9e33dba 100644 --- a/bootloader/Config.in +++ b/bootloader/Config.in @@ -4,6 +4,17 @@ choice help Choose the bootloader +config BOOTLOADER_EBG + bool "EFI Boot Guard" + depends on HAVE_LIBEBGENV + depends on HAVE_ZLIB + help + Support for EFI Boot Guard + https://github.com/siemens/efibootguard + +comment "EFI Boot Guard needs libebgenv and libz" + depends on !HAVE_ZLIB || !HAVE_LIBEBGENV + config UBOOT bool "U-Boot" depends on HAVE_LIBUBOOTENV diff --git a/bootloader/Makefile b/bootloader/Makefile index a652058..1b09048 100644 --- a/bootloader/Makefile +++ b/bootloader/Makefile @@ -1,3 +1,4 @@ lib-$(CONFIG_UBOOT) += uboot.o lib-$(CONFIG_BOOTLOADER_NONE) += none.o lib-$(CONFIG_BOOTLOADER_GRUB) += grub.o +lib-$(CONFIG_BOOTLOADER_EBG) += ebg.o diff --git a/bootloader/ebg.c b/bootloader/ebg.c new file mode 100644 index 0000000..8f40970 --- /dev/null +++ b/bootloader/ebg.c @@ -0,0 +1,193 @@ +/* + * Author: Christian Storm + * Author: Andreas Reichel + * Copyright (C) 2018, Siemens AG + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bootloader.h" + +#ifdef CONFIG_SURICATTA_STATE_CHOICE_BOOTLOADER +#define EXPANDTOKL2(token) token +#define EXPANDTOK(token) EXPANDTOKL2(token) +#define STATE_KEY EXPANDTOK(CONFIG_SURICATTA_STATE_BOOTLOADER) +#else +#define STATE_KEY "none" +#endif + +#define RCS_KEY "recovery_status" +#define RCS_VALUE "in_progress" + +static ebgenv_t ebgenv = {0}; + +int bootloader_env_set(const char *name, const char *value) +{ + int ret; + + errno = 0; + ebg_beverbose(&ebgenv, loglevel > INFOLEVEL ? true : false); + + DEBUG("Setting %s=%s in bootloader environment", name, value); + + if ((ret = ebg_env_open_current(&ebgenv)) != 0) { + ERROR("Cannot open current bootloader environment: %s.", strerror(ret)); + return ret; + } + + if (strncmp(name, RCS_KEY, strlen(name) + 1) == 0 && + strncmp(value, RCS_VALUE, strlen(RCS_VALUE) + 1) == 0) { + /* Open or create a new environment to reflect + * EFI Boot Guard's representation of SWUpdate's + * recovery_status=in_progress. */ + if ((ret = ebg_env_create_new(&ebgenv)) != 0) { + ERROR("Cannot open/create new bootloader environment: %s.", + strerror(ret)); + } + } else if (strncmp(name, (char *)STATE_KEY, strlen((char *)STATE_KEY) + 1) == 0) { + /* Map suricatta's update_state_t to EFI Boot Guard's API. */ + if ((ret = ebg_env_setglobalstate(&ebgenv, *value - '0')) != 0) { + ERROR("Cannot set %s=%s in bootloader environment.", STATE_KEY, value); + } + } else { + /* A new environment is created if EFI Boot Guard's + * representation of SWUpdate's recovery_status is + * not in_progress. */ + if ((ret = ebg_env_create_new(&ebgenv)) != 0) { + ERROR("Cannot open/create new bootloader environment: %s.", + strerror(ret)); + return ret; + } + if ((ret = ebg_env_set(&ebgenv, (char *)name, (char *)value)) != 0) { + ERROR("Cannot set %s=%s in bootloader environment: %s.", + name, value, strerror(ret)); + } + } + (void)ebg_env_close(&ebgenv); + + return ret; +} + +int bootloader_env_unset(const char *name) +{ + int ret; + + ebg_beverbose(&ebgenv, loglevel > INFOLEVEL ? true : false); + + if ((ret = ebg_env_open_current(&ebgenv)) != 0) { + ERROR("Cannot open current bootloader environment: %s.", strerror(ret)); + return ret; + } + + if (strncmp(name, RCS_KEY, strlen(name) + 1) == 0) { + ret = ebg_env_finalize_update(&ebgenv); + if (ret) { + ERROR("Cannot unset %s in bootloader environment: %s.", RCS_KEY, strerror(ret)); + } + } else { + ret = ebg_env_set_ex(&ebgenv, (char *)name, USERVAR_TYPE_DELETED, (uint8_t *)"", 1); + } + (void)ebg_env_close(&ebgenv); + + return ret; +} + +char *bootloader_env_get(const char *name) +{ + char *value = NULL; + size_t size; + + errno = 0; + ebg_beverbose(&ebgenv, loglevel > INFOLEVEL ? true : false); + + int ret; + if ((ret = ebg_env_open_current(&ebgenv)) != 0) { + ERROR("Cannot open current bootloader environment: %s.", + strerror(ret)); + return NULL; + } + + if (strncmp(name, (char *)STATE_KEY, strlen((char *)STATE_KEY) + 1) == 0) { + value = (char *)malloc(sizeof(char)); + *value = ebg_env_getglobalstate(&ebgenv); + } else { + if ((size = ebg_env_get(&ebgenv, (char *)name, NULL)) != 0) { + value = malloc(size); + if (value) { + if (ebg_env_get(&ebgenv, (char *)name, value) != 0) { + value = NULL; + } + } + } + } + + (void)ebg_env_close(&ebgenv); + + if (value == NULL) { + ERROR("Cannot get %s from bootloader environment: %s", + name, strerror(errno)); + } + + /* Map EFI Boot Guard's int return to update_state_t's char value */ + *value = *value + '0'; + return value; +} + +int bootloader_apply_list(const char *filename) +{ + FILE *fp = NULL; + char *line = NULL; + char *key; + char *value; + size_t len = 0; + int ret = 0; + + errno = 0; + ebg_beverbose(&ebgenv, loglevel > INFOLEVEL ? true : false); + + if (!(fp = fopen(filename, "rb"))) { + ERROR("Failed to open bootloader environment file %s: %s", + filename, strerror(errno)); + return -1; + } + + while ((getline(&line, &len, fp)) != -1) { + key = strtok(line, " \t\n"); + value = strtok(NULL, "\t\n"); + if (value != NULL && key != NULL) { + if ((ret = bootloader_env_set(key, value)) != 0) { + break; + } + } + } + + if (fp) { + fclose(fp); + } + if (line) { + free(line); + } + return ret; +}