From patchwork Wed May 12 04:57:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 435450 Delivered-To: patch@linaro.org Received: by 2002:a02:c901:0:0:0:0:0 with SMTP id t1csp4489026jao; Tue, 11 May 2021 21:59:02 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzpoKXd/buLf6e5pLoqbWkO+pJUB3DWhvTRfmUU5FyLYOrAok/Ip4o/adXNiYofACV/BBJU X-Received: by 2002:a05:6402:da:: with SMTP id i26mr4373086edu.379.1620795542019; Tue, 11 May 2021 21:59:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1620795542; cv=none; d=google.com; s=arc-20160816; b=DHauL6/T8fFIZH/DBr4IH6OD06eUJVq+iojqCOc4ZXr/n84FxNVnGNZ2e6F6zeIdjJ sQcpY47dK8Y/YPnUwfLCbFoK4g74GMKGxI2rB4syFcuL0QLLKV5AitX/RTXjvknW08jv wGz0fndVjKSBQSTGW/aoK6m1+J3VipP7hfz1xLX0i9VO7HcyycO0vnOXvLB5YEMOz5tV cRgcEI5huZSXvXQs3AUpRtLixlSasHxE+oNw5wy1ZdPKOSZ2wYitAr0WLLUeT3BMdA1G FQQwt9Me5V2F8IwtJlXRfEkOKMF+ph4YZW2f7Q2c70aAOU0mc59gGfGNdHV84nzOhjnt DdxA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=UQYEX7vW52TUyN2ge2xNNYO6nwda2CZvK4qAzKxmWVM=; b=St3+jiOF5qiWvq8zUo3+a4p0K3WdilxhbUZcdCIMkDSNWBD8AK2Qomrh6YQvglwMtj 6SPRe5/G1qMiSI6OvvK4F5VTp8hNxfEyBGYbhJN5rgiJ0m4Ix9RVjpxsKxrY4u4HIDnX JdGy2Zo7oI6uW+hhZnGTygWzCKnEo1dQoD8WlwQg62ACVWKa0xkG23DeuLXqpXp/qVPY voYej+JmC2tw4zLU/LPInH7zsFe+o1D9hJtwikyh3YluZFL56OaIb7O1gx2NKFyEOtAn fkhgp5Ak+JDRCNqmNwQvVRMP9R48tSqTo6L8ltKv0Jp0eMvv7wUukkNNuXUXWWVMrYgD fPNQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=AJCNXiec; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id mp39si17836041ejc.182.2021.05.11.21.59.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 May 2021 21:59:02 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=AJCNXiec; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id B372482D47; Wed, 12 May 2021 06:58:39 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="AJCNXiec"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id B5AD082D4B; Wed, 12 May 2021 06:58:35 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pf1-x42e.google.com (mail-pf1-x42e.google.com [IPv6:2607:f8b0:4864:20::42e]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id A2A5582AF0 for ; Wed, 12 May 2021 06:58:31 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pf1-x42e.google.com with SMTP id k19so17681130pfu.5 for ; Tue, 11 May 2021 21:58:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UQYEX7vW52TUyN2ge2xNNYO6nwda2CZvK4qAzKxmWVM=; b=AJCNXieceWtEbdvihRVUHKwAThaJL51Db8H3MzlPh4jTf1hT6Dy11ewhVNrl9eSI7n AknqITcMkYzCmgnC1Skx/futKGX3kba8cSIGEBbElBGxZJS0Q+spwvMkz3KsKbd/RTPc d2YAhUsOYfMyAJvX6YB+zQcRgf/LKnScqxlnmzs8sW5bYH7+KsgQ52lGLkkJNLXSTOIF OCV53M81Wzzr1tTDGoEl/TLeSIfYktH+VYXjER1KNo36jMIGBSuasSZ2QjfcWptv/gFG VO8EMiBl3Yghb9rOhDWabvem8TesaXng11nI+K6z+XHb9doKivbwrBv732Ft0qxJ2xKN DZWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UQYEX7vW52TUyN2ge2xNNYO6nwda2CZvK4qAzKxmWVM=; b=IAT/3MKtKHpSiFpyuQs37GcjJKd0vl9PaPCqIE+5t05uaBJHAaCzJAW7i5Uw6iwE4H ZLKtwi6623CPb6mrO2+jv/d4xpH/pmYbsjZvm2lW1zgEep7lQTO2CarrbN+JGPAyv2T2 N0usY2BMK4jMX+3PJ4VM6VEfGMQS4rpRRfyhNMokQQWHvYZB5dgQbQ3funM2f5Physe3 zDj1bJGmCv3W6Opbht5I7ELnQgTWjvRHTZUfH/OC1EfYzIPI43pUzbAxKPmpF88Ta0RK wkvlZrjKMgQ8sLiXXsimCg+5DnVLUF841dcCXjfhRzIhfbrYvUqRPetBK3z9PNPEmgRi 83yQ== X-Gm-Message-State: AOAM532qGMVoxDwDUpiZK2rKY9vDWAKw0EZgJ17Bj1R00d10iubo7rdr vhf4fpSvT4WkBtJWyQYcs36UMQ== X-Received: by 2002:a63:4f50:: with SMTP id p16mr33847860pgl.245.1620795509916; Tue, 11 May 2021 21:58:29 -0700 (PDT) Received: from localhost.localdomain (p3dd30534.tkyea130.ap.so-net.ne.jp. [61.211.5.52]) by smtp.gmail.com with ESMTPSA id q194sm15188202pfc.62.2021.05.11.21.58.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 May 2021 21:58:29 -0700 (PDT) From: AKASHI Takahiro To: xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, masami.hiramatsu@linaro.org, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH 3/4] tools: add fdtsig command Date: Wed, 12 May 2021 13:57:52 +0900 Message-Id: <20210512045753.62288-4-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.31.0 In-Reply-To: <20210512045753.62288-1-takahiro.akashi@linaro.org> References: <20210512045753.62288-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.4 at phobos.denx.de X-Virus-Status: Clean This command allows us to add a certificate (or public key) to dtb blob: { signature { capsule-key = "..."; }; } The value is actually a signature list in terms of UEFI specificaion, and used in verifying UEFI capsules. The code was originally developed by Sughosh and derived from mkeficapsule.c. Signed-off-by: AKASHI Takahiro --- Makefile | 2 +- tools/Makefile | 2 + tools/fdtsig.c | 274 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 tools/fdtsig.c -- 2.31.0 diff --git a/Makefile b/Makefile index 9806464357e0..8b40987234a0 100644 --- a/Makefile +++ b/Makefile @@ -1016,7 +1016,7 @@ quiet_cmd_lzma = LZMA $@ cmd_lzma = lzma -c -z -k -9 $< > $@ quiet_cmd_fdtsig = FDTSIG $@ -cmd_fdtsig = $(srctree)/tools/fdtsig.sh $(CONFIG_EFI_PKEY_FILE) $@ +cmd_fdtsig = $(objtree)/tools/fdtsig -K $(CONFIG_EFI_PKEY_FILE) -D $@ cfg: u-boot.cfg diff --git a/tools/Makefile b/tools/Makefile index 71a52719620c..e6fd1dbade19 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -234,6 +234,8 @@ HOSTCFLAGS_asn1_compiler.o = -idirafter $(srctree)/include ifneq ($(CONFIG_EFI_CAPSULE_AUTHENTICATE),) HOSTLDLIBS_mkeficapsule += \ $(shell pkg-config --libs libssl libcrypto 2> /dev/null || echo "-lssl -lcrypto") + fdtsig-objs := fdtsig.o $(LIBFDT_OBJS) + hostprogs-y += fdtsig endif hostprogs-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += mkeficapsule diff --git a/tools/fdtsig.c b/tools/fdtsig.c new file mode 100644 index 000000000000..daa1e63c3b33 --- /dev/null +++ b/tools/fdtsig.c @@ -0,0 +1,274 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2021 Linaro Limited + * The code in this file was extracted from mkeficapsule.c + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define SIGNATURE_NODENAME "signature" +#define OVERLAY_NODENAME "__overlay__" + +static const char *tool_name = "fdtsig"; + +static const char *opts_short = "D:K:Oh"; + +static struct option options[] = { + {"dtb", required_argument, NULL, 'D'}, + {"public key", required_argument, NULL, 'K'}, + {"overlay", no_argument, NULL, 'O'}, + {"help", no_argument, NULL, 'h'}, + {NULL, 0, NULL, 0}, +}; + +static void print_usage(void) +{ + printf("Usage: %s [options]\n" + "Options:\n" + + "\t-K, --public-key public key esl file\n" + "\t-D, --dtb dtb file\n" + "\t-O, --overlay the dtb file is an overlay\n" + "\t-h, --help print a help message\n", + tool_name); +} + +static int fdt_add_pub_key_data(void *sptr, void *dptr, size_t key_size, + bool overlay) +{ + int parent; + int ov_node; + int frag_node; + int ret = 0; + + if (overlay) { + /* + * The signature would be stored in the + * first fragment node of the overlay + */ + frag_node = fdt_first_subnode(dptr, 0); + if (frag_node == -FDT_ERR_NOTFOUND) { + fprintf(stderr, + "Couldn't find the fragment node: %s\n", + fdt_strerror(frag_node)); + goto done; + } + + ov_node = fdt_subnode_offset(dptr, frag_node, OVERLAY_NODENAME); + if (ov_node == -FDT_ERR_NOTFOUND) { + fprintf(stderr, + "Couldn't find the __overlay__ node: %s\n", + fdt_strerror(ov_node)); + goto done; + } + } else { + ov_node = 0; + } + + parent = fdt_subnode_offset(dptr, ov_node, SIGNATURE_NODENAME); + if (parent == -FDT_ERR_NOTFOUND) { + parent = fdt_add_subnode(dptr, ov_node, SIGNATURE_NODENAME); + if (parent < 0) { + ret = parent; + if (ret != -FDT_ERR_NOSPACE) { + fprintf(stderr, + "Couldn't create signature node: %s\n", + fdt_strerror(parent)); + } + } + } + if (ret) + goto done; + + /* Write the key to the FDT node */ + ret = fdt_setprop(dptr, parent, "capsule-key", + sptr, key_size); + +done: + if (ret) + ret = ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO; + + return ret; +} + +static int add_public_key(const char *pkey_file, const char *dtb_file, + bool overlay) +{ + int ret; + int srcfd = -1; + int destfd = -1; + void *sptr = NULL; + void *dptr = NULL; + off_t src_size; + struct stat pub_key; + struct stat dtb; + + /* Find out the size of the public key */ + srcfd = open(pkey_file, O_RDONLY); + if (srcfd == -1) { + fprintf(stderr, "%s: Can't open %s: %s\n", + __func__, pkey_file, strerror(errno)); + ret = -1; + goto err; + } + + ret = fstat(srcfd, &pub_key); + if (ret == -1) { + fprintf(stderr, "%s: Can't stat %s: %s\n", + __func__, pkey_file, strerror(errno)); + ret = -1; + goto err; + } + + src_size = pub_key.st_size; + + /* mmap the public key esl file */ + sptr = mmap(0, src_size, PROT_READ, MAP_SHARED, srcfd, 0); + if (sptr == MAP_FAILED) { + fprintf(stderr, "%s: Failed to mmap %s:%s\n", + __func__, pkey_file, strerror(errno)); + ret = -1; + goto err; + } + + /* Open the dest FDT */ + destfd = open(dtb_file, O_RDWR); + if (destfd == -1) { + fprintf(stderr, "%s: Can't open %s: %s\n", + __func__, dtb_file, strerror(errno)); + ret = -1; + goto err; + } + + ret = fstat(destfd, &dtb); + if (ret == -1) { + fprintf(stderr, "%s: Can't stat %s: %s\n", + __func__, dtb_file, strerror(errno)); + goto err; + } + + dtb.st_size += src_size + 0x30; + if (ftruncate(destfd, dtb.st_size)) { + fprintf(stderr, "%s: Can't expand %s: %s\n", + __func__, dtb_file, strerror(errno)); + ret = -1; + goto err; + } + + errno = 0; + /* mmap the dtb file */ + dptr = mmap(0, dtb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, + destfd, 0); + if (dptr == MAP_FAILED) { + fprintf(stderr, "%s: Failed to mmap %s:%s\n", + __func__, dtb_file, strerror(errno)); + ret = -1; + goto err; + } + + if (fdt_check_header(dptr)) { + fprintf(stderr, "%s: Invalid FDT header\n", __func__); + ret = -1; + goto err; + } + + ret = fdt_open_into(dptr, dptr, dtb.st_size); + if (ret) { + fprintf(stderr, "%s: Cannot expand FDT: %s\n", + __func__, fdt_strerror(ret)); + ret = -1; + goto err; + } + + /* Copy the esl file to the expanded FDT */ + ret = fdt_add_pub_key_data(sptr, dptr, src_size, overlay); + if (ret < 0) { + fprintf(stderr, "%s: Unable to add public key to the FDT\n", + __func__); + ret = -1; + goto err; + } + + ret = 0; + +err: + if (sptr) + munmap(sptr, src_size); + + if (dptr) + munmap(dptr, dtb.st_size); + + if (srcfd != -1) + close(srcfd); + + if (destfd != -1) + close(destfd); + + return ret; +} + +int main(int argc, char **argv) +{ + char *pkey_file; + char *dtb_file; + bool overlay; + int c, idx, ret; + + pkey_file = NULL; + dtb_file = NULL; + overlay = false; + + for (;;) { + c = getopt_long(argc, argv, opts_short, options, &idx); + if (c == -1) + break; + + switch (c) { + case 'K': + if (pkey_file) { + printf("Public Key already specified\n"); + return -1; + } + pkey_file = optarg; + break; + case 'D': + if (dtb_file) { + printf("DTB file already specified\n"); + return -1; + } + dtb_file = optarg; + break; + case 'O': + overlay = true; + break; + case 'h': + print_usage(); + return 0; + } + } + + /* check necessary parameters */ + if (!pkey_file || !dtb_file) { + print_usage(); + exit(EXIT_FAILURE); + } + + ret = add_public_key(pkey_file, dtb_file, overlay); + if (ret == -1) { + printf("Adding public key to the dtb failed\n"); + exit(EXIT_FAILURE); + } + + exit(EXIT_SUCCESS); +}