From patchwork Fri Nov 12 19:28:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1554550 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=Qv/+URp5; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HrTCx2456z9s0r for ; Sat, 13 Nov 2021 06:29:01 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 5F6298303D; Fri, 12 Nov 2021 20:28:56 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="Qv/+URp5"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 169BC83036; Fri, 12 Nov 2021 20:28:54 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-oi1-x230.google.com (mail-oi1-x230.google.com [IPv6:2607:f8b0:4864:20::230]) (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 1A32982F5A for ; Fri, 12 Nov 2021 20:28:50 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-oi1-x230.google.com with SMTP id r26so19769889oiw.5 for ; Fri, 12 Nov 2021 11:28:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=hakeC/iQ8yPrSkjgQmhBvpdcEx3qDWS+u73FaWsTs0Y=; b=Qv/+URp52mBWo0l7xOBiUmNDxKd2eMHikzU83CryfdF5OKThJ7jH63PE5hGOMD5t/V t1iZp394ZfuS4y3X62rjX2BzN0duci77PMDSHhogFytBhXdPWG9/e/5O80G3V0KFbvn8 Ward1AlERhBJMW3m039ClP1+6bRAJfv2Ttw6M= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=hakeC/iQ8yPrSkjgQmhBvpdcEx3qDWS+u73FaWsTs0Y=; b=FQLlIsRweLiUqABPjsJcnZMyEfYIh9Z67+GBdnTZ4LZaRlLtSNu4PYCAk3OWd34FR/ WS3Vgnyb0yynLbeP/KMHAJWvTVXlbTgyCoNcZ/OnXTliHhy/PUXam3M5P/LBFeS+r/mQ sWONvZ0JLvj0XhZPkgKAuC+zgT4Zn+Oe53CMvpHIXuqMDOFEgyeevX1c96HTuAj8V/sF gcSKGCxonFdIpEovVMsuQrjytS6Jzv3nldb/idhw+g/2RxzpPRS6dZ2YpbkEhAM2QRD5 H2ycWUsoYYICxWngGlJXi/gw0VCvVyv4nmDvvSFxzTZ46zcY6aYQOBrx4TpJfySy2ooU o2jw== X-Gm-Message-State: AOAM531aVIbFD9DoQaU1edrndDIqKQqwR+09JZiamc3mCdT1/gGP2XDh BAREA4WlIoAEPEzxK+pWjY8Ezmat8XA3sw== X-Google-Smtp-Source: ABdhPJz9GGCexVFN0s1l8ndOUxYLheIOJixTqOkkdx0rFw6MjdcIRy6/rpt8JiySAG/s/X1Lj316uQ== X-Received: by 2002:a05:6808:1482:: with SMTP id e2mr6705982oiw.45.1636745328502; Fri, 12 Nov 2021 11:28:48 -0800 (PST) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id n20sm1283527ooe.7.2021.11.12.11.28.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Nov 2021 11:28:48 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Rob Herring , Tom Rini , Bill Mills , Simon Glass , Alexandru Gagniuc , Philippe Reynes , Sean Anderson , Thomas Perrot Subject: [PATCH 01/16] rsa: Add debugging for failure cases Date: Fri, 12 Nov 2021 12:28:02 -0700 Message-Id: <20211112192817.199075-2-sjg@chromium.org> X-Mailer: git-send-email 2.34.0.rc1.387.gb447b232ab-goog In-Reply-To: <20211112192817.199075-1-sjg@chromium.org> References: <20211112192817.199075-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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.103.2 at phobos.denx.de X-Virus-Status: Clean Add some more debugging to make it easier to see what is being tried and what fails. Fix a few comment styles while here. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- lib/rsa/rsa-verify.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index 83f7564101c..26ee256cf4c 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -79,14 +79,14 @@ int padding_pkcs_15_verify(struct image_sign_info *info, struct checksum_algo *checksum = info->checksum; int ret, pad_len = msg_len - checksum->checksum_len; - /* Check pkcs1.5 padding bytes. */ + /* Check pkcs1.5 padding bytes */ ret = rsa_verify_padding(msg, pad_len, checksum); if (ret) { debug("In RSAVerify(): Padding check failed!\n"); return -EINVAL; } - /* Check hash. */ + /* Check hash */ if (memcmp((uint8_t *)msg + pad_len, hash, msg_len - pad_len)) { debug("In RSAVerify(): Hash check failed!\n"); return -EACCES; @@ -502,7 +502,8 @@ int rsa_verify_hash(struct image_sign_info *info, if (CONFIG_IS_ENABLED(RSA_VERIFY_WITH_PKEY) && !info->fdt_blob) { /* don't rely on fdt properties */ ret = rsa_verify_with_pkey(info, hash, sig, sig_len); - + if (ret) + debug("%s: rsa_verify_with_pkey() failed\n", __func__); return ret; } @@ -522,6 +523,9 @@ int rsa_verify_hash(struct image_sign_info *info, if (info->required_keynode != -1) { ret = rsa_verify_with_keynode(info, hash, sig, sig_len, info->required_keynode); + if (ret) + debug("%s: Failed to verify required_keynode\n", + __func__); return ret; } @@ -531,6 +535,8 @@ int rsa_verify_hash(struct image_sign_info *info, ret = rsa_verify_with_keynode(info, hash, sig, sig_len, node); if (!ret) return ret; + debug("%s: Could not verify key '%s', trying all\n", __func__, + name); /* No luck, so try each of the keys in turn */ for (ndepth = 0, noffset = fdt_next_node(blob, sig_node, @@ -546,6 +552,7 @@ int rsa_verify_hash(struct image_sign_info *info, } } } + debug("%s: Failed to verify by any means\n", __func__); return ret; } From patchwork Fri Nov 12 19:28:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1554551 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=UTzfn1V5; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HrTDC4gZDz9s0r for ; Sat, 13 Nov 2021 06:29:15 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 87D148306D; Fri, 12 Nov 2021 20:29:03 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="UTzfn1V5"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 27C7D83036; Fri, 12 Nov 2021 20:28:55 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-oi1-x233.google.com (mail-oi1-x233.google.com [IPv6:2607:f8b0:4864:20::233]) (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 1204582FEA for ; Fri, 12 Nov 2021 20:28:51 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-oi1-x233.google.com with SMTP id n66so19703059oia.9 for ; Fri, 12 Nov 2021 11:28:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=eN/iMcTkhVcph0teSsIekhExe4ZgIDw5UeO5syPQfh8=; b=UTzfn1V5eBiPdW3BstndZoRsJQPXqzyGmdjWzrW32PpCMMyzO48PD9AZW1v0yAupFe ljtv6h5H/9l/9TugdYI2KAltc9yo01ZvmSjmioS8fyom6uOVPpbdWMtCun5rYDDr5fZj u5Cj5KY31vTvR8mn2EW+I8xTEbYm9deJsbF68= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eN/iMcTkhVcph0teSsIekhExe4ZgIDw5UeO5syPQfh8=; b=W9/dxRtSmCmrf7oc9MNAc3lnWCFxVmBiWxQKvAUkzTinzKwIsUfOg4ztsxVyXITHdK OrVmdcYKK03oZzC0ZrspIn3DfpsH91Ef7HI74pq0M39/4Z/Ux4aPNV8zn2wePqpTjEnA ifupF/ioO1g7/4auTgqIbSNJdU04y5pjbGEVf2P9LOJUCwZh9Hq+JromNqSXytiwqGHY WHlSh8cbAfq/gPdqE4s7GO9uL3P7PoYtYkajGMAFjPa4hpR+C60OMVq8CyTV6JsOI946 yGHa3wGARz7FLnM7KE+RG6ufYFm0cdLJ8iACGct7uKUJVODnGmHAc4eCpyb144nJGHKz VzMA== X-Gm-Message-State: AOAM531p2KuKM89xGBlr4NwMfETLa23OoHGCD6cHd7Yyy7GnDtzF+ScE V+DH0tQBkvWCXVYCL7/xymkirvHd+BXDxA== X-Google-Smtp-Source: ABdhPJxiDrWXYafOc09PDSOqRD/p5LvHBGrOXB/0TUFArilqzDBV4GVqEzpfPa48zEfGw0oBFfibhg== X-Received: by 2002:a05:6808:11c9:: with SMTP id p9mr27696064oiv.169.1636745329474; Fri, 12 Nov 2021 11:28:49 -0800 (PST) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id n20sm1283527ooe.7.2021.11.12.11.28.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Nov 2021 11:28:49 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Rob Herring , Tom Rini , Bill Mills , Simon Glass , Ilies CHERGUI Subject: [PATCH 02/16] fit_check_sign: Update help to mention the key is in a dtb Date: Fri, 12 Nov 2021 12:28:03 -0700 Message-Id: <20211112192817.199075-3-sjg@chromium.org> X-Mailer: git-send-email 2.34.0.rc1.387.gb447b232ab-goog In-Reply-To: <20211112192817.199075-1-sjg@chromium.org> References: <20211112192817.199075-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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.103.2 at phobos.denx.de X-Virus-Status: Clean The key is inside a dtb file, so tweak the help to make that clear. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- tools/fit_check_sign.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/fit_check_sign.c b/tools/fit_check_sign.c index 5573842d251..3d1d33fdab1 100644 --- a/tools/fit_check_sign.c +++ b/tools/fit_check_sign.c @@ -27,7 +27,7 @@ void usage(char *cmdname) { fprintf(stderr, "Usage: %s -f fit file -k key file -c config name\n" " -f ==> set fit file which should be checked'\n" - " -k ==> set key file which contains the key'\n" + " -k ==> set key .dtb file which contains the key'\n" " -c ==> set the configuration name'\n", cmdname); exit(EXIT_FAILURE); @@ -89,7 +89,7 @@ int main(int argc, char **argv) fprintf(stderr, "Signature check OK\n"); } else { ret = EXIT_FAILURE; - fprintf(stderr, "Signature check Bad (error %d)\n", ret); + fprintf(stderr, "Signature check bad (error %d)\n", ret); } (void) munmap((void *)fit_blob, fsbuf.st_size); From patchwork Fri Nov 12 19:28:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1554552 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=XzZQQxU2; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HrTDP1MxWz9s0r for ; Sat, 13 Nov 2021 06:29:25 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id BBA3F83085; Fri, 12 Nov 2021 20:29:09 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="XzZQQxU2"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id A29638304F; Fri, 12 Nov 2021 20:28:58 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-oi1-x235.google.com (mail-oi1-x235.google.com [IPv6:2607:f8b0:4864:20::235]) (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 0674C83023 for ; Fri, 12 Nov 2021 20:28:52 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-oi1-x235.google.com with SMTP id q25so14190866oiw.0 for ; Fri, 12 Nov 2021 11:28:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=44h2GXpouUQV8c5lndx9hcMynUT5IEkCj/2OoQ15azM=; b=XzZQQxU2GNsHTCyvQ2/NSxna3i5m/MOJcx1KYpTenry/Zywkcj3NMi3ebD3CXmFDmW V6mQ5tcldQCcut1VNZxQMcf8tMPx7kn2Ui6SjTwrYYj7WlNXiQIL2ekTzXBJLntXywKw gx2N8+nsZT1vwUi/dGGiSNCJGsJzSik9OrceM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=44h2GXpouUQV8c5lndx9hcMynUT5IEkCj/2OoQ15azM=; b=mrI5o9d2w3WV73l6EqT3ZCgrzmgPBhlTtYK0q5G0kj8O4rM5Xnw8dXxZ6//2QbxPgC sw4OMe7SkhrpN0FOvI1k4V9adznLUwQuwvyZkDR53zQ3nmOqrR2kKp4W12zodJ2212lF AMOQCN0jzdcmIEAqedMsXMAyevPFaQDlPJn70bcXtu3qwpsXfZ89B1bWL+jKIV+DFjqd HC1SEfsT+MKS5h/9XG7ALGq3uQMJpLFBiBp7F1KYyEUHwsrsJt5LuDSYxyeVIC7sk0x+ SKwpd+nWH4aShBQiKjQrfLwyDJt36mrNtiQfUlb8R96szpmnTL1f7YlnZVVFpesaQ2Su iDPw== X-Gm-Message-State: AOAM532bo46WFxjn2S36cuWL7G8gwQXsqYZU433/+lBaom4TH45nc7Z0 6lIU/r1YEyfJ2R9CYOS7UmncwB5pzxFmPQ== X-Google-Smtp-Source: ABdhPJwlimKwtPS+JaJc71rV2Q+7sz9dCz7B6H2WjqaxPQnJvf8UbOrI280CITtIO5324fLnaUguRw== X-Received: by 2002:a05:6808:f08:: with SMTP id m8mr9871545oiw.5.1636745330483; Fri, 12 Nov 2021 11:28:50 -0800 (PST) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id n20sm1283527ooe.7.2021.11.12.11.28.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Nov 2021 11:28:50 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Rob Herring , Tom Rini , Bill Mills , Simon Glass , Alexandru Gagniuc , Sven Roederer Subject: [PATCH 03/16] tools: Move copyfile() into a common file Date: Fri, 12 Nov 2021 12:28:04 -0700 Message-Id: <20211112192817.199075-4-sjg@chromium.org> X-Mailer: git-send-email 2.34.0.rc1.387.gb447b232ab-goog In-Reply-To: <20211112192817.199075-1-sjg@chromium.org> References: <20211112192817.199075-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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.103.2 at phobos.denx.de X-Virus-Status: Clean This function is useful in other places. Move it to a common file. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- tools/fit_common.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ tools/fit_common.h | 11 +++++++++ tools/fit_image.c | 56 ---------------------------------------------- 3 files changed, 67 insertions(+), 56 deletions(-) diff --git a/tools/fit_common.c b/tools/fit_common.c index 52b63296f89..c161f23b0f7 100644 --- a/tools/fit_common.c +++ b/tools/fit_common.c @@ -111,3 +111,59 @@ err: return -1; } + +int copyfile(const char *src, const char *dst) +{ + int fd_src = -1, fd_dst = -1; + void *buf = NULL; + ssize_t size; + size_t count; + int ret = -1; + + fd_src = open(src, O_RDONLY); + if (fd_src < 0) { + printf("Can't open file %s (%s)\n", src, strerror(errno)); + goto out; + } + + fd_dst = open(dst, O_WRONLY | O_CREAT, 0666); + if (fd_dst < 0) { + printf("Can't open file %s (%s)\n", dst, strerror(errno)); + goto out; + } + + buf = calloc(1, 512); + if (!buf) { + printf("Can't allocate buffer to copy file\n"); + goto out; + } + + while (1) { + size = read(fd_src, buf, 512); + if (size < 0) { + printf("Can't read file %s\n", src); + goto out; + } + if (!size) + break; + + count = size; + size = write(fd_dst, buf, count); + if (size < 0) { + printf("Can't write file %s\n", dst); + goto out; + } + } + + ret = 0; + + out: + if (fd_src >= 0) + close(fd_src); + if (fd_dst >= 0) + close(fd_dst); + if (buf) + free(buf); + + return ret; +} diff --git a/tools/fit_common.h b/tools/fit_common.h index 1e81d4c68b6..a76c4001c59 100644 --- a/tools/fit_common.h +++ b/tools/fit_common.h @@ -39,4 +39,15 @@ int mmap_fdt(const char *cmdname, const char *fname, size_t size_inc, void **blobp, struct stat *sbuf, bool delete_on_error, bool read_only); +/** + * copyfile() - Copy a file + * + * This uses read()/write() to copy file @src to file @dst + * + * @src: Filename to read from + * @dst: Filename to write to + * @return 0 if OK, -1 on error + */ +int copyfile(const char *src, const char *dst); + #endif /* _FIT_COMMON_H_ */ diff --git a/tools/fit_image.c b/tools/fit_image.c index f4f372ba62f..c4f56bb6967 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -654,62 +654,6 @@ err: return ret; } -static int copyfile(const char *src, const char *dst) -{ - int fd_src = -1, fd_dst = -1; - void *buf = NULL; - ssize_t size; - size_t count; - int ret = -1; - - fd_src = open(src, O_RDONLY); - if (fd_src < 0) { - printf("Can't open file %s (%s)\n", src, strerror(errno)); - goto out; - } - - fd_dst = open(dst, O_WRONLY | O_CREAT, 0666); - if (fd_dst < 0) { - printf("Can't open file %s (%s)\n", dst, strerror(errno)); - goto out; - } - - buf = calloc(1, 512); - if (!buf) { - printf("Can't allocate buffer to copy file\n"); - goto out; - } - - while (1) { - size = read(fd_src, buf, 512); - if (size < 0) { - printf("Can't read file %s\n", src); - goto out; - } - if (!size) - break; - - count = size; - size = write(fd_dst, buf, count); - if (size < 0) { - printf("Can't write file %s\n", dst); - goto out; - } - } - - ret = 0; - - out: - if (fd_src >= 0) - close(fd_src); - if (fd_dst >= 0) - close(fd_dst); - if (buf) - free(buf); - - return ret; -} - /** * fit_handle_file - main FIT file processing function * From patchwork Fri Nov 12 19:28:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1554556 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=WS5TPGcT; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HrTDr33mkz9s0r for ; Sat, 13 Nov 2021 06:29:48 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 75FB18303F; Fri, 12 Nov 2021 20:29:22 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="WS5TPGcT"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id DF62483023; Fri, 12 Nov 2021 20:28:59 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-oi1-x22c.google.com (mail-oi1-x22c.google.com [IPv6:2607:f8b0:4864:20::22c]) (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 EACFB8302B for ; Fri, 12 Nov 2021 20:28:52 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-oi1-x22c.google.com with SMTP id r26so19770050oiw.5 for ; Fri, 12 Nov 2021 11:28:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QdtAIGbtjtG8j5k1ppokYR5vYwYwDyoEdB33xmkC/UA=; b=WS5TPGcTYj91lg8HtnlNRNOITaLjbsXRudLcxWQWK09UGy8rAFDXA5r0E01aJ2iFSQ e3Hx178ZM5tyGUWrblx+gaMyN4Tyuep92sqkH59ZGrjhk7GXnGdiC3EDTVCRcFjOaM2i rYLnkNENi1jVeg6tcwYnonSmgMcF+PqjxfXnI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=QdtAIGbtjtG8j5k1ppokYR5vYwYwDyoEdB33xmkC/UA=; b=eAQR0dxmpBQl/8mBmNMEcJi+amXwafYuap016YLKAESb4Pt7DcZQ/GvAIy8d7UZADO az2xmwX5y9LzAHBPbQXSsoL2LwpjojNsfbSI1ihiDfEBqFsORXZC0dx3rZKNwC2tX267 H7mhcM24CmtiDhdnTk6nHLdvWtuPOIN+EZLQ/F8y6cqctwmh8/Rsg1qLG86R8iOVoqBw g352kufNnyBri6byD0TxvFr8cHv3mrghTJFEaFySWTnAQ565WKCxRejrGHbHOa8WECrh YzRHEypTYrBTqsj+BhV5Spjp6NwuGSxtx4cZyVXsVcOwjtXJ7REeDtmJZhFIvbtzKQx2 Mfng== X-Gm-Message-State: AOAM530h+hMOqO76ICJEU+Q2O06lRrKHgwwOSfvowRNifapYJvvhkRFd x/8PRcSCraqC2QGN5QoDRDAK/xIdp00PjA== X-Google-Smtp-Source: ABdhPJywsBXjrhYQl0pnHnUjMsQMsZzR+FXTAV+KSlwHpJCEoxVqftEfCULArzL4gHrYbKLGEF/z2Q== X-Received: by 2002:a05:6808:1294:: with SMTP id a20mr15561440oiw.138.1636745331421; Fri, 12 Nov 2021 11:28:51 -0800 (PST) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id n20sm1283527ooe.7.2021.11.12.11.28.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Nov 2021 11:28:51 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Rob Herring , Tom Rini , Bill Mills , Simon Glass Subject: [PATCH 04/16] tools: Avoid leaving extra data at the end of copied files Date: Fri, 12 Nov 2021 12:28:05 -0700 Message-Id: <20211112192817.199075-5-sjg@chromium.org> X-Mailer: git-send-email 2.34.0.rc1.387.gb447b232ab-goog In-Reply-To: <20211112192817.199075-1-sjg@chromium.org> References: <20211112192817.199075-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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.103.2 at phobos.denx.de X-Virus-Status: Clean The copyfile() implementation has strange behaviour if the destination file already exists. Update it to ensure that any existing data in the destination file is dropped. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- tools/fit_common.c | 2 +- tools/fit_common.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/fit_common.c b/tools/fit_common.c index c161f23b0f7..d13e5ebf1ae 100644 --- a/tools/fit_common.c +++ b/tools/fit_common.c @@ -126,7 +126,7 @@ int copyfile(const char *src, const char *dst) goto out; } - fd_dst = open(dst, O_WRONLY | O_CREAT, 0666); + fd_dst = open(dst, O_WRONLY | O_CREAT | O_TRUNC, 0666); if (fd_dst < 0) { printf("Can't open file %s (%s)\n", dst, strerror(errno)); goto out; diff --git a/tools/fit_common.h b/tools/fit_common.h index a76c4001c59..55f3f6acd4e 100644 --- a/tools/fit_common.h +++ b/tools/fit_common.h @@ -44,6 +44,8 @@ int mmap_fdt(const char *cmdname, const char *fname, size_t size_inc, * * This uses read()/write() to copy file @src to file @dst * + * If @dst exists, it is overwritten and truncated to the correct size. + * * @src: Filename to read from * @dst: Filename to write to * @return 0 if OK, -1 on error From patchwork Fri Nov 12 19:28:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1554557 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=L3rFgPl+; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HrTF4384Sz9s0r for ; Sat, 13 Nov 2021 06:30:00 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id B8D7483077; Fri, 12 Nov 2021 20:29:25 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="L3rFgPl+"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 96D2F8304F; Fri, 12 Nov 2021 20:29:00 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS,T_FILL_THIS_FORM_SHORT autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-oi1-x230.google.com (mail-oi1-x230.google.com [IPv6:2607:f8b0:4864:20::230]) (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 2436582F5A for ; Fri, 12 Nov 2021 20:28:54 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-oi1-x230.google.com with SMTP id be32so19710951oib.11 for ; Fri, 12 Nov 2021 11:28:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=FzIGy1fCsN9E+J9P3yVC6qMya/GGPL6WqTLe5wk38vA=; b=L3rFgPl+Grnn8hV7wTfM/pM+asV/QszMqEVKh+gXQrjXAJUUCuMHEOpbhfDb4EKW10 yFGosTYpOxjJab+rv88v3omL+qJ2U2IsAACeOleP9JK0kzgWlFvtpWicS+CFB/ABLbsL P3UNPKG7CyGgBjgOKhMpxwshZyvdQl2kNL7m8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=FzIGy1fCsN9E+J9P3yVC6qMya/GGPL6WqTLe5wk38vA=; b=iTxoHQH+UPqZHvw1lttaCA5via8Yc/rIUStPi2JGqVZ53UGQw2CUmtpSYT2igEw0mP XCWGvCS8hxhe7pnTy6zymzFyiaTQoQ30WErRC+FWhiwioAB6tWmX94Rf7ruU+CjKe9iU nQPdEuA9UyvnXiik2D5ycOpyXwB7jplav6P4V+RXWcsJkv7CHF9IAcVaEAZGV1Oyr4wQ J3m/890fUqe5wJZGA+lAdRdlLwNTV8hl9DqOrcOp8b/7vk4aQg5pwSuR7vLqS+Moxt4u VnAyumvvMN+BKhrE1Rk6ekaaKSO0mqycVNTeoHXh0bR49y6jvxw2t8EjI5AJSe0z/lmm ryqA== X-Gm-Message-State: AOAM531K80viyXDPHyXBgGAi/zVKZPLMGPVpU19KPqyDu35GBVeC8fhT u+h7FiuKfe4yvj3fjbTRpuD6DgI+4bWZBg== X-Google-Smtp-Source: ABdhPJx2vibZydKmRzp0dmYb3McEJeTeIfwEbY/owobXTE8TEv8IK7csQCoF8Aly1HDQRuQyZP0rfA== X-Received: by 2002:a05:6808:1a90:: with SMTP id bm16mr6634289oib.133.1636745332485; Fri, 12 Nov 2021 11:28:52 -0800 (PST) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id n20sm1283527ooe.7.2021.11.12.11.28.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Nov 2021 11:28:52 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Rob Herring , Tom Rini , Bill Mills , Simon Glass , Alexandru Gagniuc , Ming Liu , Philippe Reynes , Vagrant Cascadian Subject: [PATCH 05/16] tools: Improve comments in signing functions Date: Fri, 12 Nov 2021 12:28:06 -0700 Message-Id: <20211112192817.199075-6-sjg@chromium.org> X-Mailer: git-send-email 2.34.0.rc1.387.gb447b232ab-goog In-Reply-To: <20211112192817.199075-1-sjg@chromium.org> References: <20211112192817.199075-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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.103.2 at phobos.denx.de X-Virus-Status: Clean Add some more comments to explain what is going on in the signing functions. Fix two repeated typos. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- include/image.h | 2 +- tools/fdt_host.h | 8 ++++ tools/image-host.c | 98 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 85 insertions(+), 23 deletions(-) diff --git a/include/image.h b/include/image.h index fd662e74b41..533c23e2002 100644 --- a/include/image.h +++ b/include/image.h @@ -1025,7 +1025,7 @@ int fit_cipher_data(const char *keydir, void *keydest, void *fit, * fit_add_verification_data() - add verification data to FIT image nodes * * @keydir: Directory containing keys - * @kwydest: FDT blob to write public key information to + * @kwydest: FDT blob to write public key information to (NULL if none) * @fit: Pointer to the FIT format image header * @comment: Comment to add to signature nodes * @require_keys: Mark all keys as 'required' diff --git a/tools/fdt_host.h b/tools/fdt_host.h index 15c07c7a96e..bc42306c9e5 100644 --- a/tools/fdt_host.h +++ b/tools/fdt_host.h @@ -27,6 +27,14 @@ */ int fdt_remove_unused_strings(const void *old, void *new); +/** + * fit_check_sign() - Check a signature in a FIT + * + * @fit: FIT to check + * @key: Key FDT blob to check against + * @fit_uname_config: Name of configuration to check (NULL for default) + * @return 0 if OK, -ve if signature failed + */ int fit_check_sign(const void *fit, const void *key, const char *fit_uname_config); diff --git a/tools/image-host.c b/tools/image-host.c index a6b0a944205..73d35f3eee3 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -48,10 +48,10 @@ static int fit_set_hash_value(void *fit, int noffset, uint8_t *value, * fit_image_process_hash - Process a single subnode of the images/ node * * Check each subnode and process accordingly. For hash nodes we generate - * a hash of the supplised data and store it in the node. + * a hash of the supplied data and store it in the node. * * @fit: pointer to the FIT format image header - * @image_name: name of image being processes (used to display errors) + * @image_name: name of image being processed (used to display errors) * @noffset: subnode offset * @data: data to process * @size: size of data in bytes @@ -197,12 +197,12 @@ static int fit_image_setup_sig(struct image_sign_info *info, * fit_image_process_sig- Process a single subnode of the images/ node * * Check each subnode and process accordingly. For signature nodes we - * generate a signed hash of the supplised data and store it in the node. + * generate a signed hash of the supplied data and store it in the node. * * @keydir: Directory containing keys to use for signing - * @keydest: Destination FDT blob to write public keys into + * @keydest: Destination FDT blob to write public keys into (NULL if none) * @fit: pointer to the FIT format image header - * @image_name: name of image being processes (used to display errors) + * @image_name: name of image being processed (used to display errors) * @noffset: subnode offset * @data: data to process * @size: size of data in bytes @@ -685,14 +685,14 @@ static int strlist_add(struct strlist *list, const char *str) return 0; } -static const char *fit_config_get_image_list(void *fit, int noffset, - int *lenp, int *allow_missingp) +static const char *fit_config_get_image_list(const void *fit, int noffset, + int *lenp, int *allow_missingp) { static const char default_list[] = FIT_KERNEL_PROP "\0" FIT_FDT_PROP; const char *prop; - /* If there is an "image" property, use that */ + /* If there is an "sign-image" property, use that */ prop = fdt_getprop(fit, noffset, "sign-images", lenp); if (prop) { *allow_missingp = 0; @@ -706,8 +706,24 @@ static const char *fit_config_get_image_list(void *fit, int noffset, return default_list; } -static int fit_config_add_hash(void *fit, const char *conf_name, const char *sig_name, - struct strlist *node_inc, const char *iname, int image_noffset) +/** + * fit_config_add_hash() - Add a list of nodes to hash for an image + * + * This adds a list of paths to image nodes (as referred to by a particular + * offset) that need to be hashed, to protect a configuration + * + * @fit: Pointer to the FIT format image header + * @image_noffset: Offset of image to process (e.g. /images/kernel-1) + * @node_inc: List of nodes to add to + * @conf_name Configuration-node name, child of /configurations node (only + * used for error messages) + * @sig_name Signature-node name (only used for error messages) + * @iname: Name of image being processed (e.g. "kernel-1" (only used + * for error messages) + */ +static int fit_config_add_hash(const void *fit, int image_noffset, + struct strlist *node_inc, const char *conf_name, + const char *sig_name, const char *iname) { char name[200], path[200]; int noffset; @@ -777,7 +793,21 @@ err_path: return -ENOENT; } -static int fit_config_get_hash_list(void *fit, int conf_noffset, +/** + * fit_config_get_hash_list() - Get the regions to sign + * + * This calculates a list of nodes to hash for this particular configuration, + * returning it as a string list (struct strlist, not a devicetree string list) + * + * @fit: Pointer to the FIT format image header + * @conf_noffset: Offset of configuration node to sign (child of + * /configurations node) + * @sig_offset: Offset of signature node containing info about how to sign it + * (child of 'signatures' node) + * @return 0 if OK, -ENOENT if an image referred to by the configuration cannot + * be found, -ENOMSG if ther were no images in the configuration + */ +static int fit_config_get_hash_list(const void *fit, int conf_noffset, int sig_offset, struct strlist *node_inc) { int allow_missing; @@ -828,9 +858,8 @@ static int fit_config_get_hash_list(void *fit, int conf_noffset, return -ENOENT; } - ret = fit_config_add_hash(fit, conf_name, - sig_name, node_inc, - iname, image_noffset); + ret = fit_config_add_hash(fit, image_noffset, node_inc, + conf_name, sig_name, iname); if (ret < 0) return ret; @@ -852,9 +881,32 @@ err_mem: return -ENOMEM; } -static int fit_config_get_data(void *fit, int conf_noffset, int noffset, - struct image_region **regionp, int *region_countp, - char **region_propp, int *region_proplen) +/** + * fit_config_get_regions() - Get the regions to sign + * + * This calculates a list of node to hash for this particular configuration, + * then finds which regions of the devicetree they correspond to. + * + * @fit: Pointer to the FIT format image header + * @conf_noffset: Offset of configuration node to sign (child of + * /configurations node) + * @sig_offset: Offset of signature node containing info about how to sign it + * (child of 'signatures' node) + * @regionp: Returns list of regions that need to be hashed (allocated; must be + * freed by the caller) + * @region_count: Returns number of regions + * @region_propp: Returns string-list property containing the list of nodes + * that correspond to the regions. Each entry is a full path to the node. + * This is in devicetree format, i.e. a \0 between each string. This is + * allocated and must be freed by the caller. + * @region_proplen: Returns length of *@@region_propp in bytes + * @return 0 if OK, -ENOMEM if out of memory, -EIO if the regions to hash could + * not be found, -EINVAL if no registers were found to hash + */ +static int fit_config_get_regions(const void *fit, int conf_noffset, + int sig_offset, struct image_region **regionp, + int *region_countp, char **region_propp, + int *region_proplen) { char * const exc_prop[] = {"data"}; struct strlist node_inc; @@ -867,11 +919,12 @@ static int fit_config_get_data(void *fit, int conf_noffset, int noffset, int ret, len; conf_name = fit_get_name(fit, conf_noffset, NULL); - sig_name = fit_get_name(fit, noffset, NULL); + sig_name = fit_get_name(fit, sig_offset, NULL); debug("%s: conf='%s', sig='%s'\n", __func__, conf_name, sig_name); /* Get a list of nodes we want to hash */ - ret = fit_config_get_hash_list(fit, conf_noffset, noffset, &node_inc); + ret = fit_config_get_hash_list(fit, conf_noffset, sig_offset, + &node_inc); if (ret) return ret; @@ -925,7 +978,7 @@ static int fit_config_get_data(void *fit, int conf_noffset, int noffset, } static int fit_config_process_sig(const char *keydir, const char *keyfile, - void *keydest, void *fit, const char *conf_name, + void *keydest, void *fit, const char *conf_name, int conf_noffset, int noffset, const char *comment, int require_keys, const char *engine_id, const char *cmdname) { @@ -940,8 +993,9 @@ static int fit_config_process_sig(const char *keydir, const char *keyfile, int ret; node_name = fit_get_name(fit, noffset, NULL); - if (fit_config_get_data(fit, conf_noffset, noffset, ®ion, - ®ion_count, ®ion_prop, ®ion_proplen)) + if (fit_config_get_regions(fit, conf_noffset, noffset, ®ion, + ®ion_count, ®ion_prop, + ®ion_proplen)) return -1; if (fit_image_setup_sig(&info, keydir, keyfile, fit, conf_name, noffset, From patchwork Fri Nov 12 19:28:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1554554 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=PeDgYOc6; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HrTDc3LGKz9sR4 for ; Sat, 13 Nov 2021 06:29:36 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 90C2682FEA; Fri, 12 Nov 2021 20:29:19 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="PeDgYOc6"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id D25E982F5A; Fri, 12 Nov 2021 20:29:00 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-ot1-x32e.google.com (mail-ot1-x32e.google.com [IPv6:2607:f8b0:4864:20::32e]) (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 04C2D83039 for ; Fri, 12 Nov 2021 20:28:55 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-ot1-x32e.google.com with SMTP id x19-20020a9d7053000000b0055c8b39420bso15387571otj.1 for ; Fri, 12 Nov 2021 11:28:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=jwU0Qjnc1h8q5EmHzsbmrGnM5fsmkzb6nvBO2Zh6I0Q=; b=PeDgYOc6D3fuRCGjDkJDv3cxNxyfbEMaBRxN2pLi2x2RJniKuam5OHXcZqr40OONSx vSm/kI0bTNXW89Of9ZEMVkimGVKZOxMp9ON4JlMax+/6ZwsfXhI8vkp98sim2085Hy0l FpN09ldQjE+/J63oCmsf/rgLl7ddq1CU1EboM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jwU0Qjnc1h8q5EmHzsbmrGnM5fsmkzb6nvBO2Zh6I0Q=; b=t/LG5pj+y7zBZMq0nJT7vzJYmX+MPfR/qiCU3TjOHc+wrmvRJ1Qec3wDMdBbrPAuxo vVUU+jjPJ5j5oXHvGtcoKqm2HULfRffxyoZS9pm6QQVuFuyIEUBUjpiPHb8tVcO6aA4L CBHWSgrXSD8n/MnI0uK79Dv70Z9Q7+hECscsncEQ20OfAY1GD7VxOxeRW+WwJV6Fwnrj 7rKDDtQ41ZcmI+P/YLhfxS5lLegfCuG5rmwDrlkTt20xc8Rekmsx/sZLL6EtnBEt7vK9 VY6HR7DmVFHQx0BJJPse47hm71azU4Hr1FT8H5bA/DGfgivLEZOhMgr/je8yZHD5trf0 S8Ig== X-Gm-Message-State: AOAM531Oz3rd/kLzmcLVhe+scxY5fJUf9A5iAWK2NifGqN5n8Rz279/+ wO+EMC4ss8pXs07QtMer7wVWHpgWr/hfTg== X-Google-Smtp-Source: ABdhPJyoWFi0hnwg/PVSnfpEUxwMn/b3yj38jJd8qf5+NkrGmEPGWf74og/ueesvkH+4Uwz7XQQ9VQ== X-Received: by 2002:a05:6830:55b:: with SMTP id l27mr14273981otb.309.1636745333546; Fri, 12 Nov 2021 11:28:53 -0800 (PST) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id n20sm1283527ooe.7.2021.11.12.11.28.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Nov 2021 11:28:53 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Rob Herring , Tom Rini , Bill Mills , Simon Glass , Alexandru Gagniuc , Ming Liu , Philippe Reynes , Vagrant Cascadian Subject: [PATCH 06/16] tools: Drop unused name in image-host Date: Fri, 12 Nov 2021 12:28:07 -0700 Message-Id: <20211112192817.199075-7-sjg@chromium.org> X-Mailer: git-send-email 2.34.0.rc1.387.gb447b232ab-goog In-Reply-To: <20211112192817.199075-1-sjg@chromium.org> References: <20211112192817.199075-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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.103.2 at phobos.denx.de X-Virus-Status: Clean The name is created but never used. Drop it. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- tools/image-host.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tools/image-host.c b/tools/image-host.c index 73d35f3eee3..e4322d323a2 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -725,7 +725,7 @@ static int fit_config_add_hash(const void *fit, int image_noffset, struct strlist *node_inc, const char *conf_name, const char *sig_name, const char *iname) { - char name[200], path[200]; + char path[200]; int noffset; int hash_count; int ret; @@ -736,9 +736,6 @@ static int fit_config_add_hash(const void *fit, int image_noffset, if (strlist_add(node_inc, path)) goto err_mem; - snprintf(name, sizeof(name), "%s/%s", FIT_CONFS_PATH, - conf_name); - /* Add all this image's hashes */ hash_count = 0; for (noffset = fdt_first_subnode(fit, image_noffset); From patchwork Fri Nov 12 19:28:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1554559 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=HiNUUO41; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HrTFV5r80z9s0r for ; Sat, 13 Nov 2021 06:30:22 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 51D8E8304A; Fri, 12 Nov 2021 20:29:36 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="HiNUUO41"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id DA66B83082; Fri, 12 Nov 2021 20:29:10 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-ot1-x32f.google.com (mail-ot1-x32f.google.com [IPv6:2607:f8b0:4864:20::32f]) (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 5086283040 for ; Fri, 12 Nov 2021 20:28:56 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-ot1-x32f.google.com with SMTP id x43-20020a056830246b00b00570d09d34ebso1849081otr.2 for ; Fri, 12 Nov 2021 11:28:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=O6BAudXUx4Ua8KrSGJssXdzc/qTfPVS3emgdH2zoCik=; b=HiNUUO41Srf0/QpCzKcEoBksQTUK7y5S5DopAjYCOl8o5Jcl4Yc1Z34U5jLWtwHBht DX5OVWA/tYcuJGUGoh4q8kK0N95ofawFXLuWKyz9C7jhJcdhMnRNCWuNMKikm9Ic5D7p PHHceZ76p4+geAAHLg7+pu1SebcNdD0oA0pOU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=O6BAudXUx4Ua8KrSGJssXdzc/qTfPVS3emgdH2zoCik=; b=JhW+qx2aOfdQmyo+HFQT3FS+hi0ALHBKUkka590IjcKh0l+rQJe7YPKtPwUNoUg91s sFzV6RIjOOs8fsyYASp9+4Wlxp3FvzV98MqjRnPT+hHHy5kQ1OUSbcD04M21X+oc2NXy GUZntf5xEhtAxY+2MbbWFqtLsb5lc8PvxdmDl0U90Vs89Q2+UzCSUioA6EBssHcwCFgI cfLGo7dU+Zp9K4oogTrk4z9DCCeVFgMZm/sDJOIpRmn0Tb7HTdCtmdJTygAGtVlc6jTh QUaGVgLmNq2IYFFBFH9tB6NnOaE8QzNCYBIY2SXyn4zzp15OKGUDm2BKedJJ/PC1tji7 zkAA== X-Gm-Message-State: AOAM530R6g0bTAcMghti+4wmxyykyzEs0VGiltLLw+nhLgCtrPhb33lj TngLQxJ+yHglqn1D99CFyeErEvx7wGPhhA== X-Google-Smtp-Source: ABdhPJzQH+Z1ip9XzNBJpgoW2/UYvPr8NXfc8dYfDpDiEUZFGk1VC6sUstQ0XYn1Chz1GKhIc4iFSw== X-Received: by 2002:a05:6830:270c:: with SMTP id j12mr9907851otu.231.1636745334683; Fri, 12 Nov 2021 11:28:54 -0800 (PST) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id n20sm1283527ooe.7.2021.11.12.11.28.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Nov 2021 11:28:54 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Rob Herring , Tom Rini , Bill Mills , Simon Glass , Alexandru Gagniuc , Artem Lapkin , Hannu Lounento , Joel Stanley , John Keeping Subject: [PATCH 07/16] tools: Avoid confusion between keys and signatures Date: Fri, 12 Nov 2021 12:28:08 -0700 Message-Id: <20211112192817.199075-8-sjg@chromium.org> X-Mailer: git-send-email 2.34.0.rc1.387.gb447b232ab-goog In-Reply-To: <20211112192817.199075-1-sjg@chromium.org> References: <20211112192817.199075-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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.103.2 at phobos.denx.de X-Virus-Status: Clean We should be consistent in using the term 'signature' to describe a value added to sign something and 'key' to describe the key that can be used to verify the signature. Tidy up the code to stick to this. Add some comments to fit_config_verify_key() and its callers while we are here. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- boot/image-fit-sig.c | 97 ++++++++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 25 deletions(-) diff --git a/boot/image-fit-sig.c b/boot/image-fit-sig.c index 63e5423c925..f0ccd9b5227 100644 --- a/boot/image-fit-sig.c +++ b/boot/image-fit-sig.c @@ -135,7 +135,7 @@ int fit_image_check_sig(const void *fit, int noffset, const void *data, static int fit_image_verify_sig(const void *fit, int image_noffset, const char *data, size_t size, - const void *sig_blob, int sig_offset) + const void *key_blob, int key_offset) { int noffset; char *err_msg = ""; @@ -184,34 +184,34 @@ error: int fit_image_verify_required_sigs(const void *fit, int image_noffset, const char *data, size_t size, - const void *sig_blob, int *no_sigsp) + const void *key_blob, int *no_sigsp) { int verify_count = 0; int noffset; - int sig_node; + int key_node; /* Work out what we need to verify */ *no_sigsp = 1; - sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME); - if (sig_node < 0) { + key_node = fdt_subnode_offset(key_blob, 0, FIT_SIG_NODENAME); + if (key_node < 0) { debug("%s: No signature node found: %s\n", __func__, - fdt_strerror(sig_node)); + fdt_strerror(key_node)); return 0; } - fdt_for_each_subnode(noffset, sig_blob, sig_node) { + fdt_for_each_subnode(noffset, key_blob, key_node) { const char *required; int ret; - required = fdt_getprop(sig_blob, noffset, FIT_KEY_REQUIRED, + required = fdt_getprop(key_blob, noffset, FIT_KEY_REQUIRED, NULL); if (!required || strcmp(required, "image")) continue; ret = fit_image_verify_sig(fit, image_noffset, data, size, - sig_blob, noffset); + key_blob, noffset); if (ret) { printf("Failed to verify required signature '%s'\n", - fit_get_name(sig_blob, noffset, NULL)); + fit_get_name(key_blob, noffset, NULL)); return ret; } verify_count++; @@ -368,8 +368,35 @@ static int fit_config_check_sig(const void *fit, int noffset, return 0; } -static int fit_config_verify_sig(const void *fit, int conf_noffset, - const void *sig_blob, int sig_offset) +/** + * fit_config_verify_key() - Verify that a configuration is signed with a key + * + * Here we are looking at a particular configuration that needs verification: + * + * configurations { + * default = "conf-1"; + * conf-1 { + * kernel = "kernel-1"; + * fdt = "fdt-1"; + * signature-1 { + * algo = "sha1,rsa2048"; + * value = <...conf 1 signature...>; + * }; + * }; + * + * We must check each of the signature subnodes of conf-1. Hopefully one of them + * will match the key at key_offset. + * + * @fit: FIT to check + * @conf_noffset: Offset of the configuration node to check (e.g. + * /configurations/conf-1) + * @key_blob: Blob containing the keys to check against + * @key_offset: Offset of the key to check within @key_blob + * @return 0 if OK, -EPERM if any signatures did not verify, or the + * configuration node has an invalid name + */ +static int fit_config_verify_key(const void *fit, int conf_noffset, + const void *key_blob, int key_offset) { int noffset; char *err_msg = "No 'signature' subnode found"; @@ -382,7 +409,7 @@ static int fit_config_verify_sig(const void *fit, int conf_noffset, if (!strncmp(name, FIT_SIG_NODENAME, strlen(FIT_SIG_NODENAME))) { - ret = fit_config_check_sig(fit, noffset, sig_offset, + ret = fit_config_check_sig(fit, noffset, key_offset, conf_noffset, &err_msg); if (ret) { puts("- "); @@ -409,12 +436,25 @@ error: return -EPERM; } -static int fit_config_verify_required_sigs(const void *fit, int conf_noffset, - const void *sig_blob) +/** + * fit_config_verify_required_keys() - verify any required signatures for config + * + * This looks through all the signatures we expect and verifies that at least + * all the required ones are valid signatures for the configuration + * + * @fit: FIT to check + * @conf_noffset: Offset of the configuration node to check (e.g. + * /configurations/conf-1) + * @key_blob: Blob containing the keys to check against + * @return 0 if OK, -EPERM if any signatures did not verify, or the + * configuration node has an invalid name + */ +static int fit_config_verify_required_keys(const void *fit, int conf_noffset, + const void *key_blob) { const char *name = fit_get_name(fit, conf_noffset, NULL); int noffset; - int sig_node; + int key_node; int verified = 0; int reqd_sigs = 0; bool reqd_policy_all = true; @@ -430,38 +470,45 @@ static int fit_config_verify_required_sigs(const void *fit, int conf_noffset, } /* Work out what we need to verify */ - sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME); - if (sig_node < 0) { + key_node = fdt_subnode_offset(key_blob, 0, FIT_SIG_NODENAME); + if (key_node < 0) { debug("%s: No signature node found: %s\n", __func__, - fdt_strerror(sig_node)); + fdt_strerror(key_node)); return 0; } /* Get required-mode policy property from DTB */ - reqd_mode = fdt_getprop(sig_blob, sig_node, "required-mode", NULL); + reqd_mode = fdt_getprop(key_blob, key_node, "required-mode", NULL); if (reqd_mode && !strcmp(reqd_mode, "any")) reqd_policy_all = false; debug("%s: required-mode policy set to '%s'\n", __func__, reqd_policy_all ? "all" : "any"); - fdt_for_each_subnode(noffset, sig_blob, sig_node) { + /* + * The algorithm here is a little convoluted due to how we want it to + * work. Here we work through each of the signature nodes in the + * public-key area. These are in the U-Boot control devicetree. Each + * node was created by signing a configuration, so we check if it is + * 'required' and if so, request that it be verified. + */ + fdt_for_each_subnode(noffset, key_blob, key_node) { const char *required; int ret; - required = fdt_getprop(sig_blob, noffset, FIT_KEY_REQUIRED, + required = fdt_getprop(key_blob, noffset, FIT_KEY_REQUIRED, NULL); if (!required || strcmp(required, "conf")) continue; reqd_sigs++; - ret = fit_config_verify_sig(fit, conf_noffset, sig_blob, + ret = fit_config_verify_key(fit, conf_noffset, key_blob, noffset); if (ret) { if (reqd_policy_all) { printf("Failed to verify required signature '%s'\n", - fit_get_name(sig_blob, noffset, NULL)); + fit_get_name(key_blob, noffset, NULL)); return ret; } } else { @@ -481,6 +528,6 @@ static int fit_config_verify_required_sigs(const void *fit, int conf_noffset, int fit_config_verify(const void *fit, int conf_noffset) { - return fit_config_verify_required_sigs(fit, conf_noffset, + return fit_config_verify_required_keys(fit, conf_noffset, gd_fdt_blob()); } From patchwork Fri Nov 12 19:28:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1554558 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=eRC837nd; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HrTFJ0Xznz9s0r for ; Sat, 13 Nov 2021 06:30:12 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id EC34383081; Fri, 12 Nov 2021 20:29:30 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="eRC837nd"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 014A383046; Fri, 12 Nov 2021 20:29:08 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-ot1-x331.google.com (mail-ot1-x331.google.com [IPv6:2607:f8b0:4864:20::331]) (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 5020083046 for ; Fri, 12 Nov 2021 20:28:57 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-ot1-x331.google.com with SMTP id w6-20020a9d77c6000000b0055e804fa524so15386562otl.3 for ; Fri, 12 Nov 2021 11:28:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=YJCK0y1XTsl36mFoKs00M5/TdhQoGyA5hcbmusj/o28=; b=eRC837ndDkkmX3QD1m/mFpm7HLXGv11NZf3cjO4RoRRbie8lt2h/LvUSV12C2fDSqJ TcKweygS0WJIay5ZXoUKqWgn8XhJgi7WmBKEt77cd/TljJTmkcSudDuWDx5rXX81tisx 5gOzy0YgEVsmo5WXhnVxBFmQMHK3cnyBsNN8Q= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=YJCK0y1XTsl36mFoKs00M5/TdhQoGyA5hcbmusj/o28=; b=oaA8Q8vaSZxCp56Mk1hrOJL7MRMmkNwgckQPe5SaBPWNZw/+9RtaZSn1WIWr4g+jT2 VHGT/428gJdlLDbjCekyq/JEGLEgpZs56YgoodzGJDUShwdcEY5zX7gByMKA4eYCaWaB JHGCS2zsXuF2bE8nxzDVIv2LuRgjSZ3PEmL8vzlYn8WySZtnjDsmrPSe9mAhONPVA3YA O99VGgO5HQs1gtkcvHTmcWOpwVzy56S0aAX+6xIJc9G3mp2CGS+Phs7WGB01KpCHqELD o2r6iAE4HDtCwrA+jBu7DIKzPB9AcSUHVKocQZ+etuEuF9gbCkAIn0Lvi+Ek/uQ+9HRd PZSw== X-Gm-Message-State: AOAM532NLrqBGaSKALjMysbBLQDZtHEqe1IxopeUXy0OUZmZUWgsYgt9 T4XLix97i1UoqD9uCL+FrnzpvzGLXfiwhQ== X-Google-Smtp-Source: ABdhPJxfqc2bd7ddAEaxpI/a1dtf4KzmLZDCwzBdzfjoNd7Y8DcAMr/2hRIEcF1Wr4xT6INQvZKUPg== X-Received: by 2002:a9d:6297:: with SMTP id x23mr14271063otk.142.1636745335772; Fri, 12 Nov 2021 11:28:55 -0800 (PST) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id n20sm1283527ooe.7.2021.11.12.11.28.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Nov 2021 11:28:55 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Rob Herring , Tom Rini , Bill Mills , Simon Glass , Alexandru Gagniuc , Artem Lapkin , Hannu Lounento , Joel Stanley , John Keeping Subject: [PATCH 08/16] tools: Tidy up argument order in fit_config_check_sig() Date: Fri, 12 Nov 2021 12:28:09 -0700 Message-Id: <20211112192817.199075-9-sjg@chromium.org> X-Mailer: git-send-email 2.34.0.rc1.387.gb447b232ab-goog In-Reply-To: <20211112192817.199075-1-sjg@chromium.org> References: <20211112192817.199075-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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.103.2 at phobos.denx.de X-Virus-Status: Clean Put the parent node first in the parameters as this is more natural. Also add a comment to explain what is going on. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- boot/image-fit-sig.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/boot/image-fit-sig.c b/boot/image-fit-sig.c index f0ccd9b5227..253748ef649 100644 --- a/boot/image-fit-sig.c +++ b/boot/image-fit-sig.c @@ -226,21 +226,34 @@ int fit_image_verify_required_sigs(const void *fit, int image_noffset, /** * fit_config_check_sig() - Check the signature of a config * + * Here we are looking at a particular signature that needs verification (here + * signature-1): + * + * configurations { + * default = "conf-1"; + * conf-1 { + * kernel = "kernel-1"; + * fdt = "fdt-1"; + * signature-1 { + * algo = "sha1,rsa2048"; + * value = <...conf 1 signature...>; + * }; + * }; + * * @fit: FIT to check - * @noffset: Offset of configuration node (e.g. /configurations/conf-1) - * @required_keynode: Offset in the control FDT of the required key node, + * @noffset: Offset of the signature node being checked (e.g. + * /configurations/conf-1/signature-1) + * @conf_noffset: Offset of configuration node (e.g. /configurations/conf-1) + * @required_keynode: Offset in @key_blob of the required key node, * if any. If this is given, then the configuration wil not * pass verification unless that key is used. If this is * -1 then any signature will do. - * @conf_noffset: Offset of the configuration subnode being checked (e.g. - * /configurations/conf-1/kernel) * @err_msgp: In the event of an error, this will be pointed to a * help error string to display to the user. * @return 0 if all verified ok, <0 on error */ -static int fit_config_check_sig(const void *fit, int noffset, - int required_keynode, int conf_noffset, - char **err_msgp) +static int fit_config_check_sig(const void *fit, int noffset, int conf_noffset, + int required_keynode, char **err_msgp) { static char * const exc_prop[] = { "data", @@ -409,8 +422,8 @@ static int fit_config_verify_key(const void *fit, int conf_noffset, if (!strncmp(name, FIT_SIG_NODENAME, strlen(FIT_SIG_NODENAME))) { - ret = fit_config_check_sig(fit, noffset, key_offset, - conf_noffset, &err_msg); + ret = fit_config_check_sig(fit, noffset, conf_noffset, + key_offset, &err_msg); if (ret) { puts("- "); } else { From patchwork Fri Nov 12 19:28:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1554560 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=LEvqOqnr; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HrTFj13ccz9s0r for ; Sat, 13 Nov 2021 06:30:33 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 80E2E8307D; Fri, 12 Nov 2021 20:29:40 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="LEvqOqnr"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id E4B2583040; Fri, 12 Nov 2021 20:29:11 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-oi1-x22c.google.com (mail-oi1-x22c.google.com [IPv6:2607:f8b0:4864:20::22c]) (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 AC70683053 for ; Fri, 12 Nov 2021 20:28:58 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-oi1-x22c.google.com with SMTP id bk14so19750095oib.7 for ; Fri, 12 Nov 2021 11:28:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=fWa9DTKd5o3+D29WbleOSNNAuuCyWbLZFc9hgmZiDQM=; b=LEvqOqnrrUBmxfQMNXec5/mJdIyBZJHJ1GlAxjwW3sdMMpT6YOyySlqh/ZAPkro0oW LEm/7EQl8wShMqXvnhxCslYEVdXe61+ZA2zWqUK+SndI2Bt3VHHvFOcaZMHvQXeeZDD7 qdAOkGDYxNPFDVyes9wBZcFz3oEG1XWfZ8q8w= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=fWa9DTKd5o3+D29WbleOSNNAuuCyWbLZFc9hgmZiDQM=; b=azmmo8xOYoRYtDCFDtRGMeKmecd15CRVtOFr6V+Ryxjg1eYOETV5PEDkose+1V36jr Onaqu5OOB6BbXgifZxT0JmPcapNpG8KSQp0rfWnwmKMnBGVQYwnpokfncGEemdZOna4y bpkiIcUFt9fHEMD1F5IYtJLfVM5jkYcTTJWMfqtqArNps4dB/0bR4RgGXfcm0b8v7i3e XmheChyG0XFyiyPbp38SeYuBWc2MEWGi9e56ss1LJzjpHMp+hLem0e+OnZpDbaIoPx0Y oIeSEs9Gcle467XUiirBurJlwSIetOzGD/QZpMgd4plYZ+mACptYSAmm3coN0/EHZ5nS jLLw== X-Gm-Message-State: AOAM5322o1jS0X4L+4I6ZBaELDqS7/SK9przVH+p73MXUkHBNXgQDXX9 dThZ/n7YHieflo5vlx4KIgqbGytB7Jg1uQ== X-Google-Smtp-Source: ABdhPJz/oijLBwpAQLDzBzqcNC3+/StSz1BkSWPtKdefRk/tFceatJIYuQMS9Kdyfg3CyoaflM/j0Q== X-Received: by 2002:a05:6808:1811:: with SMTP id bh17mr17473283oib.105.1636745337023; Fri, 12 Nov 2021 11:28:57 -0800 (PST) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id n20sm1283527ooe.7.2021.11.12.11.28.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Nov 2021 11:28:56 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Rob Herring , Tom Rini , Bill Mills , Simon Glass , Alexandru Gagniuc , Artem Lapkin , Hannu Lounento , Heiko Schocher , Joel Stanley , John Keeping , Philippe Reynes , Sebastian Reichel Subject: [PATCH 09/16] tools: Pass the key blob around Date: Fri, 12 Nov 2021 12:28:10 -0700 Message-Id: <20211112192817.199075-10-sjg@chromium.org> X-Mailer: git-send-email 2.34.0.rc1.387.gb447b232ab-goog In-Reply-To: <20211112192817.199075-1-sjg@chromium.org> References: <20211112192817.199075-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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.103.2 at phobos.denx.de X-Virus-Status: Clean At present we rely on the key blob being in the global_data fdt_blob pointer. This is true in U-Boot but not with tools. For clarity, pass the parameter around. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- boot/image-fit-sig.c | 31 ++++++++++++++++++------------- boot/image-fit.c | 12 +++++++----- common/spl/spl_fit.c | 3 ++- include/image.h | 23 ++++++++++++++++++----- 4 files changed, 45 insertions(+), 24 deletions(-) diff --git a/boot/image-fit-sig.c b/boot/image-fit-sig.c index 253748ef649..a751c12d174 100644 --- a/boot/image-fit-sig.c +++ b/boot/image-fit-sig.c @@ -65,7 +65,8 @@ struct image_region *fit_region_make_list(const void *fit, static int fit_image_setup_verify(struct image_sign_info *info, const void *fit, int noffset, - int required_keynode, char **err_msgp) + const void *key_blob, int required_keynode, + char **err_msgp) { char *algo_name; const char *padding_name; @@ -91,7 +92,7 @@ static int fit_image_setup_verify(struct image_sign_info *info, info->checksum = image_get_checksum_algo(algo_name); info->crypto = image_get_crypto_algo(algo_name); info->padding = image_get_padding_algo(padding_name); - info->fdt_blob = gd_fdt_blob(); + info->fdt_blob = key_blob; info->required_keynode = required_keynode; printf("%s:%s", algo_name, info->keyname); @@ -104,7 +105,8 @@ static int fit_image_setup_verify(struct image_sign_info *info, } int fit_image_check_sig(const void *fit, int noffset, const void *data, - size_t size, int required_keynode, char **err_msgp) + size_t size, const void *key_blob, int required_keynode, + char **err_msgp) { struct image_sign_info info; struct image_region region; @@ -112,8 +114,8 @@ int fit_image_check_sig(const void *fit, int noffset, const void *data, int fit_value_len; *err_msgp = NULL; - if (fit_image_setup_verify(&info, fit, noffset, required_keynode, - err_msgp)) + if (fit_image_setup_verify(&info, fit, noffset, key_blob, + required_keynode, err_msgp)) return -1; if (fit_image_hash_get_value(fit, noffset, &fit_value, @@ -156,8 +158,8 @@ static int fit_image_verify_sig(const void *fit, int image_noffset, } if (!strncmp(name, FIT_SIG_NODENAME, strlen(FIT_SIG_NODENAME))) { - ret = fit_image_check_sig(fit, noffset, data, - size, -1, &err_msg); + ret = fit_image_check_sig(fit, noffset, data, size, + key_blob, -1, &err_msg); if (ret) { puts("- "); } else { @@ -244,6 +246,7 @@ int fit_image_verify_required_sigs(const void *fit, int image_noffset, * @noffset: Offset of the signature node being checked (e.g. * /configurations/conf-1/signature-1) * @conf_noffset: Offset of configuration node (e.g. /configurations/conf-1) + * @key_blob: Blob containing the keys to check against * @required_keynode: Offset in @key_blob of the required key node, * if any. If this is given, then the configuration wil not * pass verification unless that key is used. If this is @@ -253,7 +256,8 @@ int fit_image_verify_required_sigs(const void *fit, int image_noffset, * @return 0 if all verified ok, <0 on error */ static int fit_config_check_sig(const void *fit, int noffset, int conf_noffset, - int required_keynode, char **err_msgp) + const void *key_blob, int required_keynode, + char **err_msgp) { static char * const exc_prop[] = { "data", @@ -275,12 +279,12 @@ static int fit_config_check_sig(const void *fit, int noffset, int conf_noffset, int count; config_name = fit_get_name(fit, conf_noffset, NULL); - debug("%s: fdt=%p, conf='%s', sig='%s'\n", __func__, gd_fdt_blob(), + debug("%s: fdt=%p, conf='%s', sig='%s'\n", __func__, key_blob, fit_get_name(fit, noffset, NULL), - fit_get_name(gd_fdt_blob(), required_keynode, NULL)); + fit_get_name(key_blob, required_keynode, NULL)); *err_msgp = NULL; - if (fit_image_setup_verify(&info, fit, noffset, required_keynode, - err_msgp)) + if (fit_image_setup_verify(&info, fit, noffset, key_blob, + required_keynode, err_msgp)) return -1; if (fit_image_hash_get_value(fit, noffset, &fit_value, @@ -423,7 +427,8 @@ static int fit_config_verify_key(const void *fit, int conf_noffset, if (!strncmp(name, FIT_SIG_NODENAME, strlen(FIT_SIG_NODENAME))) { ret = fit_config_check_sig(fit, noffset, conf_noffset, - key_offset, &err_msg); + key_blob, key_offset, + &err_msg); if (ret) { puts("- "); } else { diff --git a/boot/image-fit.c b/boot/image-fit.c index 33b4a46028b..59191a5486c 100644 --- a/boot/image-fit.c +++ b/boot/image-fit.c @@ -1309,7 +1309,8 @@ static int fit_image_check_hash(const void *fit, int noffset, const void *data, } int fit_image_verify_with_data(const void *fit, int image_noffset, - const void *data, size_t size) + const void *key_blob, const void *data, + size_t size) { int noffset = 0; char *err_msg = ""; @@ -1319,7 +1320,7 @@ int fit_image_verify_with_data(const void *fit, int image_noffset, /* Verify all required signatures */ if (FIT_IMAGE_ENABLE_VERIFY && fit_image_verify_required_sigs(fit, image_noffset, data, size, - gd_fdt_blob(), &verify_all)) { + key_blob, &verify_all)) { err_msg = "Unable to verify required signature"; goto error; } @@ -1342,8 +1343,8 @@ int fit_image_verify_with_data(const void *fit, int image_noffset, } else if (FIT_IMAGE_ENABLE_VERIFY && verify_all && !strncmp(name, FIT_SIG_NODENAME, strlen(FIT_SIG_NODENAME))) { - ret = fit_image_check_sig(fit, noffset, data, - size, -1, &err_msg); + ret = fit_image_check_sig(fit, noffset, data, size, + gd_fdt_blob(), -1, &err_msg); /* * Show an indication on failure, but do not return @@ -1406,7 +1407,8 @@ int fit_image_verify(const void *fit, int image_noffset) goto err; } - return fit_image_verify_with_data(fit, image_noffset, data, size); + return fit_image_verify_with_data(fit, image_noffset, gd_fdt_blob(), + data, size); err: printf("error!\n%s in '%s' image node\n", err_msg, diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index 5fe0273d66d..55133ceea6f 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -314,7 +314,8 @@ static int spl_load_fit_image(struct spl_load_info *info, ulong sector, if (CONFIG_IS_ENABLED(FIT_SIGNATURE)) { printf("## Checking hash(es) for Image %s ... ", fit_get_name(fit, node, NULL)); - if (!fit_image_verify_with_data(fit, node, src, length)) + if (!fit_image_verify_with_data(fit, node, gd_fdt_blob(), src, + length)) return -EPERM; puts("OK\n"); } diff --git a/include/image.h b/include/image.h index 533c23e2002..d5598cec461 100644 --- a/include/image.h +++ b/include/image.h @@ -1047,8 +1047,19 @@ int fit_add_verification_data(const char *keydir, const char *keyfile, int require_keys, const char *engine_id, const char *cmdname); +/** + * fit_image_verify_with_data() - Verify an image with given data + * + * @fit: Pointer to the FIT format image header + * @image_offset: Offset in @fit of image to verify + * @key_blob: FDT containing public keys + * @data: Image data to verify + * @size: Size of image data + */ int fit_image_verify_with_data(const void *fit, int image_noffset, - const void *data, size_t size); + const void *key_blob, const void *data, + size_t size); + int fit_image_verify(const void *fit, int noffset); int fit_config_verify(const void *fit, int conf_noffset); int fit_all_image_verify(const void *fit); @@ -1296,7 +1307,7 @@ struct padding_algo *image_get_padding_algo(const char *name); * @image_noffset: Offset of image node to check * @data: Image data to check * @size: Size of image data - * @sig_blob: FDT containing public keys + * @key_blob: FDT containing public keys * @no_sigsp: Returns 1 if no signatures were required, and * therefore nothing was checked. The caller may wish * to fall back to other mechanisms, or refuse to @@ -1304,7 +1315,7 @@ struct padding_algo *image_get_padding_algo(const char *name); * @return 0 if all verified ok, <0 on error */ int fit_image_verify_required_sigs(const void *fit, int image_noffset, - const char *data, size_t size, const void *sig_blob, + const char *data, size_t size, const void *key_blob, int *no_sigsp); /** @@ -1314,7 +1325,8 @@ int fit_image_verify_required_sigs(const void *fit, int image_noffset, * @noffset: Offset of signature node to check * @data: Image data to check * @size: Size of image data - * @required_keynode: Offset in the control FDT of the required key node, + * @keyblob: Key blob to check (typically the control FDT) + * @required_keynode: Offset in the keyblob of the required key node, * if any. If this is given, then the image wil not * pass verification unless that key is used. If this is * -1 then any signature will do. @@ -1323,7 +1335,8 @@ int fit_image_verify_required_sigs(const void *fit, int image_noffset, * @return 0 if all verified ok, <0 on error */ int fit_image_check_sig(const void *fit, int noffset, const void *data, - size_t size, int required_keynode, char **err_msgp); + size_t size, const void *key_blob, int required_keynode, + char **err_msgp); int fit_image_decrypt_data(const void *fit, int image_noffset, int cipher_noffset, From patchwork Fri Nov 12 19:28:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1554561 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=VAZ8mJjd; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HrTFv14KTz9s0r for ; Sat, 13 Nov 2021 06:30:43 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 717B583073; Fri, 12 Nov 2021 20:29:45 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="VAZ8mJjd"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id A668583036; Fri, 12 Nov 2021 20:29:14 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.2 Received: from mail-oi1-x229.google.com (mail-oi1-x229.google.com [IPv6:2607:f8b0:4864:20::229]) (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 BE3F383064 for ; Fri, 12 Nov 2021 20:28:59 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-oi1-x229.google.com with SMTP id o4so19715440oia.10 for ; Fri, 12 Nov 2021 11:28:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=u5gX/KcDntmPNi9gVJ+4ARA2KSTh7mY41lZMq3PRYP4=; b=VAZ8mJjdH1l9o+ba+JvPxNyzgdj0Pehdlww6sfumwIyxtiXsgiMN8maZhujihgwtAp jxs75O+Pkm1oH537R+XrD84XuQjN+qeCj7kExvR2IPXh8XJSPyC8qEK2HEiNO6DW6yHF EsENe0xVws9aw2Dn638FRECL2nMVojG7cGfuc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=u5gX/KcDntmPNi9gVJ+4ARA2KSTh7mY41lZMq3PRYP4=; b=CtU6w5+UefQ+UvWe4Dms10V5ndvFRmnLYVpt/bvlZWPzP1zqaLkD8gOOqQxJ0eU6xX Lt2IhRJgjBrLQN1WErN/6YtgfvGGZNgT2qUjtWY46W5Ys8xiRVH7ZXy223XxEslas7QY PM2QdBeVxmzURB4KNnkVshMuCvgVVOiEY5cRLUpwARJJvM7MJ0CCtOAU0BHwRBH9o+ij EnxZZsrE+qzqWVuBQ5lRGxJrdGmufC9yh0/ArCa0zwBpgazS7ejqJg/rMp6tfiojcnCK mKTk0gqo8B6pQoBYmm6ZIEIOk1XC9Z4Dv0c3OMmkZoZaaSDxSGHV1Al0G0nXQlLy48GO TuRw== X-Gm-Message-State: AOAM532avrz2xo83EDKIC6cY7P4KyzgiAPn7verJFGaxRarK6OgmFPKN TXBNfduORaDA21ON7FuTrmrywFQiCo4iDg== X-Google-Smtp-Source: ABdhPJximn5W3DCrquqc9CvE3+HsfvTdgO8tiqZbBYEG5VV/C1mhWhEnoXWZ2IgNIPq5BggmYuGGDg== X-Received: by 2002:aca:bb56:: with SMTP id l83mr14802317oif.47.1636745338281; Fri, 12 Nov 2021 11:28:58 -0800 (PST) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id n20sm1283527ooe.7.2021.11.12.11.28.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Nov 2021 11:28:57 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Rob Herring , Tom Rini , Bill Mills , Simon Glass , Alexandru Gagniuc , "Chan, Donald" , Heinrich Schuchardt , Joe Hershberger , Marc Kleine-Budde , Marek Vasut , Ming Liu , Philippe Reynes , Vagrant Cascadian Subject: [PATCH 10/16] image: Return destination node for add_verify_data() method Date: Fri, 12 Nov 2021 12:28:11 -0700 Message-Id: <20211112192817.199075-11-sjg@chromium.org> X-Mailer: git-send-email 2.34.0.rc1.387.gb447b232ab-goog In-Reply-To: <20211112192817.199075-1-sjg@chromium.org> References: <20211112192817.199075-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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.103.2 at phobos.denx.de X-Virus-Status: Clean It is useful to know where the verification data was written. Update the API to return this. Signed-off-by: Simon Glass --- include/image.h | 3 ++- include/u-boot/ecdsa.h | 5 +++-- include/u-boot/rsa.h | 5 +++-- lib/ecdsa/ecdsa-libcrypto.c | 4 ++-- lib/rsa/rsa-sign.c | 5 ++++- tools/image-host.c | 5 ++--- 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/include/image.h b/include/image.h index d5598cec461..0f5e037a192 100644 --- a/include/image.h +++ b/include/image.h @@ -1242,7 +1242,8 @@ struct crypto_algo { * * @info: Specifies key and FIT information * @keydest: Destination FDT blob for public key data - * @return: 0, on success, -ve on error + * @return: node offset within the FDT blob where the data was written, + * or -ve on error */ int (*add_verify_data)(struct image_sign_info *info, void *keydest); diff --git a/include/u-boot/ecdsa.h b/include/u-boot/ecdsa.h index f6951c7346d..f1fa176d916 100644 --- a/include/u-boot/ecdsa.h +++ b/include/u-boot/ecdsa.h @@ -44,8 +44,9 @@ int ecdsa_sign(struct image_sign_info *info, const struct image_region region[], * * @info: Specifies key and FIT information * @keydest: Destination FDT blob for public key data - * @return: 0, on success, -ENOSPC if the keydest FDT blob ran out of space, - * other -ve value on error + * @return: node offset within the FDT blob where the data was written on + * success, -ENOSPC if the keydest FDT blob ran out of space, other -ve + * value on other error */ int ecdsa_add_verify_data(struct image_sign_info *info, void *keydest); diff --git a/include/u-boot/rsa.h b/include/u-boot/rsa.h index 7556aa5b4b7..fafefeedd80 100644 --- a/include/u-boot/rsa.h +++ b/include/u-boot/rsa.h @@ -61,8 +61,9 @@ int rsa_sign(struct image_sign_info *info, * * @info: Specifies key and FIT information * @keydest: Destination FDT blob for public key data - * @return: 0, on success, -ENOSPC if the keydest FDT blob ran out of space, - other -ve value on error + * @return: node offset within the FDT blob where the data was written on + * success, -ENOSPC if the keydest FDT blob ran out of space, other -ve + * value on other error */ int rsa_add_verify_data(struct image_sign_info *info, void *keydest); diff --git a/lib/ecdsa/ecdsa-libcrypto.c b/lib/ecdsa/ecdsa-libcrypto.c index 1757a145623..aa9a226d031 100644 --- a/lib/ecdsa/ecdsa-libcrypto.c +++ b/lib/ecdsa/ecdsa-libcrypto.c @@ -299,7 +299,7 @@ static int do_add(struct signer *ctx, void *fdt, const char *key_node_name) if (ret < 0) return ret; - return 0; + return key_node; } int ecdsa_add_verify_data(struct image_sign_info *info, void *fdt) @@ -311,7 +311,7 @@ int ecdsa_add_verify_data(struct image_sign_info *info, void *fdt) fdt_key_name = info->keyname ? info->keyname : "default-key"; ret = prepare_ctx(&ctx, info); if (ret >= 0) - do_add(&ctx, fdt, fdt_key_name); + ret = do_add(&ctx, fdt, fdt_key_name); free_ctx(&ctx); return ret; diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c index 0579e5294ee..e8b06c857f2 100644 --- a/lib/rsa/rsa-sign.c +++ b/lib/rsa/rsa-sign.c @@ -701,5 +701,8 @@ err_get_pub_key: if (info->engine_id) rsa_engine_remove(e); - return ret; + if (ret) + return ret; + + return node; } diff --git a/tools/image-host.c b/tools/image-host.c index e4322d323a2..e53fe4bbbed 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -264,7 +264,7 @@ static int fit_image_process_sig(const char *keydir, const char *keyfile, */ if (keydest) { ret = info.crypto->add_verify_data(&info, keydest); - if (ret) { + if (ret < 0) { printf("Failed to add verification data for '%s' signature node in '%s' image node\n", node_name, image_name); return ret; @@ -1030,11 +1030,10 @@ static int fit_config_process_sig(const char *keydir, const char *keyfile, /* Write the public key into the supplied FDT file */ if (keydest) { ret = info.crypto->add_verify_data(&info, keydest); - if (ret) { + if (ret < 0) { printf("Failed to add verification data for '%s' signature node in '%s' configuration node\n", node_name, conf_name); } - return ret; } return 0; From patchwork Fri Nov 12 19:28:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1554562 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=PzW2hE+n; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HrTG50lfrz9s0r for ; Sat, 13 Nov 2021 06:30:52 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 4EB5A83093; Fri, 12 Nov 2021 20:29:50 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="PzW2hE+n"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id C1BC88302F; Fri, 12 Nov 2021 20:29:17 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-oi1-x22f.google.com (mail-oi1-x22f.google.com [IPv6:2607:f8b0:4864:20::22f]) (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 4025A82FB9 for ; Fri, 12 Nov 2021 20:29:01 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-oi1-x22f.google.com with SMTP id q124so19776670oig.3 for ; Fri, 12 Nov 2021 11:29:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=apKefxu6VtOCFchHVhRx4SHGPdUIWdydVDUnbhLU1E4=; b=PzW2hE+n1N3tcdB8c95OPVrPXsYDe7PD3AalDExaK+9dJVaJJCm7xTnqW8g/Gs7LNy WjBw3AUD7xsyr1DdYWKw987ahwT3eyfc4B7NCOWLtZNhrAe70NEv2AJASu/QM3jUPKaA bBRuYGgsCU+xZfxUMbgLRD7LDfm84cRYb1H9g= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=apKefxu6VtOCFchHVhRx4SHGPdUIWdydVDUnbhLU1E4=; b=o7WQwLDhSAVnXrp/UE0Cb1KAHahWtNAcufqA/mpWFRZpyzGashtA0yJ13G3p4wIVgj COKJ/fv7y1f6lZvecsm9ya/4hOnYXetUMuNcdBE4qWsoc7cG/fIJKWTrF5MuEIsoZXXJ DNQwOUa/4Dro+0D/NF/O9y1QYmSZcPt7jNCG6bilU6GrWdM7nzIzA21K8cqRnN9omCWl 7a9vdTBM6u/4Yg71mrPhLAsnSStoh4y4QxZkEHyyGDKYK8bXKe6980w0Wj/uMHtMuKmi 21OalZM3CQIs9Ix89RVjglrfolMv+UBFQI6c6mlXc8takncM7aha6EbnJEKknE48pawk wZkA== X-Gm-Message-State: AOAM532sg4lNYABI2USIIaWxH7DWtj/F0Qfb7V3AngrseXiWw5xT4VWQ Z3S7y55Sbd5dS25LRAdWhbiHTe7/eYt+SQ== X-Google-Smtp-Source: ABdhPJw6RyWnqzbX0Xh7vaJXAkQOlHaO2ot6Jl+jg78HlNW+1fpeBC9a4k6ID1pvTmcmCquDOZRMZQ== X-Received: by 2002:aca:604:: with SMTP id 4mr28036724oig.8.1636745339719; Fri, 12 Nov 2021 11:28:59 -0800 (PST) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id n20sm1283527ooe.7.2021.11.12.11.28.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Nov 2021 11:28:59 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Rob Herring , Tom Rini , Bill Mills , Simon Glass , Alexandru Gagniuc , Ming Liu , Philippe Reynes , Vagrant Cascadian Subject: [PATCH 11/16] tools: Pass public-key node through to caller Date: Fri, 12 Nov 2021 12:28:12 -0700 Message-Id: <20211112192817.199075-12-sjg@chromium.org> X-Mailer: git-send-email 2.34.0.rc1.387.gb447b232ab-goog In-Reply-To: <20211112192817.199075-1-sjg@chromium.org> References: <20211112192817.199075-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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.103.2 at phobos.denx.de X-Virus-Status: Clean Update the two functions that call add_verify_data() so that the caller can see the node that was written to. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- tools/image-host.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/tools/image-host.c b/tools/image-host.c index e53fe4bbbed..e2b120ce532 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -209,7 +209,8 @@ static int fit_image_setup_sig(struct image_sign_info *info, * @comment: Comment to add to signature nodes * @require_keys: Mark all keys as 'required' * @engine_id: Engine to use for signing - * @return 0 if ok, -1 on error + * @return keydest node if @keydest is non-NULL, else 0 if none; -ve error code + * on failure */ static int fit_image_process_sig(const char *keydir, const char *keyfile, void *keydest, void *fit, const char *image_name, @@ -269,6 +270,8 @@ static int fit_image_process_sig(const char *keydir, const char *keyfile, node_name, image_name); return ret; } + /* Return the node that was written to */ + return ret; } return 0; @@ -645,7 +648,7 @@ int fit_image_add_verification_data(const char *keydir, const char *keyfile, fit, image_name, noffset, data, size, comment, require_keys, engine_id, cmdname); } - if (ret) + if (ret < 0) return ret; } @@ -974,6 +977,24 @@ static int fit_config_get_regions(const void *fit, int conf_noffset, return 0; } +/** + * fit_config_process_sig - Process a single subnode of the configurations/ node + * + * Generate a signed hash of the supplied data and store it in the node. + * + * @keydir: Directory containing keys to use for signing + * @keydest: Destination FDT blob to write public keys into (NULL if none) + * @fit: pointer to the FIT format image header + * @conf_name name of config being processed (used to display errors) + * @conf_noffset: Offset of configuration node, e.g. '/configurations/conf-1' + * @noffset: subnode offset, e.g. '/configurations/conf-1/sig-1' + * @comment: Comment to add to signature nodes + * @require_keys: Mark all keys as 'required' + * @engine_id: Engine to use for signing + * @cmdname: Command name used when reporting errors + * @return keydest node if @keydest is non-NULL, else 0 if none; -ve error code + * on failure + */ static int fit_config_process_sig(const char *keydir, const char *keyfile, void *keydest, void *fit, const char *conf_name, int conf_noffset, int noffset, const char *comment, @@ -1034,6 +1055,7 @@ static int fit_config_process_sig(const char *keydir, const char *keyfile, printf("Failed to add verification data for '%s' signature node in '%s' configuration node\n", node_name, conf_name); } + return ret; } return 0; @@ -1063,7 +1085,7 @@ static int fit_config_add_verification_data(const char *keydir, fit, conf_name, conf_noffset, noffset, comment, require_keys, engine_id, cmdname); } - if (ret) + if (ret < 0) return ret; } From patchwork Fri Nov 12 19:28:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1554563 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=Hh1lCGnm; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HrTGH3cGgz9s0r for ; Sat, 13 Nov 2021 06:31:03 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 80A268309A; Fri, 12 Nov 2021 20:29:54 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="Hh1lCGnm"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 3A89883036; Fri, 12 Nov 2021 20:29:18 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-oo1-xc30.google.com (mail-oo1-xc30.google.com [IPv6:2607:f8b0:4864:20::c30]) (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 33EBD83061 for ; Fri, 12 Nov 2021 20:29:03 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-oo1-xc30.google.com with SMTP id p2-20020a4adfc2000000b002c2676904fdso3256930ood.13 for ; Fri, 12 Nov 2021 11:29:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=D2C2pGU5AqWmVqxspxOr6ARnVD9DebDB5hL71LVJUIU=; b=Hh1lCGnmkEoGX8fCanb3z503qWiAv4jRxazs/4VAK1nzfrRmypoJeJD9FN1irqWdwa sfQ7xNCkNCTHsAPrpnt2HCDo02+TEuztdKRBO5+v3M5QrMyzh08sB53Ku5QrUitZaUfI dWAwJ1cy60IfWFQq1PnWLnhxzpBJi3L72MiaY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=D2C2pGU5AqWmVqxspxOr6ARnVD9DebDB5hL71LVJUIU=; b=08nf2sPISC7sfEgDkf0QqBZrwRKkJCPV0HtTM1e/xRwQcSJqDqFeJa/Il8dpj1AwVi aBW7KdJ1oNrouVZEA9ziyENGnCCT9LK0qIJyKa3ex20inSLo9MVxaVO2PEuyg+zdAfFW da3N8EneNhP91ALhhd6tWbtJgQq2MpeunDas8pKeueLiVtkATVn/IJ6IQW3dtsq3dWzS ayr+sArfVJyCsHnBOTljqRUnteh940pRzdRTF4nKH2rpcOK3rgrBwUe6G9Ia63MVo9kh Nw/DuAwBmVNoYqDJDq3QIwm50qX9F47diqdt4dGvc4zbmxVtY4cibIKXgqtANx9lQ5pj zlvQ== X-Gm-Message-State: AOAM5338XNyJ2F9PkoxHOfSa/LpgF374227Rzpzz/Qa5r9z59qbnWJJr ssIYK5FQcBWaoXOzog00O4J/GbmMWKfTVQ== X-Google-Smtp-Source: ABdhPJzxfbHst/NzNdJHkSuxLRbFI4v+ZiN+4v+mJhAj+Dkr6PHhFMkqcqpPkiuzwChn5plsR92TBg== X-Received: by 2002:a4a:ae0b:: with SMTP id z11mr9841378oom.25.1636745341216; Fri, 12 Nov 2021 11:29:01 -0800 (PST) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id n20sm1283527ooe.7.2021.11.12.11.28.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Nov 2021 11:29:00 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Rob Herring , Tom Rini , Bill Mills , Simon Glass , Alexandru Gagniuc , Jessica Clarke , Joe Hershberger , Joel Stanley , Marek Vasut , Martyn Welch , Ming Liu , Philippe Reynes , Stefano Babic , Sven Roederer , Thomas Hebb , Tyler Hicks , Vagrant Cascadian , Yann Dirson Subject: [PATCH 12/16] tools: mkimage: Show where signatures/keys are written Date: Fri, 12 Nov 2021 12:28:13 -0700 Message-Id: <20211112192817.199075-13-sjg@chromium.org> X-Mailer: git-send-email 2.34.0.rc1.387.gb447b232ab-goog In-Reply-To: <20211112192817.199075-1-sjg@chromium.org> References: <20211112192817.199075-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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.103.2 at phobos.denx.de X-Virus-Status: Clean At present mkimage displays the node information but it is not clear what signing action was taken. Add a message that shows it. For now it only supports showing a single signing action, since that is the common case. Sample: Signature written to 'sha1-basic/test.fit', node '/configurations/conf-1/signature' Public key written to 'sha1-basic/sandbox-u-boot.dtb', node '/signature/key-dev' Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- include/image.h | 23 ++++++++++++++++++++++- tools/fit_common.c | 13 +++++++++++++ tools/fit_common.h | 10 ++++++++++ tools/fit_image.c | 3 ++- tools/image-host.c | 23 ++++++++++++++++++----- tools/imagetool.h | 3 +++ tools/mkimage.c | 4 ++++ 7 files changed, 72 insertions(+), 7 deletions(-) diff --git a/include/image.h b/include/image.h index 0f5e037a192..733fa016694 100644 --- a/include/image.h +++ b/include/image.h @@ -1021,6 +1021,25 @@ int fit_cipher_data(const char *keydir, void *keydest, void *fit, const char *comment, int require_keys, const char *engine_id, const char *cmdname); +#define NODE_MAX_NAME_LEN 80 + +/** + * struct image_summary - Provides information about signing info added + * + * @sig_offset: Offset of the node in the blob devicetree where the signature + * was wriiten + * @sig_path: Path to @sig_offset + * @keydest_offset: Offset of the node in the keydest devicetree where the + * public key was written (-1 if none) + * @keydest_path: Path to @keydest_offset + */ +struct image_summary { + int sig_offset; + char sig_path[NODE_MAX_NAME_LEN]; + int keydest_offset; + char keydest_path[NODE_MAX_NAME_LEN]; +}; + /** * fit_add_verification_data() - add verification data to FIT image nodes * @@ -1031,6 +1050,7 @@ int fit_cipher_data(const char *keydir, void *keydest, void *fit, * @require_keys: Mark all keys as 'required' * @engine_id: Engine to use for signing * @cmdname: Command name used when reporting errors + * @summary: Returns information about what data was written * * Adds hash values for all component images in the FIT blob. * Hashes are calculated for all component images which have hash subnodes @@ -1045,7 +1065,8 @@ int fit_cipher_data(const char *keydir, void *keydest, void *fit, int fit_add_verification_data(const char *keydir, const char *keyfile, void *keydest, void *fit, const char *comment, int require_keys, const char *engine_id, - const char *cmdname); + const char *cmdname, + struct image_summary *summary); /** * fit_image_verify_with_data() - Verify an image with given data diff --git a/tools/fit_common.c b/tools/fit_common.c index d13e5ebf1ae..defdc9d5688 100644 --- a/tools/fit_common.c +++ b/tools/fit_common.c @@ -167,3 +167,16 @@ int copyfile(const char *src, const char *dst) return ret; } + +void summary_show(struct image_summary *summary, const char *imagefile, + const char *keydest) +{ + if (summary->sig_offset) { + printf("Signature written to '%s', node '%s'\n", imagefile, + summary->sig_path); + if (keydest) { + printf("Public key written to '%s', node '%s'\n", + keydest, summary->keydest_path); + } + } +} diff --git a/tools/fit_common.h b/tools/fit_common.h index 55f3f6acd4e..07fb718ae3a 100644 --- a/tools/fit_common.h +++ b/tools/fit_common.h @@ -52,4 +52,14 @@ int mmap_fdt(const char *cmdname, const char *fname, size_t size_inc, */ int copyfile(const char *src, const char *dst); +/** + * summary_show() - Show summary information about the signing process + * + * @summary: Summary info to show + * @imagefile: Filename of the output image + * @keydest: Filename where the key information is written (NULL if none) + */ +void summary_show(struct image_summary *summary, const char *imagefile, + const char *keydest); + #endif /* _FIT_COMMON_H_ */ diff --git a/tools/fit_image.c b/tools/fit_image.c index c4f56bb6967..aff27d0ffcb 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -73,7 +73,8 @@ static int fit_add_file_data(struct image_tool_params *params, size_t size_inc, params->comment, params->require_keys, params->engine_id, - params->cmdname); + params->cmdname, + ¶ms->summary); } if (dest_blob) { diff --git a/tools/image-host.c b/tools/image-host.c index e2b120ce532..fb9aa7493cc 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -1064,7 +1064,7 @@ static int fit_config_process_sig(const char *keydir, const char *keyfile, static int fit_config_add_verification_data(const char *keydir, const char *keyfile, void *keydest, void *fit, int conf_noffset, const char *comment, int require_keys, const char *engine_id, - const char *cmdname) + const char *cmdname, struct image_summary *summary) { const char *conf_name; int noffset; @@ -1084,9 +1084,20 @@ static int fit_config_add_verification_data(const char *keydir, ret = fit_config_process_sig(keydir, keyfile, keydest, fit, conf_name, conf_noffset, noffset, comment, require_keys, engine_id, cmdname); + if (ret < 0) + return ret; + + summary->sig_offset = noffset; + fdt_get_path(fit, noffset, summary->sig_path, + sizeof(summary->sig_path)); + + if (keydest) { + summary->keydest_offset = ret; + fdt_get_path(keydest, ret, + summary->keydest_path, + sizeof(summary->keydest_path)); + } } - if (ret < 0) - return ret; } return 0; @@ -1130,7 +1141,8 @@ int fit_cipher_data(const char *keydir, void *keydest, void *fit, int fit_add_verification_data(const char *keydir, const char *keyfile, void *keydest, void *fit, const char *comment, int require_keys, const char *engine_id, - const char *cmdname) + const char *cmdname, + struct image_summary *summary) { int images_noffset, confs_noffset; int noffset; @@ -1178,7 +1190,8 @@ int fit_add_verification_data(const char *keydir, const char *keyfile, ret = fit_config_add_verification_data(keydir, keyfile, keydest, fit, noffset, comment, require_keys, - engine_id, cmdname); + engine_id, cmdname, + summary); if (ret) return ret; } diff --git a/tools/imagetool.h b/tools/imagetool.h index e229a34ffc5..c0579c8c93c 100644 --- a/tools/imagetool.h +++ b/tools/imagetool.h @@ -21,6 +21,8 @@ #include #include +#include + #include "fdt_host.h" #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) @@ -83,6 +85,7 @@ struct image_tool_params { int bl_len; /* Block length in byte for external data */ const char *engine_id; /* Engine to use for signing */ bool reset_timestamp; /* Reset the timestamp on an existing image */ + struct image_summary summary; /* results of signing process */ }; /* diff --git a/tools/mkimage.c b/tools/mkimage.c index fbe883ce362..566607c489e 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -10,6 +10,7 @@ #include "imagetool.h" #include "mkimage.h" #include "imximage.h" +#include #include #include #ifdef __linux__ @@ -469,6 +470,9 @@ int main(int argc, char **argv) (void) munmap((void *)ptr, sbuf.st_size); (void) close (ifd); + if (!retval) + summary_show(¶ms.summary, params.imagefile, + params.keydest); exit (retval); } From patchwork Fri Nov 12 19:28:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1554566 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=IeGKNSgy; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HrTGy5n3Tz9s0r for ; Sat, 13 Nov 2021 06:31:38 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 53108830AB; Fri, 12 Nov 2021 20:30:24 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="IeGKNSgy"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 843DB83072; Fri, 12 Nov 2021 20:29:28 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-oo1-xc32.google.com (mail-oo1-xc32.google.com [IPv6:2607:f8b0:4864:20::c32]) (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 6944B83075 for ; Fri, 12 Nov 2021 20:29:05 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-oo1-xc32.google.com with SMTP id d1-20020a4a3c01000000b002c2612c8e1eso3267587ooa.6 for ; Fri, 12 Nov 2021 11:29:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=RDJRFOWaULWL62Z/usRaGlx7TTCWnTHYj3uV1MaPJME=; b=IeGKNSgyUOMylCczAqTtEn2Bx2c5LbL5miLgPpRVI/kJ1vDXtZRMc7/gni/H0l4CYl Rq+iiUIh1RdT59I+yYRF12Dx7er6xHy7I3L6HnRhUMcwlD+bk4vw+oGeRHb2V1ezDAb8 KG9ScxxTFYfPA7y3X7QezAJ19DDwgobnTS5YY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=RDJRFOWaULWL62Z/usRaGlx7TTCWnTHYj3uV1MaPJME=; b=z4W/OqNdUcZ2hHu0kUZd51yP96XGOWeVM1R7Q3h6O29rlpmxbnMWFmMJiAicPSukLU ymKRcA0oL/XexO8c/oJLYWYvOObl12486zd6zkZRfETtvlk48jJKXHi5avnrjGy3GSj1 93ha/j+1dFb4lXTsuLLYknfuJiwWHpfut+OB8kaKMF4jyfb6+SJGkjum4k1qYr3mHDwf Sirk3MKPWsrVJ/NOE27tanqYyUrz/nKYNNgJAPnrLEpSLXyDrYA6Ci8dvEVvx2+tgE3b rCsy9ZQ6dRULTBwoBob/vMk36I00yHZIXy+4Ep3d2JIrxpTyTyXWBAfnYc8QTTgpJ3aR gbrg== X-Gm-Message-State: AOAM531xSXK79iIPKRSwmSmTU8O1u5hURrv0yXkWp1lCQkEK0CjNtdhi N1fqmfFYDE1OpLXr9pi7bwkhbqTHgh9Z7w== X-Google-Smtp-Source: ABdhPJzwvqzRLot9R7EWRI3eSO4UnxwoVgWNJcvF7KZq166IdL/g37smQGdwQhdrMPF5PiRapMdcCg== X-Received: by 2002:a4a:6215:: with SMTP id x21mr9948772ooc.16.1636745342571; Fri, 12 Nov 2021 11:29:02 -0800 (PST) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id n20sm1283527ooe.7.2021.11.12.11.29.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Nov 2021 11:29:02 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Rob Herring , Tom Rini , Bill Mills , Simon Glass , AKASHI Takahiro , Alexandru Gagniuc , Chris Packham , Jessica Clarke , Martyn Welch , =?utf-8?q?Pali_Roh=C3=A1r?= , Stefan Roese , Tyler Hicks Subject: [PATCH 13/16] tools: Add a new tool to sign FDT blobs Date: Fri, 12 Nov 2021 12:28:14 -0700 Message-Id: <20211112192817.199075-14-sjg@chromium.org> X-Mailer: git-send-email 2.34.0.rc1.387.gb447b232ab-goog In-Reply-To: <20211112192817.199075-1-sjg@chromium.org> References: <20211112192817.199075-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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.103.2 at phobos.denx.de X-Virus-Status: Clean This works similarly to FIT signing except that it signs the entire FDT (with a few exclusions), rather than just FIT configurations or images. Also it is a stand-alone tool rather than being part of mkimage. The signature is added to the FDT so it can be checked later, to ensure that no modifications were made to the FDT. The /chosen node is excluded, since U-Boot may want to update it. Signed-off-by: Simon Glass --- include/image.h | 29 ++++ tools/Makefile | 8 +- tools/fdt-host.c | 333 ++++++++++++++++++++++++++++++++++++++++++++++ tools/fdt_host.h | 19 +++ tools/fdt_sign.c | 210 +++++++++++++++++++++++++++++ tools/imagetool.h | 1 + 6 files changed, 598 insertions(+), 2 deletions(-) create mode 100644 tools/fdt-host.c create mode 100644 tools/fdt_sign.c diff --git a/include/image.h b/include/image.h index 733fa016694..b2767883636 100644 --- a/include/image.h +++ b/include/image.h @@ -1154,6 +1154,35 @@ int fit_check_ramdisk(const void *fit, int os_noffset, int calculate_hash(const void *data, int data_len, const char *algo, uint8_t *value, int *value_len); +/** + * fdt_add_verif_data() - add verification data to an FDT blob + * + * @keydir: Directory containing keys + * @keyfile: Filename containing .key file + * @kwydest: FDT blob to write public key information to (NULL if none) + * @fit: Pointer to the FIT format image header + * @key_name: Name of key used to sign (used for node name and .crt file) + * @comment: Comment to add to signature nodes + * @require_keys: Mark all keys as 'required' + * @engine_id: Engine to use for signing + * @cmdname: Command name used when reporting errors + * @summary: Returns information about what data was written + * + * Adds hash values for all component images in the FIT blob. + * Hashes are calculated for all component images which have hash subnodes + * with algorithm property set to one of the supported hash algorithms. + * + * Also add signatures if signature nodes are present. + * + * returns + * 0, on success + * libfdt error code, on failure + */ +int fdt_add_verif_data(const char *keydir, const char *keyfile, void *keydest, + void *blob, const char *key_name, const char *comment, + bool require_keys, const char *engine_id, + const char *cmdname, struct image_summary *summary); + /* * At present we only support signing on the host, and verification on the * device diff --git a/tools/Makefile b/tools/Makefile index 1763f44cac4..07eca631cb0 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -72,12 +72,14 @@ hostprogs-y += mkenvimage mkenvimage-objs := mkenvimage.o os_support.o lib/crc32.o hostprogs-y += dumpimage mkimage -hostprogs-$(CONFIG_TOOLS_LIBCRYPTO) += fit_info fit_check_sign +hostprogs-$(CONFIG_TOOLS_LIBCRYPTO) += fit_info fit_check_sign \ + fdt_sign hostprogs-$(CONFIG_CMD_BOOTEFI_SELFTEST) += file2include FIT_OBJS-y := fit_common.o fit_image.o image-host.o boot/image-fit.o -FIT_SIG_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := image-sig-host.o boot/image-fit-sig.o +FIT_SIG_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := image-sig-host.o \ + boot/image-fit-sig.o fdt-host.o FIT_CIPHER_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := boot/image-cipher.o # The following files are synced with upstream DTC. @@ -154,6 +156,7 @@ dumpimage-objs := $(dumpimage-mkimage-objs) dumpimage.o mkimage-objs := $(dumpimage-mkimage-objs) mkimage.o fit_info-objs := $(dumpimage-mkimage-objs) fit_info.o fit_check_sign-objs := $(dumpimage-mkimage-objs) fit_check_sign.o +fdt_sign-objs := $(dumpimage-mkimage-objs) fdt_sign.o file2include-objs := file2include.o ifneq ($(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_TOOLS_LIBCRYPTO),) @@ -191,6 +194,7 @@ HOSTCFLAGS_fit_image.o += -DMKIMAGE_DTC=\"$(CONFIG_MKIMAGE_DTC_PATH)\" HOSTLDLIBS_dumpimage := $(HOSTLDLIBS_mkimage) HOSTLDLIBS_fit_info := $(HOSTLDLIBS_mkimage) HOSTLDLIBS_fit_check_sign := $(HOSTLDLIBS_mkimage) +HOSTLDLIBS_fdt_sign := $(HOSTLDLIBS_mkimage) hostprogs-$(CONFIG_EXYNOS5250) += mkexynosspl hostprogs-$(CONFIG_EXYNOS5420) += mkexynosspl diff --git a/tools/fdt-host.c b/tools/fdt-host.c new file mode 100644 index 00000000000..8aa0e099f2f --- /dev/null +++ b/tools/fdt-host.c @@ -0,0 +1,333 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2021 Google, LLC + * Written by Simon Glass + */ + +#include "mkimage.h" +#include +#include +#include + +/** + * fdt_setup_sig() - Setup the signing info ready for use + * + * @info: Info to set up + * @keydir: Directory holding private keys + * @keyfile: Filename of private or public key (NULL to find it in @keydir) + * @keyname: Name to use for key node if added + * @blob: FDT blob to sign + * @algo_name: Algorithm name to use for signing, e.g. "sha256,rsa2048" + * @padding_name: Padding method to use for signing, NULL if none + * @require_keys: Mark signing keys as 'required' (else they are optional) + * @engine_id: Engine to use for signin, NULL for default + * @return 0 if OK, -ENOMEM if out of memory, -ENOSYS if unsupported algorithm + */ +static int fdt_setup_sig(struct image_sign_info *info, const char *keydir, + const char *keyfile, const char *keyname, void *blob, + const char *algo_name, const char *padding_name, + const char *require_keys, const char *engine_id) +{ + memset(info, '\0', sizeof(*info)); + info->keydir = keydir; + info->keyfile = keyfile; + info->keyname = keyname; + info->fit = blob; + info->name = strdup(algo_name); + if (!info->name) { + printf("Out of memory for algo_name\n"); + return -ENOMEM; + } + info->checksum = image_get_checksum_algo(algo_name); + info->crypto = image_get_crypto_algo(algo_name); + info->padding = image_get_padding_algo(padding_name); + info->require_keys = require_keys; + info->engine_id = engine_id; + if (!info->checksum || !info->crypto) { + printf("Unsupported signature algorithm (%s)\n", algo_name); + return -ENOSYS; + } + + return 0; +} + +/** + * h_exclude_nodes() - Handles excluding certain nodes from the FDT + * + * This is called by fdt_next_region() when it wants to find out if a node or + * property should be included in the hash. + * + * This function simply omits the /chosen node as well as /signature and any + * subnodes. + * + * @return 0 if the node should be excluded, -1 for everything else (meaning it + * has no opinion) + */ +static int h_exclude_nodes(void *priv, const void *fdt, int offset, int type, + const char *data, int size) +{ + if (type == FDT_IS_NODE) { + /* Ignore the chosen node as well as /signature and subnodes */ + if (!strcmp("/chosen", data) || + !strncmp("/signature", data, 10)) + return 0; + } + + return -1; +} + +/** + * run_find_regions() - Use the fdt region calculation to get a list of regions + * + * This finds the regions of the FDT that need to be hashed so that it can be + * protected against modification by a signature + * + * @fdt: FDT blob to check + * @include_func: Function to call to determine whether to include an element of + * the devicetree + * @priv: Private data, set to NULL for now + * @region: Region list to fill in + * @max_regions: Max size of region list, e.g. 100 + * @path: Place to keep the path to each node (used by this function) + * @path_len: Max size of @path, 200 bytes is recommended + * @return 0 if OK, -FDT_ERR_... on error + */ +static int run_find_regions(const void *fdt, + int (*include_func)(void *priv, const void *fdt, + int offset, int type, + const char *data, int size), + void *priv, struct fdt_region *region, + int max_regions, char *path, int path_len, + int flags) +{ + struct fdt_region_state state; + int count; + int ret; + + count = 0; + ret = fdt_first_region(fdt, include_func, NULL, ®ion[count++], path, + path_len, flags, &state); + while (ret == 0) { + ret = fdt_next_region(fdt, include_func, NULL, + count < max_regions ? ®ion[count] : + NULL, path, path_len, flags, &state); + if (!ret) + count++; + } + if (ret && ret != -FDT_ERR_NOTFOUND) + return ret; + + return count; +} + +int fdt_get_regions(const void *blob, int strtab_len, + struct image_region **regionp, int *region_countp) +{ + struct image_region *region; + struct fdt_region fdt_regions[100]; + char path[200]; + int count; + + /* Get a list of regions to hash */ + count = run_find_regions(blob, h_exclude_nodes, NULL, fdt_regions, + ARRAY_SIZE(fdt_regions), path, sizeof(path), + FDT_REG_SUPERNODES | FDT_REG_ADD_MEM_RSVMAP | + FDT_REG_ADD_STRING_TAB); + if (count < 0) { + fprintf(stderr, "Failed to hash device tree\n"); + return -EIO; + } + if (count == 0) { + fprintf(stderr, "No data to hash for device tree"); + return -EINVAL; + } + + /* Limit the string table to what was hashed */ + if (strtab_len != -1) { + if (strtab_len < 0 || + strtab_len > fdt_regions[count - 1].size) { + fprintf(stderr, "Invalid string-table offset\n"); + return -EINVAL; + } + fdt_regions[count - 1].size = strtab_len; + } + + /* Build our list of data blocks */ + region = fit_region_make_list(blob, fdt_regions, count, NULL); + if (!region) { + fprintf(stderr, "Out of memory making region list'\n"); + return -ENOMEM; + } +#ifdef DEBUG + int i; + + printf("Regions:\n"); + for (i = 0; i < count; i++) { + printf("region %d: %x %x %x\n", i, fdt_regions[i].offset, + fdt_regions[i].size, + fdt_regions[i].offset + fdt_regions[i].size); + } +#endif + *region_countp = count; + *regionp = region; + + return 0; +} + +/** + * fdt_write_sig() - write the signature to an FDT + * + * This writes the signature and signer data to the FDT + * + * @blob: pointer to the FDT header + * @noffset: hash node offset + * @value: signature value to be set + * @value_len: signature value length + * @comment: Text comment to write (NULL for none) + * + * returns + * offset of node where things were added, on success + * -FDT_ERR_..., on failure + */ +static int fdt_write_sig(void *blob, uint8_t *value, int value_len, + const char *algo_name, const char *sig_name, + const char *comment, const char *cmdname) +{ + uint32_t strdata[2]; + int string_size; + int sigs_node, noffset; + int ret; + + /* + * Get the current string size, before we update the FIT and add + * more + */ + string_size = fdt_size_dt_strings(blob); + + sigs_node = fdt_subnode_offset(blob, 0, FIT_SIG_NODENAME); + if (sigs_node == -FDT_ERR_NOTFOUND) + sigs_node = fdt_add_subnode(blob, 0, FIT_SIG_NODENAME); + if (sigs_node < 0) + return sigs_node; + + /* Create a node for this signature */ + noffset = fdt_subnode_offset(blob, sigs_node, sig_name); + if (noffset == -FDT_ERR_NOTFOUND) + noffset = fdt_add_subnode(blob, sigs_node, sig_name); + if (noffset < 0) + return noffset; + + ret = fdt_setprop(blob, noffset, FIT_VALUE_PROP, value, value_len); + if (!ret) { + ret = fdt_setprop_string(blob, noffset, FIT_ALGO_PROP, + algo_name); + } + if (!ret) { + ret = fdt_setprop_string(blob, noffset, "signer-name", + "fdt_sign"); + } + if (!ret) { + ret = fdt_setprop_string(blob, noffset, "signer-version", + PLAIN_VERSION); + } + if (comment && !ret) + ret = fdt_setprop_string(blob, noffset, "comment", comment); + if (!ret) { + time_t timestamp = imagetool_get_source_date(cmdname, + time(NULL)); + uint32_t t = cpu_to_uimage(timestamp); + + ret = fdt_setprop(blob, noffset, FIT_TIMESTAMP_PROP, &t, + sizeof(uint32_t)); + } + + /* This is a legacy offset, it is unused, and must remain 0. */ + strdata[0] = 0; + strdata[1] = cpu_to_fdt32(string_size); + if (!ret) { + ret = fdt_setprop(blob, noffset, "hashed-strings", + strdata, sizeof(strdata)); + } + if (ret) + return ret; + + return noffset; +} + +static int fdt_process_sig(const char *keydir, const char *keyfile, + void *keydest, void *blob, const char *keyname, + const char *comment, int require_keys, + const char *engine_id, const char *cmdname, + struct image_summary *summary) +{ + struct image_sign_info info; + struct image_region *region; + int region_count; + uint8_t *value; + uint value_len; + int ret; + + ret = fdt_get_regions(blob, -1, ®ion, ®ion_count); + if (ret) + return ret; + ret = fdt_setup_sig(&info, keydir, keyfile, keyname, blob, + "sha256,rsa2048", NULL, require_keys ? "fdt" : NULL, + engine_id); + if (ret) + return ret; + + ret = info.crypto->sign(&info, region, region_count, &value, + &value_len); + free(region); + if (ret) { + fprintf(stderr, "Failed to sign FDT\n"); + + /* We allow keys to be missing */ + if (ret == -ENOENT) + return 0; + return -1; + } + + ret = fdt_write_sig(blob, value, value_len, info.name, keyname, comment, + cmdname); + if (ret < 0) { + if (ret == -FDT_ERR_NOSPACE) + return -ENOSPC; + printf("Can't write signature: %s\n", fdt_strerror(ret)); + return -1; + } + summary->sig_offset = ret; + fdt_get_path(blob, ret, summary->sig_path, + sizeof(summary->sig_path)); + free(value); + + /* Write the public key into the supplied FDT file */ + if (keydest) { + ret = info.crypto->add_verify_data(&info, keydest); + if (ret < 0) { + if (ret != -ENOSPC) + fprintf(stderr, "Failed to add verification data (err=%d)\n", + ret); + return ret; + } + summary->keydest_offset = ret; + fdt_get_path(keydest, ret, summary->keydest_path, + sizeof(summary->keydest_path)); + } + + return 0; +} + +/* This function exists just to mirror fit_image_add_verification_data() */ +int fdt_add_verif_data(const char *keydir, const char *keyfile, void *keydest, + void *blob, const char *keyname, const char *comment, + bool require_keys, const char *engine_id, + const char *cmdname, struct image_summary *summary) +{ + int ret; + + ret = fdt_process_sig(keydir, keyfile, keydest, blob, keyname, comment, + require_keys, engine_id, cmdname, summary); + + return ret; +} diff --git a/tools/fdt_host.h b/tools/fdt_host.h index bc42306c9e5..877f098676b 100644 --- a/tools/fdt_host.h +++ b/tools/fdt_host.h @@ -10,6 +10,8 @@ #include "../include/linux/libfdt.h" #include "../include/fdt_support.h" +struct image_region; + /** * fdt_remove_unused_strings() - Remove any unused strings from an FDT * @@ -38,4 +40,21 @@ int fdt_remove_unused_strings(const void *old, void *new); int fit_check_sign(const void *fit, const void *key, const char *fit_uname_config); +/** + * fdt_get_regions() - Get the regions to sign + * + * This calculates a list of node to hash for this particular configuration, + * then finds which regions of the devicetree they correspond to. + * + * @blob: Pointer to the FDT blob to sign + * @strtab_len: Length in bytes of the string table to sign, -1 to sign it all + * @regionp: Returns list of regions that need to be hashed (allocated; must be + * freed by the caller) + * @region_count: Returns number of regions + * @return 0 if OK, -ENOMEM if out of memory, -EIO if the regions to hash could + * not be found, -EINVAL if no registers were found to hash + */ +int fdt_get_regions(const void *blob, int strtab_len, + struct image_region **regionp, int *region_countp); + #endif /* __FDT_HOST_H__ */ diff --git a/tools/fdt_sign.c b/tools/fdt_sign.c new file mode 100644 index 00000000000..b3a7fb4f8bf --- /dev/null +++ b/tools/fdt_sign.c @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Sign an FDT file + * + * Copyright 2021 Google LLC + * Written by Simon Glass + */ + +#include "mkimage.h" +#include "fit_common.h" +#include + +void usage(char *cmdname) +{ + fprintf(stderr, + "Usage: %s -f dtb_file -G file.key -k dir [-K pub.dtb] [-o out_file]\n" + " -f ==> set dtb file which should be signed\n" + " -G ==> set signing key to use\n" + " -k ==> set directory containing private keys\n" + " -K ==> set DTB file to receive signing key\n" + " -o ==> if not provided, dtb file is updated\n" + " -S ==> name to use for signaure (defaults to -G)\n" + " -r ==> mark keys as required to be verified\n" + " -q ==> quiet mode\n", + cmdname); + exit(EXIT_FAILURE); +} + +/** + * sign_fdt() - Sign an FDT + * + * @params: Image parameters + * @destfile: Filename of FDT being signed (only used for messages) + * @size_inc: Amount to expand the FDT blob by, before adding signing data + * @blob: FDT blob to sign + * @size: Size of blob in bytes + * @return 0 if OK, -ve on error + */ +static int sign_fdt(struct image_tool_params *params, const char *destfile, + size_t size_inc, char *blob, int size) +{ + struct image_summary summary; + void *dest_blob = NULL; + struct stat dest_sbuf; + char def_name[80]; + int destfd = 0; + int ret; + + /* + * If we don't have a signature name, try to make one from the keyfile. + * '/path/to/dir/name.key' becomes 'name' + */ + if (!params->keyname) { + const char *p = strrchr(params->keyfile, '/'); + char *q; + + if (p) + p++; + else + p = params->keyfile; + strncpy(def_name, p, sizeof(def_name)); + def_name[sizeof(def_name) - 1] = '\0'; + q = strstr(def_name, ".key"); + if (q && q[strlen(q)] == '\0') + *q = '\0'; + params->keyname = def_name; + } + + if (params->keydest) { + destfd = mmap_fdt(params->cmdname, params->keydest, size_inc, + &dest_blob, &dest_sbuf, false, + false); + if (destfd < 0) { + ret = -EIO; + fprintf(stderr, "Cannot open keydest file '%s'\n", + params->keydest); + } + } + + ret = fdt_add_verif_data(params->keydir, params->keyfile, dest_blob, + blob, params->keyname, params->comment, + params->require_keys, params->engine_id, + params->cmdname, &summary); + if (!ret && !params->quiet) + summary_show(&summary, destfile, params->keydest); + + if (params->keydest) { + (void)munmap(dest_blob, dest_sbuf.st_size); + close(destfd); + } + if (ret < 0) { + if (ret != -ENOSPC) + fprintf(stderr, "Failed to add signature\n"); + return ret; + } + + return ret; +} + +/** + * do_fdt_sign() - Sign an FDT, expanding if needed + * + * If a separate output file is specified, the FDT blob is copied to that first. + * + * If there is not space in the FDT to add the signature, it is expanded + * slightly and the operation is retried. + * + * @params: Image parameters + * @cmdname: Name of tool (e.g. argv[0]), to use in error messages + * @fdtfile: Filename of FDT blob to sign + * @return 0 if OK, -ve on error + */ +static int do_fdt_sign(struct image_tool_params *params, const char *cmdname, + const char *fdtfile) +{ + const char *destfile; + struct stat fsbuf; + int ffd, size_inc; + void *blob; + int ret; + + destfile = params->outfile ? params->outfile : fdtfile; + for (size_inc = 0; size_inc < 64 * 1024;) { + if (params->outfile) { + if (copyfile(fdtfile, params->outfile) < 0) { + printf("Can't copy %s to %s\n", fdtfile, + params->outfile); + return -EIO; + } + } + ffd = mmap_fdt(cmdname, destfile, size_inc, &blob, &fsbuf, + params->outfile, false); + if (ffd < 0) + return -1; + + ret = sign_fdt(params, destfile, 0, blob, fsbuf.st_size); + (void)munmap((void *)blob, fsbuf.st_size); + close(ffd); + + if (ret >= 0 || ret != -ENOSPC) + break; + size_inc += 512; + debug("Not enough space in FDT '%s', trying size_inc=%#x\n", + destfile, size_inc); + } + + if (ret < 0) { + fprintf(stderr, "Failed to sign '%s' (error %d)\n", + destfile, ret); + return ret; + } + + return 0; +} + +int main(int argc, char **argv) +{ + struct image_tool_params params; + char *fdtfile = NULL; + char cmdname[256]; + int ret; + int c; + + memset(¶ms, '\0', sizeof(params)); + strncpy(cmdname, *argv, sizeof(cmdname) - 1); + cmdname[sizeof(cmdname) - 1] = '\0'; + while ((c = getopt(argc, argv, "f:G:k:K:o:qrS:")) != -1) + switch (c) { + case 'f': + fdtfile = optarg; + break; + case 'G': + params.keyfile = optarg; + break; + case 'k': + params.keydir = optarg; + break; + case 'K': + params.keydest = optarg; + break; + case 'o': + params.outfile = optarg; + break; + case 'q': + params.quiet = true; + break; + case 'r': + params.require_keys = true; + break; + case 'S': + params.keyname = optarg; + break; + default: + usage(cmdname); + break; + } + + if (!fdtfile) { + fprintf(stderr, "%s: Missing fdt file\n", *argv); + usage(*argv); + } + if (!params.keyfile) { + fprintf(stderr, "%s: Missing key file\n", *argv); + usage(*argv); + } + + ret = do_fdt_sign(¶ms, cmdname, fdtfile); + + exit(ret); +} diff --git a/tools/imagetool.h b/tools/imagetool.h index c0579c8c93c..4f9626fd1e0 100644 --- a/tools/imagetool.h +++ b/tools/imagetool.h @@ -70,6 +70,7 @@ struct image_tool_params { const char *keydir; /* Directory holding private keys */ const char *keydest; /* Destination .dtb for public key */ const char *keyfile; /* Filename of private or public key */ + const char *keyname; /* Name to use for key node if added */ const char *comment; /* Comment to add to signature node */ int require_keys; /* 1 to mark signing keys as 'required' */ int file_size; /* Total size of output file */ From patchwork Fri Nov 12 19:28:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1554565 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=JgGp9ur4; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HrTGj5L4nz9s0r for ; Sat, 13 Nov 2021 06:31:25 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 84B588309B; Fri, 12 Nov 2021 20:30:19 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="JgGp9ur4"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id EBD5483089; Fri, 12 Nov 2021 20:29:26 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.2 Received: from mail-ot1-x329.google.com (mail-ot1-x329.google.com [IPv6:2607:f8b0:4864:20::329]) (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 934C383069 for ; Fri, 12 Nov 2021 20:29:05 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-ot1-x329.google.com with SMTP id u18-20020a9d7212000000b00560cb1dc10bso15326190otj.11 for ; Fri, 12 Nov 2021 11:29:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/mgTBuhTSll8eKyM2AcR7nIJqLSQGDN7bg/ynLIvRKY=; b=JgGp9ur443dCLvxHE3hlnuheSvWr63blnqOJDxSdlHxKKFE9lA3GsymgKmaPFyqG+h lX8vtP3RfHR+v3kXMno7RJxoJLPNOyb5tP2WP30wuemlkTaOueh2ZVQmCgwaFi1j9FYl V5fI5L4TfvRf68nnocX+tgKzXOLPtkhdqVsj0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/mgTBuhTSll8eKyM2AcR7nIJqLSQGDN7bg/ynLIvRKY=; b=UgAniSjQgejMVdG8hPpZn/EPWH92stFbCp5nbANBFfk+iAWPgMTRAFyJ0XmirXJLVT 1OT9QQ/uVh/3czh6vu5Veg8tmXfbG34hhSIhWr6nu73ic+5eO8MOzPX7CD0lG7eFgVQc Vh5iHcMThNOGYQn0cgmhXfbC1ENkQiRzK4ZiyS8OFELgOTu1HuYrGZ1ecr/8UU7r+7vu UVCkBMzqxWQk2Aek7mU/CardQ9Jooq3TeOTCEt8O8RSF1f9D9pb1X8bfJvoBlMbmI6Sq rqTQp3iqAAkl+gNxhypwCFZmKKCrF9VoOY8vIcIOQ+VjzGVWnavoQsIhHVRZu6mq0/hX djQQ== X-Gm-Message-State: AOAM530O6o+BT0B61z7sL41zj0FZJpUsfqFzR2WPIIw8fAXixovN47sF +58qhRnW4+35SXkUhRxyR+iZxhB9iLn9lQ== X-Google-Smtp-Source: ABdhPJx9+ZQIRIemZaNHev95YP/9VBfY4cM8Xefm4oqOcr4DBh17jwTS3G8HWhFIhkvDiP3WlrWCQQ== X-Received: by 2002:a05:6830:280a:: with SMTP id w10mr13978367otu.78.1636745343759; Fri, 12 Nov 2021 11:29:03 -0800 (PST) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id n20sm1283527ooe.7.2021.11.12.11.29.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Nov 2021 11:29:03 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Rob Herring , Tom Rini , Bill Mills , Simon Glass , Alexandru Gagniuc , Chris Packham , Joel Stanley , =?utf-8?q?Pali_Roh=C3=A1r?= , Stefan Roese Subject: [PATCH 14/16] tools: Add a new tool to check FDT-blob signatures Date: Fri, 12 Nov 2021 12:28:15 -0700 Message-Id: <20211112192817.199075-15-sjg@chromium.org> X-Mailer: git-send-email 2.34.0.rc1.387.gb447b232ab-goog In-Reply-To: <20211112192817.199075-1-sjg@chromium.org> References: <20211112192817.199075-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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.103.2 at phobos.denx.de X-Virus-Status: Clean Add a stand-alone (from mkimage) tool that checks signatures in an FDT blob. Signed-off-by: Simon Glass --- tools/Makefile | 6 +- tools/fdt-host.c | 20 ++++ tools/fdt_check_sign.c | 85 ++++++++++++++ tools/fdt_host.h | 19 +++ tools/image-fdt-sig.c | 254 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 382 insertions(+), 2 deletions(-) create mode 100644 tools/fdt_check_sign.c create mode 100644 tools/image-fdt-sig.c diff --git a/tools/Makefile b/tools/Makefile index 07eca631cb0..b7857d86fac 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -73,13 +73,13 @@ mkenvimage-objs := mkenvimage.o os_support.o lib/crc32.o hostprogs-y += dumpimage mkimage hostprogs-$(CONFIG_TOOLS_LIBCRYPTO) += fit_info fit_check_sign \ - fdt_sign + fdt_sign fdt_check_sign hostprogs-$(CONFIG_CMD_BOOTEFI_SELFTEST) += file2include FIT_OBJS-y := fit_common.o fit_image.o image-host.o boot/image-fit.o FIT_SIG_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := image-sig-host.o \ - boot/image-fit-sig.o fdt-host.o + boot/image-fit-sig.o fdt-host.o image-fdt-sig.o FIT_CIPHER_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := boot/image-cipher.o # The following files are synced with upstream DTC. @@ -157,6 +157,7 @@ mkimage-objs := $(dumpimage-mkimage-objs) mkimage.o fit_info-objs := $(dumpimage-mkimage-objs) fit_info.o fit_check_sign-objs := $(dumpimage-mkimage-objs) fit_check_sign.o fdt_sign-objs := $(dumpimage-mkimage-objs) fdt_sign.o +fdt_check_sign-objs := $(dumpimage-mkimage-objs) fdt_check_sign.o file2include-objs := file2include.o ifneq ($(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_TOOLS_LIBCRYPTO),) @@ -195,6 +196,7 @@ HOSTLDLIBS_dumpimage := $(HOSTLDLIBS_mkimage) HOSTLDLIBS_fit_info := $(HOSTLDLIBS_mkimage) HOSTLDLIBS_fit_check_sign := $(HOSTLDLIBS_mkimage) HOSTLDLIBS_fdt_sign := $(HOSTLDLIBS_mkimage) +HOSTLDLIBS_fdt_check_sign := $(HOSTLDLIBS_mkimage) hostprogs-$(CONFIG_EXYNOS5250) += mkexynosspl hostprogs-$(CONFIG_EXYNOS5420) += mkexynosspl diff --git a/tools/fdt-host.c b/tools/fdt-host.c index 8aa0e099f2f..142d486091b 100644 --- a/tools/fdt-host.c +++ b/tools/fdt-host.c @@ -331,3 +331,23 @@ int fdt_add_verif_data(const char *keydir, const char *keyfile, void *keydest, return ret; } + +#ifdef CONFIG_FIT_SIGNATURE +int fdt_check_sign(const void *blob, const void *key) +{ + int fdt_sigs; + int ret; + + fdt_sigs = fdt_subnode_offset(blob, 0, FIT_SIG_NODENAME); + if (fdt_sigs < 0) { + printf("No %s node found (err=%d)\n", FIT_SIG_NODENAME, + fdt_sigs); + return fdt_sigs; + } + + ret = fdt_sig_verify(blob, fdt_sigs, key); + fprintf(stderr, "Verify %s\n", ret ? "failed" : "OK"); + + return ret; +} +#endif diff --git a/tools/fdt_check_sign.c b/tools/fdt_check_sign.c new file mode 100644 index 00000000000..943d01d5167 --- /dev/null +++ b/tools/fdt_check_sign.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Check a signature in an FDT file + * + * Copyright 2021 Google LLC + * Written by Simon Glass + */ + +#include "mkimage.h" +#include "fit_common.h" +#include + +void usage(char *cmdname) +{ + fprintf(stderr, + "Usage: %s -f dtb_file -k key file\n" + " -f ==> set dtb file which should be checked\n" + " -k ==> set key .dtb file which should be checked\n", + cmdname); + exit(EXIT_FAILURE); +} + +int main(int argc, char **argv) +{ + struct image_tool_params params; + char *fdtfile = NULL; + char *keyfile = NULL; + char cmdname[256]; + struct stat fsbuf; + struct stat ksbuf; + void *fdt_blob; + void *key_blob; + int ffd = -1; + int kfd = -1; + int ret; + int c; + + memset(¶ms, '\0', sizeof(params)); + strncpy(cmdname, *argv, sizeof(cmdname) - 1); + cmdname[sizeof(cmdname) - 1] = '\0'; + while ((c = getopt(argc, argv, "f:k:")) != -1) + switch (c) { + case 'f': + fdtfile = optarg; + break; + case 'k': + keyfile = optarg; + break; + default: + usage(cmdname); + break; + } + + if (!fdtfile) { + fprintf(stderr, "%s: Missing fdt file\n", *argv); + usage(*argv); + } + if (!keyfile) { + fprintf(stderr, "%s: Missing key file\n", *argv); + usage(*argv); + } + + ffd = mmap_fdt(cmdname, fdtfile, 0, &fdt_blob, &fsbuf, false, true); + if (ffd < 0) + return EXIT_FAILURE; + kfd = mmap_fdt(cmdname, keyfile, 0, &key_blob, &ksbuf, false, true); + if (kfd < 0) + return EXIT_FAILURE; + + ret = fdt_check_sign(fdt_blob, key_blob); + if (!ret) { + ret = EXIT_SUCCESS; + printf("Signature check OK\n"); + } else { + ret = EXIT_FAILURE; + fprintf(stderr, "Signature check bad (error %d)\n", ret); + } + + (void)munmap((void *)fdt_blob, fsbuf.st_size); + (void)munmap((void *)key_blob, ksbuf.st_size); + + close(ffd); + close(kfd); + exit(ret); +} diff --git a/tools/fdt_host.h b/tools/fdt_host.h index 877f098676b..b653efcb5d3 100644 --- a/tools/fdt_host.h +++ b/tools/fdt_host.h @@ -57,4 +57,23 @@ int fit_check_sign(const void *fit, const void *key, int fdt_get_regions(const void *blob, int strtab_len, struct image_region **regionp, int *region_countp); +/** + * fdt_check_sign() - Check signatures in an FDT blob + * + * @fdt: FDT blob to check + * @key: Key FDT blob to check against + * @return 0 if OK, -ve if any required signature failed + */ +int fdt_check_sign(const void *blob, const void *key); + +/** + * fdt_sig_verify() - Check signatures in an FDT blob + * + * @fdt: FDT blob to check + * @fit_sigs: Offset of /signatures node in the FDT + * @key: Key FDT blob to check against + * @return 0 if OK, -ve if any required signature failed + */ +int fdt_sig_verify(const void *blob, int fdt_sigs, const void *key); + #endif /* __FDT_HOST_H__ */ diff --git a/tools/image-fdt-sig.c b/tools/image-fdt-sig.c new file mode 100644 index 00000000000..8b2570cbb06 --- /dev/null +++ b/tools/image-fdt-sig.c @@ -0,0 +1,254 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2021 Google, LLC + * Written by Simon Glass + */ + +#include "mkimage.h" +#include +#include + +/** + * fdt_setup_sig() - Setup the signing info ready for use + * + * @info: Info to set up + * @blob: FDT blob to check + * @noffset: Offset of signature to verify, e.g. '/signatures/sig-1' + * @key_blob: FDT blob containing keys to verify against + * @required_keynode: Node containing the key to verify + * @err_msgp: Returns the error messages if something goes wrong + * @return 0 if OK, -E2BIG if the FDT is too large, -ENOSYS if unsupported + * algorithm, -EINVAL if the algorithm name is not present in the signature + */ +static int fdt_image_setup_verify(struct image_sign_info *info, + const void *blob, int noffset, + const void *key_blob, int required_keynode, + char **err_msgp) +{ + char *algo_name; + const char *padding_name; + + if (fdt_totalsize(blob) > CONFIG_VAL(FIT_SIGNATURE_MAX_SIZE)) { + *err_msgp = "Total size too large"; + return -E2BIG; + } + if (fit_image_hash_get_algo(blob, noffset, &algo_name)) { + *err_msgp = "Can't get hash algo property"; + return -EINVAL; + } + + padding_name = fdt_getprop(blob, noffset, "padding", NULL); + if (!padding_name) + padding_name = RSA_DEFAULT_PADDING_NAME; + + memset(info, '\0', sizeof(*info)); + info->keyname = fdt_getprop(blob, noffset, FIT_KEY_HINT, NULL); + info->fit = blob; + info->node_offset = noffset; + info->name = algo_name; + info->checksum = image_get_checksum_algo(algo_name); + info->crypto = image_get_crypto_algo(algo_name); + info->padding = image_get_padding_algo(padding_name); + info->fdt_blob = key_blob; + info->required_keynode = required_keynode; + + if (!info->checksum || !info->crypto || !info->padding) { + *err_msgp = "Unknown signature algorithm"; + return -ENOSYS; + } + + return 0; +} + +/** + * fdt_verify_sig() - Verify that a signature can be verified with a key + * + * This checks a particular key to see if it verifies the given signature + * + * @blob: FDT blob to verify + * @noffset: Offset of signature to verify, e.g. '/signatures/sig-1' + * @key_blob: FDT blob containing keys to verify against + * @required_keynode: Node containing the key to verify + * @err_msgp: Returns the error messages if something goes wrong + * @return 0 if OK, -EPERM if the key could not be verified + */ +static int fdt_check_sig(const void *blob, int noffset, const void *key_blob, + int required_keynode, char **err_msgp) +{ + int region_count, strtab_len; + struct image_sign_info info; + struct image_region *region; + const uint32_t *strings; + uint8_t *fdt_value; + int fdt_value_len; + int size; + int ret; + + if (fdt_image_setup_verify(&info, blob, noffset, key_blob, + required_keynode, err_msgp)) + return -EPERM; + + if (fit_image_hash_get_value(blob, noffset, &fdt_value, + &fdt_value_len)) { + *err_msgp = "Can't get hash value property"; + return -EPERM; + } + + /* Add the strings */ + strings = fdt_getprop(blob, noffset, "hashed-strings", &size); + if (!strings) { + *err_msgp = "Missing 'hashed-strings' property"; + return -EINVAL; + } + if (size != sizeof(u32) * 2) { + *err_msgp = "Invalid 'hashed-strings' property"; + return -EINVAL; + } + strtab_len = fdt32_to_cpu(strings[1]); + debug("%s: strtab_len=%x\n", __func__, strtab_len); + + ret = fdt_get_regions(blob, strtab_len, ®ion, ®ion_count); + if (ret) { + *err_msgp = "Cannot get regions"; + return ret; + } + + ret = info.crypto->verify(&info, region, region_count, fdt_value, + fdt_value_len); + free(region); + if (ret) { + *err_msgp = "Verification failed"; + return -EPERM; + } + + return 0; +} + +/** + * fdt_verify_sig() - Verify that a signature exists for a key + * + * This checks a particular key to see if it verifies. It tries all signatures + * to find a match. + * + * @blob: FDT blob to verify + * @fdt_sigs: Offset of /signatures node in blob + * @key_blob: FDT blob containing keys to verify against + * @required_keynode: Node containing the key to verify + * @return 0 if OK, -EPERM if the key could not be verified + */ +static int fdt_verify_sig(const void *blob, int fdt_sigs, + const void *key_blob, int required_keynode) +{ + char *err_msg = "No 'signature' subnode found"; + int bad_noffset = -1; + int noffset; + int verified = 0; + int ret; + + /* Process all subnodes of the /signature node */ + fdt_for_each_subnode(noffset, blob, fdt_sigs) { + printf("%s", fdt_get_name(blob, noffset, NULL)); + ret = fdt_check_sig(blob, noffset, key_blob, required_keynode, + &err_msg); + if (ret) { + printf("- "); + bad_noffset = noffset; + } else { + printf("+ "); + verified = 1; + break; + } + } + + if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) { + err_msg = "Corrupted or truncated tree"; + goto error; + } + + if (verified) { + printf("\n"); + return 0; + } + +error: + printf(" error!\n%s for node '%s'\n", err_msg, + fdt_get_name(blob, bad_noffset, NULL)); + return -EPERM; +} + +/** + * fdt_verify_required_sigs() - Verify that required signatures are valid + * + * This works through all the provided keys, checking for a signature that uses + * that key. If the key is required, then it must verify correctly. If it is not + * required, then the failure is ignored, just displayed for informational + * purposes. + * + * If the "required-mode" property is present and set to "any" then only one of + * the required keys needs to be verified + * + * @blob: FDT blob to verify + * @fdt_sigs: Offset of /signatures node in blob + * @key_blob: FDT blob containing keys to verify against + * @return 0 if OK, -EPERM if required keys could not be verified (either any or + * all), -EINVAL if the FDT is missing something + */ +static int fdt_verify_required_sigs(const void *blob, int fdt_sigs, + const void *key_blob) +{ + int key_node; + int keys_node; + int verified = 0; + int reqd_sigs = 0; + bool reqd_policy_all = true; + const char *reqd_mode; + + /* Work out what we need to verify */ + keys_node = fdt_subnode_offset(key_blob, 0, FIT_SIG_NODENAME); + if (keys_node < 0) { + debug("%s: No signature node found: %s\n", __func__, + fdt_strerror(keys_node)); + return 0; + } + + /* Get required-mode policy property from DTB */ + reqd_mode = fdt_getprop(key_blob, keys_node, "required-mode", NULL); + if (reqd_mode && !strcmp(reqd_mode, "any")) + reqd_policy_all = false; + + debug("%s: required-mode policy set to '%s'\n", __func__, + reqd_policy_all ? "all" : "any"); + + /* Check each key node */ + fdt_for_each_subnode(key_node, key_blob, keys_node) { + const char *required_prop; + bool required; + int ret; + + required_prop = fdt_getprop(key_blob, key_node, FIT_KEY_REQUIRED, + NULL); + required = required_prop && !strcmp(required_prop, "fdt"); + + if (required) + reqd_sigs++; + + ret = fdt_verify_sig(blob, fdt_sigs, key_blob, key_node); + if (!ret && required) + verified++; + } + + if (reqd_policy_all && reqd_sigs != verified) { + fprintf(stderr, "Failed to verify all required signature\n"); + return -EPERM; + } else if (reqd_sigs && !verified) { + fprintf(stderr, "Failed to verify 'any' of the required signature(s)\n"); + return -EPERM; + } + + return 0; +} + +int fdt_sig_verify(const void *blob, int fdt_sigs, const void *key) +{ + return fdt_verify_required_sigs(blob, fdt_sigs, key); +} From patchwork Fri Nov 12 19:28:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1554564 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=lTTjpR1I; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HrTGW1JQ2z9s0r for ; Sat, 13 Nov 2021 06:31:13 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 26D9783061; Fri, 12 Nov 2021 20:30:10 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="lTTjpR1I"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id F19AF83069; Fri, 12 Nov 2021 20:29:28 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-oi1-x230.google.com (mail-oi1-x230.google.com [IPv6:2607:f8b0:4864:20::230]) (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 6EF6383070 for ; Fri, 12 Nov 2021 20:29:06 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-oi1-x230.google.com with SMTP id q25so14192029oiw.0 for ; Fri, 12 Nov 2021 11:29:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=gxGChbDyTgCSosUbCEMMpjhPqud0irx6lpIUc9tSZQo=; b=lTTjpR1IM3Gq8r1s0TgOq8p7wlOODdF87hRfAe8SA7QWZ4Au261aFR0HaBrw9Fyljm 3aC4de8IRpZcKrPfa24JKfCUcLaxt+scbK1/hlL9CUkY+rwqNt5bt4kcQPKeGci6Ap/F 9sijj2J/T1ICPEpRBEQ7A/grKhAkXetvuY7F0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gxGChbDyTgCSosUbCEMMpjhPqud0irx6lpIUc9tSZQo=; b=1a3Rjyr4DqOo9ImMiqPRoA7ODmgvf0GHhMEZdFHRgYapqtmHjcA/H8gZpBhTn5rYuF d7GpgH+RCZC0l0ohJ7OVcciCMLXKGqshipzVk2FgdBDv6w4+bSO+DhWzHG1I9hclo8FL 66RfsgwDKIWMmiWOCJZK4E41Y0X/S4PyBQl/N1MZba8sv2Hy12w1Xxn961BetJ9EpKrk fjKE32kW4r+NsOl/MYpfOR012K7I5LaRkBeeP9yiyz0YtJe1halJXiA8PPx8L42aouKs 9PpH5SkkYDzFLJqOH9+jTB0gW+sG1HgvsMZiXLeumR9qc/Vhse2oKB/SrgZ2mW7fO0J5 Pfzw== X-Gm-Message-State: AOAM53366u5xDGFtXTizYBvy+5o5Xbh34saNOP621P2qiWebtHppaePn hYZ3rDno3XxxQPwQ6jXr3Gk4I72Arl+9hA== X-Google-Smtp-Source: ABdhPJw6/asj2FWXd2qnhRkGmLpt2Ipww8rDtCbs46ETghb4DilcasgSRE/c5PnxBFBhGjHpxa74cQ== X-Received: by 2002:a05:6808:11c9:: with SMTP id p9mr27697145oiv.169.1636745344904; Fri, 12 Nov 2021 11:29:04 -0800 (PST) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id n20sm1283527ooe.7.2021.11.12.11.29.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Nov 2021 11:29:04 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Rob Herring , Tom Rini , Bill Mills , Simon Glass Subject: [PATCH 15/16] test: Add a test for FDT signing Date: Fri, 12 Nov 2021 12:28:16 -0700 Message-Id: <20211112192817.199075-16-sjg@chromium.org> X-Mailer: git-send-email 2.34.0.rc1.387.gb447b232ab-goog In-Reply-To: <20211112192817.199075-1-sjg@chromium.org> References: <20211112192817.199075-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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.103.2 at phobos.denx.de X-Virus-Status: Clean Add a test which checks that signing and checking work, including signing an FDT twice. Signed-off-by: Simon Glass --- test/py/tests/test_fdt_sign.py | 83 ++++++++++++++++++++++++++++++++ test/py/tests/test_vboot.py | 21 ++------ test/py/tests/vboot/sign-fdt.dts | 23 +++++++++ test/py/tests/vboot_comm.py | 22 +++++++++ 4 files changed, 131 insertions(+), 18 deletions(-) create mode 100644 test/py/tests/test_fdt_sign.py create mode 100644 test/py/tests/vboot/sign-fdt.dts create mode 100644 test/py/tests/vboot_comm.py diff --git a/test/py/tests/test_fdt_sign.py b/test/py/tests/test_fdt_sign.py new file mode 100644 index 00000000000..72d58211159 --- /dev/null +++ b/test/py/tests/test_fdt_sign.py @@ -0,0 +1,83 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2021 Google LLC +# +# U-Boot FDT-signing test + +import os + +import u_boot_utils as util +import vboot_comm + +def test_fdt_sign(u_boot_console): + def dtc(dts): + """Run the device tree compiler to compile a .dts file + + The output file will be the same as the input file but with a .dtb + extension. + + Args: + dts: Device tree file to compile. + """ + dtb = dts.replace('.dts', '.dtb') + util.run_and_log(cons, 'dtc %s %s%s -O dtb -p 0x1000 ' + '-o %s%s' % (dtc_args, datadir, dts, tmpdir, dtb)) + + cons = u_boot_console + datadir = os.path.join(cons.config.source_dir, 'test/py/tests/vboot/') + fdt_sign = os.path.join(cons.config.build_dir, 'tools/fdt_sign') + fdt_check_sign = os.path.join(cons.config.build_dir, 'tools/fdt_check_sign') + + tmpdir = os.path.join(cons.config.result_dir, 'fdt_sign') + '/' + if not os.path.exists(tmpdir): + os.mkdir(tmpdir) + + dtb = '%ssandbox-u-boot.dtb' % tmpdir + dtc_args = '-I dts -O dtb -i %s' % tmpdir + dtc('sign-fdt.dts') + dtc('sandbox-u-boot.dts') + + vboot_comm.create_rsa_pair(cons, tmpdir, 'dev') + + # Sign and check that it verifies + signed = os.path.join(tmpdir, 'sign-fdt.dtb') + cmd = [fdt_sign, '-f', signed, '-G', os.path.join(tmpdir, 'dev.key'), + '-K', dtb, '-k', tmpdir, '-r'] + util.run_and_log(cons, ' '.join(cmd)) + + cmd = [fdt_check_sign, '-f', signed, '-k', dtb] + util.run_and_log(cons, ' '.join(cmd)) + + # Update the chosen node, which dpes not affect things since the signature + # omits that node + util.run_and_log(cons, 'fdtput -t bx %s /chosen fred 1' % signed) + + cmd = [fdt_check_sign, '-f', signed, '-k', dtb] + util.run_and_log(cons, ' '.join(cmd)) + + # Update the alias node, which should break things because that is included + # in the signature + util.run_and_log(cons, 'fdtput -t bx %s /aliases fred 1' % signed) + + cmd = [fdt_check_sign, '-f', signed, '-k', dtb] + util.run_and_log_expect_exception(cons, cmd, 1, 'Verification failed') + + # Regenerate the original devictree and sign it + dtc('sign-fdt.dts') + dtc('sandbox-u-boot.dts') + out = os.path.join(tmpdir, 'out-fdt.dtb') + cmd = [fdt_sign, '-f', signed, '-G', os.path.join(tmpdir, 'dev.key'), + '-K', dtb, '-k', tmpdir, '-r', '-o', out] + util.run_and_log(cons, ' '.join(cmd)) + + cmd = [fdt_check_sign, '-f', out, '-k', dtb] + util.run_and_log(cons, ' '.join(cmd)) + + # Create a new key and sign with that too + vboot_comm.create_rsa_pair(cons, tmpdir, 'prod') + cmd = [fdt_sign, '-f', out, '-G', os.path.join(tmpdir, 'prod.key'), + '-K', dtb, '-k', tmpdir, '-r'] + util.run_and_log(cons, ' '.join(cmd)) + + # Now check that both signatures are valid + cmd = [fdt_check_sign, '-f', out, '-k', dtb] + util.run_and_log(cons, ' '.join(cmd)) diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py index 095e00cce36..8458210691d 100644 --- a/test/py/tests/test_vboot.py +++ b/test/py/tests/test_vboot.py @@ -29,6 +29,7 @@ import shutil import struct import pytest import u_boot_utils as util +import vboot_comm import vboot_forge import vboot_evil @@ -173,22 +174,6 @@ def test_vboot(u_boot_console, name, sha_algo, padding, sign_options, required, handle.write(struct.pack(">I", size)) return struct.unpack(">I", total_size)[0] - def create_rsa_pair(name): - """Generate a new RSA key paid and certificate - - Args: - name: Name of of the key (e.g. 'dev') - """ - public_exponent = 65537 - util.run_and_log(cons, 'openssl genpkey -algorithm RSA -out %s%s.key ' - '-pkeyopt rsa_keygen_bits:2048 ' - '-pkeyopt rsa_keygen_pubexp:%d' % - (tmpdir, name, public_exponent)) - - # Create a certificate containing the public key - util.run_and_log(cons, 'openssl req -batch -new -x509 -key %s%s.key ' - '-out %s%s.crt' % (tmpdir, name, tmpdir, name)) - def test_with_algo(sha_algo, padding, sign_options): """Test verified boot with the given hash algorithm. @@ -377,8 +362,8 @@ def test_vboot(u_boot_console, name, sha_algo, padding, sign_options, required, dtb = '%ssandbox-u-boot.dtb' % tmpdir sig_node = '/configurations/conf-1/signature' - create_rsa_pair('dev') - create_rsa_pair('prod') + vboot_comm.create_rsa_pair(cons, tmpdir, 'dev') + vboot_comm.create_rsa_pair(cons, tmpdir, 'prod') # Create a number kernel image with zeroes with open('%stest-kernel.bin' % tmpdir, 'wb') as fd: diff --git a/test/py/tests/vboot/sign-fdt.dts b/test/py/tests/vboot/sign-fdt.dts new file mode 100644 index 00000000000..2c5b84976b1 --- /dev/null +++ b/test/py/tests/vboot/sign-fdt.dts @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + model = "Google Snow"; + chosen { + bootargs = "console=tty1"; + stdout-path = "serial3:115200n8"; + }; + aliases { + serail0 = "/serial@12c30000"; + }; + + serial@12c30000 { + compatible = "samsung,exynos4210-uart"; + reg = <0x12c30000 0x00000100>; + u-boot,dm-pre-reloc; + }; +}; diff --git a/test/py/tests/vboot_comm.py b/test/py/tests/vboot_comm.py new file mode 100644 index 00000000000..7e1690e89f8 --- /dev/null +++ b/test/py/tests/vboot_comm.py @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2021 Google LLC +# +# Common functions + +import u_boot_utils as util + +def create_rsa_pair(cons, tmpdir, name): + """Generate a new RSA key pair and certificate + + Args: + name: Name of the key (e.g. 'dev') + """ + public_exponent = 65537 + util.run_and_log(cons, 'openssl genpkey -algorithm RSA -out %s%s.key ' + '-pkeyopt rsa_keygen_bits:2048 ' + '-pkeyopt rsa_keygen_pubexp:%d' % + (tmpdir, name, public_exponent)) + + # Create a certificate containing the public key + util.run_and_log(cons, 'openssl req -batch -new -x509 -key %s%s.key ' + '-out %s%s.crt' % (tmpdir, name, tmpdir, name)) From patchwork Fri Nov 12 19:28:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1554567 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=ZntpLIUy; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HrTHC354Jz9s0r for ; Sat, 13 Nov 2021 06:31:51 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id DE169830AE; Fri, 12 Nov 2021 20:30:28 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="ZntpLIUy"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 405F483070; Fri, 12 Nov 2021 20:29:29 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-oi1-x22e.google.com (mail-oi1-x22e.google.com [IPv6:2607:f8b0:4864:20::22e]) (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 7BC5183081 for ; Fri, 12 Nov 2021 20:29:07 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-oi1-x22e.google.com with SMTP id 7so9613244oip.12 for ; Fri, 12 Nov 2021 11:29:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=AGBUFDa1rY5dDLR3kQEtyXsrexdZhzfctPb5OcEWxAk=; b=ZntpLIUy0yXLubPfFbZeYhF0c9+NV2n5Z4HCOdBqdYn158p6+LDwT5iL4bxTDmmnb6 EgZ+GqW8GwvdpfUDz0xS6Sev1lfa1D6Dg4zBa+fdLz+XKnoDobI7YSS6m5V2fE8AfatA ey37tYXm4fousD90MXrjzJsZW2ZG5RCTqsrrs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=AGBUFDa1rY5dDLR3kQEtyXsrexdZhzfctPb5OcEWxAk=; b=kr42n74BbuEWhw62L8gAEGLMJIaP2xFE0+/5bF8e7DehibpkU/9mpMezFSaX60eCTb Cmmak0B6f9FI+M/DGu0tHTJ3HCuJBHaBc9h14bPbinYLUvwRkRCDfTYZQuru4hIdcmNU aVm+eeHCAZSKS0xLLKBpdAu/4TnvkBR9Savh3V/sosbK1BazikRC/+srsRB6HaUoFuAB mGmHWscPGRxtUMd79ZOsKJVbs42x9ooU7PKTP9x91IxsGHJBr7UzTldYqEUP6fNoP+F+ 1xiA4ltDswZE9WIwxRc06whrEFA8FlCbWU0exHCRcIEWge56Aw1WJXTb2tLuB/n2l+qP +Oaw== X-Gm-Message-State: AOAM531Dt2sf94F/c61OXqybKxmGf84FpR7hp8OFOvl/sdTo36tWrA/g lwbtijCt6+n1LdDTOcPEwP7Jb63UnK0E5w== X-Google-Smtp-Source: ABdhPJwZnpdjhFBdsh89okbdpfmFFFI6scn6tnlCOj+AsFZmyGAKC5kDrKaKDGXRzgANSgnWm2WObg== X-Received: by 2002:a05:6808:23c3:: with SMTP id bq3mr14922646oib.124.1636745345845; Fri, 12 Nov 2021 11:29:05 -0800 (PST) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id n20sm1283527ooe.7.2021.11.12.11.29.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Nov 2021 11:29:05 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Rob Herring , Tom Rini , Bill Mills , Simon Glass Subject: [PATCH 16/16] tools: Add man pages for fdt_sign and fdt_check_sign Date: Fri, 12 Nov 2021 12:28:17 -0700 Message-Id: <20211112192817.199075-17-sjg@chromium.org> X-Mailer: git-send-email 2.34.0.rc1.387.gb447b232ab-goog In-Reply-To: <20211112192817.199075-1-sjg@chromium.org> References: <20211112192817.199075-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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.103.2 at phobos.denx.de X-Virus-Status: Clean Add some documentation for these tools, along with a MAINTAINER entry. Signed-off-by: Simon Glass --- MAINTAINERS | 7 +++ doc/fdt_check_sign.1 | 74 +++++++++++++++++++++++++++++ doc/fdt_sign.1 | 111 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+) create mode 100644 doc/fdt_check_sign.1 create mode 100644 doc/fdt_sign.1 diff --git a/MAINTAINERS b/MAINTAINERS index 00ff572d4d2..9f476d03eb0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -780,6 +780,13 @@ F: cmd/fdt.c F: common/fdt_support.c F: scripts/dtc-version.sh +FDT SIGNING +M: Simon Glass +S: Maintained +F: doc/fdt_*sign.1 +F: tools/fdt_check_sign.c +F: tools/fdt_sign.c + FREEBSD M: Rafal Jaworowski S: Maintained diff --git a/doc/fdt_check_sign.1 b/doc/fdt_check_sign.1 new file mode 100644 index 00000000000..ca4d338a92b --- /dev/null +++ b/doc/fdt_check_sign.1 @@ -0,0 +1,74 @@ +.TH FDT_CHECK_SIGN 1 "2021-11-11" + +.SH NAME +fdt_check_sign \- Check the signature in a flat device tree (FDT) file +.SH SYNOPSIS +.B fdt_check_sign +.RB [\fIoptions\fP] " \-f [" "device tree binary file" "] " \-K " [" "key file" "]" + +.SH "DESCRIPTION" +The +.B fdt_check_sign +command is used to check the signatures in a device tree binary file (.dtb +file) to ensure it has not been modified since it was signed. + +Permitted modifications are to the +.B /chosen +node and +.B /signature +node/subnodes only. + +.SH "OPTIONS" + +.TP +.BI "\-f [" "device tree binary file" "]" +Selects the .dtb file to check. + +.TP +.BI "\-k [" "key directory" "]" +Selects the device tree binary file containing the public key to check against. + +.SH EXAMPLES + +.P +Generate a key pair with openssl: + +.nf + $ openssl genpkey -algorithm RSA -out name.key \\ + -pkeyopt rsa_keygen_bits:2048 \\ + -pkeyopt rsa_keygen_pubexp:65537 + $ openssl req -batch -new -x509 -key name.key -out name.crt +.fi + +.P +Create a .dtb file to accept the public key, called pubkey.dtb in this example. + + # echo "/dts-v1/; /{};" | dtc - -o pubkey.dtb + +Sign a device tree binary: + +.nf + $ fdt_sign -f input.dtb -G name.key -K pubkey.dtb -k . -r + Signature written to 'input.dtb', node '/signature/name' + Public key written to 'pubkey.dtb', node '/signature/key-name +.fi + +.P +Check the signatures: + +.nf + $ fdt_check_sign -f input.dtb -k pubkey.dtb + name+ + Verify OK + Signature check OK +.fi + +.SH SEE ALSO + +fdt_sign + +.SH HOMEPAGE +http://www.denx.de/wiki/U-Boot/WebHome +.PP +.SH AUTHOR +This manual page was written by Simon Glass . diff --git a/doc/fdt_sign.1 b/doc/fdt_sign.1 new file mode 100644 index 00000000000..39f8bdc2a40 --- /dev/null +++ b/doc/fdt_sign.1 @@ -0,0 +1,111 @@ +.TH FDT_SIGN 1 "2021-11-11" + +.SH NAME +fdt_sign \- Sign a flat device tree (FDT) file +.SH SYNOPSIS +.B fdt_sign +.RB [\fIoptions\fP] " \-f [" "device tree binary file" "] " \-G " [" "key file" "]" + +.SH "DESCRIPTION" +The +.B fdt_sign +command is used to sign device tree binary files (.dtb files) so that they be +protected against unwanted modification. + +.B fdt_sign +adds a /signature node to the FDT, if not already present, then adds a node with +the signature itself, in a simplified format. It uses a private key to generate +the signature. + +.B fdt_check_sign +can then be used to verify the signature against a public key. + +The /chosen node is ignored when signing. A /signature node is added containing +the signature. + +.SH "OPTIONS" + +.TP +.BI "\-f [" "device tree binary file" "]" +Selects the .dtb file to sign. + +.TP +.BI "\-G [" "key file" "]" +Selects the key file to sign with. This should be a .key file containing an +RSA private key. + +.TP +.BI "\-k [" "key directory" "]" +Selects the directory containing the key file. + +.TP +.BI "\-K [" "key .dtb file" "]" +Selects the device tree binary file to write the public key into. This is +updated with a /signature subnode containing the public key the can be used to +verify the signed device tree. + +.TP +.BI "\-o [" "output file" "]" +Selects the output file to write to. If omitted, the device tree binary file is +updated in-place and only the +.B -f +parameter is used. + +.TP +.BI "\-q +Selects quiet mode which supresses non-error output. + +.TP +.BI "\-r +Marks the key as 'required', meaning that it must be used to check a signature +in the device tree, when fdt_check_sign is used. + +.TP +.BI "\-S +Selects the key name to sign with. This is optional and defaults to the base +name of the key file. + +.SH EXAMPLES + +.P +Generate a key pair with openssl: + +.nf + $ openssl genpkey -algorithm RSA -out name.key \\ + -pkeyopt rsa_keygen_bits:2048 \\ + -pkeyopt rsa_keygen_pubexp:65537 + $ openssl req -batch -new -x509 -key name.key -out name.crt +.fi + +.P +Create a .dtb file to accept the public key, called pubkey.dtb in this example. + + # echo "/dts-v1/; /{};" | dtc - -o pubkey.dtb + +Sign a device tree binary: + +.nf + $ fdt_sign -f input.dtb -G name.key -K pubkey.dtb -k . -r + Signature written to 'input.dtb', node '/signature/name' + Public key written to 'pubkey.dtb', node '/signature/key-name +.fi + +.P +Check the signatures: + +.nf + $ fdt_check_sign -f input.dtb -k pubkey.dtb + name+ + Verify OK + Signature check OK +.fi + +.SH SEE ALSO + +fdt_check_sign + +.SH HOMEPAGE +http://www.denx.de/wiki/U-Boot/WebHome +.PP +.SH AUTHOR +This manual page was written by Simon Glass .