From patchwork Sun Jan 17 03:07:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Norris X-Patchwork-Id: 1427675 X-Patchwork-Delegate: mail@aparcar.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.openwrt.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=UvshRS0I; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=DEUY+Y5h; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DJKfN1z0vz9sWV for ; Sun, 17 Jan 2021 14:10:04 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=dOwgcaZ1AKaPDbydsvbcKRXdvxlw0kMVG8/JFh2ikh8=; b=UvshRS0IOwx4FVLJPH2+QIO0o kbKBxRLiBUlbcBukWsK//b12O57/8pEhr8I77iopREokb7v+0bbxfgYHs0H1uP0IXtOejmq3vos9F HR32Y8x1RGXUvBQQsfNlr7/mTyEFLzObM1+ldd9jWhUcRLVnmtXzTGcwcXh2eE99PRoJHtt4vanzy Ss9SE00QCsbwqVbip+t19gQRTA/JJ0y1HlVouNIcXNuelxjjo1Cp+E4Xz0aCXOT1Grby6fWYhEDA3 v0qf2laC9iyNPEgRSuPQ6Gc9Sc6GK2Jg2ws4OqA9bF5ind1SYrWX+Om1d+/gyOqygRQKP4DhMKq5B 6G1+u8/JQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0yPc-00048F-GG; Sun, 17 Jan 2021 03:07:32 +0000 Received: from mail-pl1-x633.google.com ([2607:f8b0:4864:20::633]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0yPY-000469-4H for openwrt-devel@lists.openwrt.org; Sun, 17 Jan 2021 03:07:29 +0000 Received: by mail-pl1-x633.google.com with SMTP id b8so6755122plx.0 for ; Sat, 16 Jan 2021 19:07:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cHxoKB2nY6JjYJHElMBQmdGEsk5I8FQoIQajB2DnFzw=; b=DEUY+Y5hukC4Q9BR1fijc1CwcANmy6++KpfVvBqWHEzRbvbVaxMpfZFrjkl2XPdprT Apmx/lL4Ooza3c6Ft2Ub/fihhb3aQ51M7f+jhsLUmZedww7PVkwbvSia4XmKafUAcaz0 PrhrB5Ih9bI1feukU29U+qhP0LlhIunqIGtS6YbA7U533GX5iih5WUleJoSaVsJ/FEFS IZgH2bQvu3QGCUo4L6xMKj8L+q9unUwB47Hm2pz/QbxGfxAPqg3BoXPUbonP6QMNY5TO OiFx4HAngSgSPvjv40tl02yP9zc6Ws/a3F61gJpoCcaAkmVmbwuXXKfauC5l7XffOkCH Jpig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cHxoKB2nY6JjYJHElMBQmdGEsk5I8FQoIQajB2DnFzw=; b=dX2PssoQLFcxtBL3j7kRLcwO/Or2eZb99ngvUEjzZV4nM51ygg51+JBF4usehTnMnR SMlqZ3oXY/sqc7GdmruA0Evj21/txj9PntGb88ZzqmPUoLn5o4pAQuqhd/8yUsUOnz8k i9x2vb8ayM071fdxcwYf2bhQlVXlh1BdjPRa762UE+dwhIrpATnqA/nn+L1Ggf80FZ9V T4/+piR5mVbHvgHWXXSG5DkFh8jDdRp5Lgv0+rCTz82axiwy+QJK0wI7SS7Cim8Mgh/f VM8VLa5okOCax93xJEJU6YU/mY/NzYL4vQoqWd4XwiIgPcxr3m13ywAWwwlz9ywg4fhO c+GA== X-Gm-Message-State: AOAM533BwXU3YJ2K4g78hoDe1Pe0Z/J4VNJzip5LldgUxNlZfpEHs7dP htk+1eS++QB+Ac0L09GL62FHiOT2ztg= X-Google-Smtp-Source: ABdhPJxx8TlWxfHPeXXMxrQc+5A8uITfWUyw2gMg1vAdKZWwWjOZVh8dSpNWgzddeHMyP2mdfyE2YQ== X-Received: by 2002:a17:90a:f2d6:: with SMTP id gt22mr3419350pjb.110.1610852840255; Sat, 16 Jan 2021 19:07:20 -0800 (PST) Received: from localhost ([2601:647:5800:2ac5:9eef:d5ff:fefc:64ae]) by smtp.gmail.com with ESMTPSA id p22sm12668640pgk.21.2021.01.16.19.07.19 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 16 Jan 2021 19:07:19 -0800 (PST) From: Brian Norris To: openwrt-devel@lists.openwrt.org Subject: [PATCH v2 1/4] firmware-utils/ptgen: add Chromium OS kernel partition support Date: Sat, 16 Jan 2021 19:07:03 -0800 Message-Id: <20210117030707.1251501-2-computersforpeace@gmail.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210117030707.1251501-1-computersforpeace@gmail.com> References: <20210117030707.1251501-1-computersforpeace@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210116_220728_301687_EEB49389 X-CRM114-Status: GOOD ( 19.75 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:633 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [computersforpeace[at]gmail.com] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Brian Norris Sender: "openwrt-devel" Errors-To: openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org Chrom{ium,e} OS (shortened as "CrOS") bootloaders use a custom GPT partition type to locate their kernel(s), with custom attributes for noting properties around which partition(s) should be active and how many times they've been tried as part of their A/B in-place upgrade system. OpenWRT doesn't use A/B updates for upgrades (instead, just shutting things down far enough to reprogram the necessary partitions), so all we need to do is tell the bootloader which one is the kernel partition, and how to use it (i.e., set the "successful" and "priority" attributes). ptgen already supports some basic GPT partition creation, so just add support for a '-T ' argument. Currently, this only supports '-T cros_kernel', but it could be extended if there are other GPT partition types needed. For GPT attribute and GUID definitions, see the CrOS verified boot sources: https://chromium.googlesource.com/chromiumos/platform/vboot_reference/+/refs/heads/master/firmware/lib/cgptlib/include/cgptlib_internal.h https://chromium.googlesource.com/chromiumos/platform/vboot_reference/+/refs/heads/master/firmware/include/gpt.h The GUID is also recognized in fdisk, and likely other utilities, but creation/manipulation is typically done via the 'cgpt' utility, provided as part of the vboot_reference project. Signed-off-by: Brian Norris --- tools/firmware-utils/src/ptgen.c | 39 +++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/tools/firmware-utils/src/ptgen.c b/tools/firmware-utils/src/ptgen.c index 223ee295611f..bc1da6d64061 100644 --- a/tools/firmware-utils/src/ptgen.c +++ b/tools/firmware-utils/src/ptgen.c @@ -80,6 +80,10 @@ typedef struct { GUID_INIT( 0x21686148, 0x6449, 0x6E6F, \ 0x74, 0x4E, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49) +#define GUID_PARTITION_CHROME_OS_KERNEL \ + GUID_INIT( 0xFE3A2A5D, 0x4F32, 0x41A7, \ + 0xB7, 0x25, 0xAC, 0xCC, 0x32, 0x85, 0xA3, 0x09) + #define GPT_HEADER_SIZE 92 #define GPT_ENTRY_SIZE 128 #define GPT_ENTRY_MAX 128 @@ -109,6 +113,9 @@ struct partinfo { unsigned long start; unsigned long size; int type; + bool has_gtype; + guid_t gtype; /* GPT partition type */ + uint64_t gattr; /* GPT partition attributes */ }; /* GPT Partition table header */ @@ -248,6 +255,19 @@ static inline int guid_parse(char *buf, guid_t *guid) return 0; } +/* Map GPT partition types to partition GUIDs. */ +static inline bool parse_gpt_parttype(const char *type, struct partinfo *part) +{ + if (!strcmp(type, "cros_kernel")) { + part->has_gtype = true; + part->gtype = GUID_PARTITION_CHROME_OS_KERNEL; + part->gattr = (1ULL << 48) | /* priority=1 */ + (1ULL << 56); /* success=1 */ + return true; + } + return false; +} + /* init an utf-16 string from utf-8 string */ static inline void init_utf16(char *str, uint16_t *buf, unsigned bufsize) { @@ -396,12 +416,15 @@ static int gen_gptable(uint32_t signature, guid_t guid, unsigned nr) gpte[i].end = cpu_to_le64(sect -1); gpte[i].guid = guid; gpte[i].guid.b[sizeof(guid_t) -1] += i + 1; - if (parts[i].type == 0xEF || (i + 1) == (unsigned)active) { + if (parts[i].has_gtype) { + gpte[i].type = parts[i].gtype; + } else if (parts[i].type == 0xEF || (i + 1) == (unsigned)active) { gpte[i].type = GUID_PARTITION_SYSTEM; init_utf16("EFI System Partition", (uint16_t *)gpte[i].name, GPT_ENTRY_NAME_SIZE / sizeof(uint16_t)); } else { gpte[i].type = GUID_PARTITION_BASIC_DATA; } + gpte[i].attr = parts[i].gattr; if (verbose) fprintf(stderr, "Partition %d: start=%" PRIu64 ", end=%" PRIu64 ", size=%" PRIu64 "\n", @@ -498,7 +521,9 @@ fail: static void usage(char *prog) { - fprintf(stderr, "Usage: %s [-v] [-n] [-g] -h -s -o [-a 0..4] [-l ] [-G ] [[-t ] -p [@]...] \n", prog); + fprintf(stderr, "Usage: %s [-v] [-n] [-g] -h -s -o \n" + " [-a 0..4] [-l ] [-G ]\n" + " [[-t | -T ] -p [@]...] \n", prog); exit(EXIT_FAILURE); } @@ -512,7 +537,7 @@ int main (int argc, char **argv) guid_t guid = GUID_INIT( signature, 0x2211, 0x4433, \ 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0x00); - while ((ch = getopt(argc, argv, "h:s:p:a:t:o:vngl:S:G:")) != -1) { + while ((ch = getopt(argc, argv, "h:s:p:a:t:T:o:vngl:S:G:")) != -1) { switch (ch) { case 'o': filename = optarg; @@ -560,6 +585,14 @@ int main (int argc, char **argv) case 'S': signature = strtoul(optarg, NULL, 0); break; + case 'T': + if (!parse_gpt_parttype(optarg, &parts[part])) { + fprintf(stderr, + "Invalid GPT partition type \"%s\"\n", + optarg); + exit(EXIT_FAILURE); + } + break; case 'G': if (guid_parse(optarg, &guid)) { fputs("Invalid guid string\n", stderr); From patchwork Sun Jan 17 03:07:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Norris X-Patchwork-Id: 1427677 X-Patchwork-Delegate: mail@aparcar.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.openwrt.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=XuNJHpug; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=KBu9jZEq; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DJKfN6Vjwz9sWX for ; Sun, 17 Jan 2021 14:10:04 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=Qh8AVAf+P86Y6mvn5BtmiUZepNZute/DODelmaNZHfg=; b=XuNJHpug8qScu7qhVXUHseCod oPL+ESOiQeCjh/ZUqoNZt9RpxPw1Z0cjlwkuTxtVAr54Ch2d3bUFiIGSU1yi1y6U7uXy/9iGChSjZ tQS5TT8DB05UtwgHAtqoA2x5seP8XaLdwBq03miTDaiaBWDOREMZSENBTRrA7e0c3ivclhXm0I4P9 ZCXN2dnubDeRehHwOKzNF/xRUrZ6PsnHLL1pRuF+QY7hrcji3cVGOUg8UVgaIc0L9pFcU878+QPYt f3PwQVp/sAwHGwhlYZBBKKRgOYilWIvCvYvrnW2L9ViJ4WZfGMSbilLO+RShb8hYj+559cLebwv68 SotEh4+Uw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0yPj-00049P-7C; Sun, 17 Jan 2021 03:07:39 +0000 Received: from mail-pj1-x1030.google.com ([2607:f8b0:4864:20::1030]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0yPZ-00046U-2z for openwrt-devel@lists.openwrt.org; Sun, 17 Jan 2021 03:07:34 +0000 Received: by mail-pj1-x1030.google.com with SMTP id y12so7294666pji.1 for ; Sat, 16 Jan 2021 19:07:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=iWIxtYBN+umJ3DFuKx6oZftC7EBE1DS7+lDOlzwg2LM=; b=KBu9jZEqOEjAyQitwhOzt0ygQU8RtgIioNLS3pYH9c3i0mPFtW87vaeLnVoQc7sGDr BtZCp8JB1VbnVipip1EF/fCofQNcMu+qgS0klWSnfuRC4XZ978TbcgYcEMK77DPJSEn7 KGVs5yNdk84Cr9exOB+1u/Vq4O+umDi8MXcH87qGxFRNAux0VNJs/YyWYtVHfuZ9XML7 4tB8h+MxocBG1l5Jo5y9S4itRD+hAN4m1uplYzOZTEdCxwEVBqGhydsyofxaVhU6ZTSc OFA9BJu8GUV+yxQobJYIHyu2oWRoI7CRl44n2kPZeruQLbZIoMQxtZu8DiDWu9LupGpc j/2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=iWIxtYBN+umJ3DFuKx6oZftC7EBE1DS7+lDOlzwg2LM=; b=lI2tD2ie9sqw85eA8KLucC39pTe+5h1bdXZFR2JRLf+WIVlaccBJt2oH8oMg/9Lkm9 CyEARLiEolekTNi2S8elTwykXchXrhfwiTYQ1n0GZFsqyQ1R/kgnQmq//iAjWmrQ3oBd D1YIuPNRzEjv4ro4f7BUtcUOszwWqun9WpLPhyYVg+tgqvpfWuQ/hbO0/HcSr6PvPhm9 EhM6/CLkzSqS8/UcG5A3/kcEluhYRKV+n1cowsPYL4iHz81rR49HIqJ1SxJ6TxA7cwOF H0VZNAekZygNufnNy5/KCLBDR/CKrjDgEUnMuUFOtKaOspzk0l/X2h5gOpVc0T4LFJeB nhZQ== X-Gm-Message-State: AOAM532Y8cTr8wd1UWv14rknn2QoqaMYcVtT6KlZcVDL0kiCdiuoqQ3S zKr/SufLasZYTKLFWW8Qtr8rMJXzsyo= X-Google-Smtp-Source: ABdhPJzPRgZ7NCl0Kavz9glBAsy09k2zgjjdaV1qcY2sNDJl+N6uBCIARk9WMYEMgt9BTqZouxnXQA== X-Received: by 2002:a17:90a:540c:: with SMTP id z12mr7133656pjh.58.1610852842064; Sat, 16 Jan 2021 19:07:22 -0800 (PST) Received: from localhost ([2601:647:5800:2ac5:9eef:d5ff:fefc:64ae]) by smtp.gmail.com with ESMTPSA id x14sm12167183pfp.77.2021.01.16.19.07.21 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 16 Jan 2021 19:07:21 -0800 (PST) From: Brian Norris To: openwrt-devel@lists.openwrt.org Subject: [PATCH v2 2/4] firmware-utils/cros-vbutil: add Chrome OS vboot kernel-signing utility Date: Sat, 16 Jan 2021 19:07:04 -0800 Message-Id: <20210117030707.1251501-3-computersforpeace@gmail.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210117030707.1251501-1-computersforpeace@gmail.com> References: <20210117030707.1251501-1-computersforpeace@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210116_220730_132822_3A64318A X-CRM114-Status: GOOD ( 26.04 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:1030 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [computersforpeace[at]gmail.com] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Brian Norris Sender: "openwrt-devel" Errors-To: openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org Chrom{ium,e} OS based devices use a Coreboot+Depthcharge-based firmware, which verifies and loads a kernel packed in a verified-boot payload. The verification tooling (both for creating and verifying payloads) is implemented here: https://chromium.googlesource.com/chromiumos/platform/vboot_reference Devices running such bootloaders also tend to support a "developer mode," where a device can be unlocked to run arbitrary kernel payloads, using the same verified-boot format plus well-known developer keys. More information can be found here: https://chromium.googlesource.com/chromiumos/docs/+/master/developer_mode.md Rather than build and package the vboot_reference utilities as part of the base OpenWRT tools, I chose to reimplement just the portion that's required for signing payloads. I also embed the developer key directly in the source for convenience, though it's certainly possible to provide other keys too, if one were to build their own firmware that accepts it. This tool is essentially the same as running something like this, using the Chromium OS tooling: vbutil_kernel --pack kernel_partition.bin \ --keyblock /usr/share/vboot/devkeys/kernel.keyblock \ --signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk \ --version 1 \ --vmlinuz kernel.bin \ --bootloader zero.txt \ --config commnad_line.txt \ --arch ${ARCH} I have also packaged the Chromium OS vboot_reference tooling for the packages feed, as it can be useful beyond simply creating a bootable image (e.g., manipulating Chromium OS specific GPT attributes, handling other NVRAM attributes, vboot packing/unpacking/verifying): https://github.com/openwrt/packages/pull/12829 The vboot_reference tools are released by Google under a BSD 3-clause license. I've provided the original license text as well as a GPL-2 notice for my modifications (essentially just borrowing the data structures and rewriting everything else). Signed-off-by: Brian Norris --- tools/firmware-utils/Makefile | 1 + tools/firmware-utils/src/cros-vbutil.c | 609 +++++++++++++++++++++++++ 2 files changed, 610 insertions(+) create mode 100644 tools/firmware-utils/src/cros-vbutil.c diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile index 6074ecc608d0..f4f9f233cdc2 100644 --- a/tools/firmware-utils/Makefile +++ b/tools/firmware-utils/Makefile @@ -30,6 +30,7 @@ define Host/Compile $(call cc,buffalo-enc buffalo-lib,-Wall) $(call cc,buffalo-tag buffalo-lib,-Wall) $(call cc,buffalo-tftp buffalo-lib,-Wall) + $(call cc,cros-vbutil,-lcrypto -lpthread) $(call cc,dgfirmware) $(call cc,dgn3500sum,-Wall) $(call cc,dns313-header,-Wall) diff --git a/tools/firmware-utils/src/cros-vbutil.c b/tools/firmware-utils/src/cros-vbutil.c new file mode 100644 index 000000000000..13ba9a3245b3 --- /dev/null +++ b/tools/firmware-utils/src/cros-vbutil.c @@ -0,0 +1,609 @@ +/* + * cros-vbutil - Tool for signing kernels using the Chromium OS verified boot + * format, using widely-shared "developer" keys. The output of this tool is + * intended to be written to a GPT partition of type "Chrome OS Kernel", such + * that a Chromium OS bootloader can find it. + * + * Much of this is adapted from Google's vboot_reference project found here: + * https://chromium.googlesource.com/chromiumos/platform/vboot_reference + * + * Copyright (c) 2010 The Chromium OS Authors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Rewritten: + * Copyright (c) 2021 Brian Norris + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#define BLOCK_PAD 65536 +/* Sections are aligned to 4K blocks */ +#define ALIGN 4096 +#define ROUNDUP(x) (((x) + (ALIGN-1)) & ~(ALIGN-1)) + +/* + * Signature size, in bytes. This is an RSA-2048 encryption of a SHA256 hash. + */ +#define SIG_SIZE (2048 / 8) + +/* + * From vboot_reference: tests/devkeys/kernel.keyblock + */ +static const unsigned char keyblock[] = { + 0x43, 0x48, 0x52, 0x4f, 0x4d, 0x45, 0x4f, 0x53, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xb8, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x78, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x78, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xcb, 0x02, 0x40, 0x41, + 0x1d, 0x2d, 0x86, 0x0f, 0x6d, 0x53, 0xcc, 0xcc, 0xa7, 0x9b, 0x1b, 0xca, + 0xdc, 0x22, 0xc4, 0xc2, 0x3a, 0x72, 0xa5, 0x12, 0x21, 0xfe, 0x78, 0x1d, + 0x9c, 0x03, 0x65, 0x0c, 0x94, 0xba, 0x3d, 0x5b, 0x5e, 0x98, 0x16, 0x8a, + 0xaf, 0xaf, 0x67, 0x5a, 0x46, 0x88, 0x2c, 0xf0, 0x2a, 0x65, 0xbd, 0xc7, + 0x59, 0xcc, 0x70, 0xe9, 0x01, 0x4e, 0x7d, 0x8c, 0x43, 0x2e, 0x1c, 0x6d, + 0x72, 0x15, 0xaf, 0xd0, 0x71, 0x9f, 0xb4, 0x3a, 0xe7, 0x44, 0x82, 0xd1, + 0x83, 0x8b, 0x9d, 0x6c, 0x64, 0x99, 0xaf, 0xdb, 0x8a, 0xcc, 0xd1, 0xd6, + 0x83, 0xa6, 0xa4, 0xea, 0xa9, 0x81, 0x1d, 0x9f, 0x1b, 0x5a, 0x8c, 0xf8, + 0xdb, 0x26, 0x21, 0xb2, 0x7b, 0x53, 0x92, 0xf0, 0x6a, 0xc5, 0x8c, 0x11, + 0xba, 0x7e, 0x43, 0xcb, 0x1e, 0x57, 0xa1, 0x6e, 0xd5, 0xfe, 0x82, 0x28, + 0x3d, 0x6d, 0xbd, 0x97, 0xb0, 0xe8, 0xfb, 0x1f, 0x88, 0x06, 0x1b, 0x0a, + 0xc5, 0x8f, 0x96, 0x69, 0x48, 0x69, 0x41, 0x2a, 0x52, 0xd7, 0xb7, 0x33, + 0x78, 0x8b, 0x6f, 0x97, 0xa7, 0x7d, 0xdc, 0xd0, 0x2b, 0xd9, 0x81, 0x67, + 0xc9, 0x3f, 0xa9, 0xb4, 0x1e, 0x0b, 0x08, 0x54, 0xc6, 0x01, 0xc6, 0x20, + 0xe6, 0xc6, 0x09, 0x5f, 0x0a, 0xc5, 0x02, 0x05, 0x6b, 0x40, 0x96, 0x11, + 0x20, 0xe5, 0xa2, 0x88, 0x37, 0x6a, 0xd3, 0xda, 0xda, 0xda, 0x76, 0x1c, + 0xe4, 0x3d, 0x2c, 0xfe, 0x65, 0x86, 0x98, 0xa2, 0xa8, 0x49, 0x7d, 0x26, + 0x45, 0x14, 0x04, 0x10, 0xe3, 0x38, 0x4b, 0x66, 0x9c, 0x5c, 0x2c, 0xe8, + 0xd9, 0x06, 0xd4, 0xc3, 0x05, 0x94, 0x1c, 0x7b, 0x23, 0x89, 0x86, 0x1d, + 0x32, 0xbb, 0x23, 0x90, 0x2b, 0x72, 0xd7, 0x90, 0x53, 0x52, 0x10, 0x12, + 0xd0, 0xc2, 0xe2, 0x72, 0x81, 0x70, 0x3c, 0xb1, 0x27, 0x42, 0xec, 0xbf, + 0x2b, 0x54, 0xd6, 0xcb, 0x61, 0xea, 0xb4, 0xd4, 0xa8, 0xde, 0xf3, 0xdf, + 0x3d, 0xd1, 0x17, 0xde, 0x86, 0x89, 0xf4, 0xa1, 0x28, 0x5e, 0xda, 0xb4, + 0x47, 0x19, 0x9b, 0xc2, 0xce, 0x49, 0xea, 0x63, 0xda, 0x42, 0x1c, 0x85, + 0x1c, 0xab, 0x6c, 0xd7, 0xc2, 0xfd, 0x34, 0x1b, 0xd5, 0x11, 0xa2, 0x44, + 0xb7, 0x7a, 0x85, 0x61, 0x03, 0xba, 0xd4, 0x64, 0xe1, 0x49, 0x87, 0x92, + 0xe6, 0xdc, 0x39, 0x94, 0x9c, 0xba, 0xef, 0x58, 0x9e, 0x0e, 0x36, 0x98, + 0xd7, 0xd2, 0x4c, 0x14, 0x71, 0x94, 0x78, 0xaf, 0x86, 0xe7, 0x2f, 0xe9, + 0xf9, 0x20, 0x4d, 0xfe, 0xda, 0xd7, 0x3f, 0x89, 0xc1, 0x59, 0xae, 0xbd, + 0x60, 0x9b, 0x97, 0xa4, 0x66, 0x00, 0xbb, 0x7b, 0xd0, 0x49, 0x85, 0x6f, + 0x7b, 0x01, 0x24, 0xc3, 0x48, 0xe2, 0xc7, 0x61, 0x98, 0x9c, 0xe5, 0x93, + 0x87, 0x04, 0x09, 0x3a, 0x92, 0x54, 0x1f, 0xb5, 0x80, 0x29, 0x15, 0xe5, + 0x7f, 0xfe, 0xdc, 0xaf, 0xd3, 0xe1, 0x62, 0xc4, 0xb6, 0xdb, 0x2f, 0x1a, + 0x08, 0xf3, 0x54, 0x06, 0x3a, 0xce, 0x5e, 0x89, 0x71, 0xdf, 0x3b, 0x5c, + 0x8c, 0x6b, 0x83, 0xa9, 0x0c, 0x05, 0x50, 0x7b, 0x84, 0x09, 0x18, 0x66, + 0x84, 0xe1, 0x7e, 0x60, 0xd6, 0xdc, 0xbf, 0x1c, 0xac, 0x5c, 0xdc, 0xe6, + 0x4c, 0x9e, 0xa0, 0x4a, 0x59, 0x30, 0xff, 0x91, 0x90, 0x1e, 0x21, 0x29, + 0x50, 0x99, 0x76, 0xfd, 0x2f, 0x5a, 0x67, 0x6a, 0x00, 0x6b, 0x40, 0x27, + 0xe7, 0xbd, 0x17, 0xe6, 0x5f, 0x9e, 0xe4, 0x6b, 0xe0, 0x05, 0x9e, 0x7d, + 0xcb, 0x90, 0xe9, 0x3c, 0x9c, 0x79, 0xc9, 0x47, 0xf8, 0x58, 0xbc, 0x3f, + 0xb1, 0xa5, 0xef, 0x67, 0xf0, 0x22, 0xa1, 0x70, 0x33, 0x36, 0xb0, 0x5c, + 0xed, 0xea, 0x4e, 0xde, 0x24, 0x0c, 0x5b, 0xd8, 0x4d, 0xbe, 0xac, 0x6a, + 0x12, 0x31, 0xa6, 0x5e, 0x5f, 0x04, 0xb6, 0x58, 0xa1, 0xd1, 0x29, 0xa3, + 0x33, 0x9c, 0x64, 0xb1, 0x8e, 0x3b, 0xfa, 0xaf, 0x35, 0x94, 0x7a, 0xa4, + 0xf5, 0xcb, 0x9e, 0x67, 0x1b, 0x8d, 0x35, 0xca, 0x10, 0x69, 0x8d, 0xea, + 0x78, 0xc2, 0xf6, 0x63, 0xc0, 0x11, 0xf1, 0xf6, 0x66, 0x70, 0x2e, 0x96, + 0xf0, 0xbc, 0x7b, 0x1e, 0x16, 0x26, 0xde, 0xe3, 0x7f, 0xc0, 0xf4, 0x6c, + 0x3c, 0x0b, 0x52, 0xe2, 0x07, 0xde, 0x70, 0x8b, 0xaf, 0x84, 0x95, 0x1b, + 0x46, 0x95, 0x69, 0x05, 0x92, 0xea, 0x36, 0xa5, 0xca, 0x50, 0xdb, 0x49, + 0xc8, 0x44, 0xee, 0x7c, 0x49, 0x40, 0x34, 0x05, 0xf3, 0x06, 0x1f, 0x1c, + 0xcc, 0x78, 0x62, 0x1b, 0x9d, 0xe2, 0x4f, 0x3e, 0x04, 0x96, 0xba, 0xd0, + 0xc7, 0xa2, 0x3a, 0xaa, 0xf7, 0xc3, 0xae, 0xc0, 0x6b, 0xca, 0xc8, 0x59, + 0x90, 0xe0, 0x45, 0x7b, 0x4b, 0x60, 0xbf, 0xae, 0x15, 0x25, 0xd0, 0xa2, + 0x2f, 0x95, 0x6a, 0x2e, 0x37, 0x24, 0x15, 0x69, 0x0e, 0x3a, 0x6d, 0x40, + 0x21, 0xf6, 0x74, 0x5c, 0xa6, 0x9f, 0xe0, 0x03, 0x60, 0x04, 0x59, 0x70, + 0x70, 0xa0, 0x46, 0xf4, 0xdf, 0x0a, 0x4b, 0x14, 0xab, 0x87, 0x0c, 0xaa, + 0x64, 0x9b, 0x82, 0xca, 0x21, 0xb0, 0x72, 0xfa, 0x8b, 0x37, 0xf5, 0x60, + 0xd7, 0xb7, 0x4e, 0x72, 0x5e, 0x13, 0x23, 0x73, 0x84, 0x6c, 0xd1, 0x8d, + 0x72, 0xa2, 0x15, 0x8b, 0x51, 0x38, 0x90, 0x68, 0x90, 0xd9, 0x8b, 0x65, + 0x30, 0x61, 0xdb, 0x51, 0x80, 0x58, 0xdd, 0xc3, 0xf0, 0x29, 0x33, 0xdc, + 0x39, 0x92, 0xbf, 0x27, 0xe6, 0xc7, 0x82, 0xf6, 0xea, 0xcf, 0x21, 0xd2, + 0xa0, 0x38, 0x02, 0x57, 0x52, 0xf5, 0xdd, 0x07, 0x99, 0xe3, 0x09, 0xd7, + 0xad, 0x9e, 0x1e, 0xe7, 0xf3, 0x5e, 0x72, 0xa0, 0xc6, 0x9d, 0x41, 0x86, + 0x96, 0x82, 0x74, 0x46, 0x1f, 0x05, 0xd2, 0x05, 0x25, 0x29, 0x27, 0x66, + 0xe1, 0xab, 0x5c, 0x06, 0xf4, 0xac, 0xe7, 0xd0, 0xf8, 0xe6, 0x5e, 0x8b, + 0x19, 0x55, 0xc2, 0x99, 0x8e, 0xa7, 0x2e, 0x66, 0x0c, 0x2a, 0x61, 0xb0, + 0x98, 0x41, 0x93, 0x05, 0x54, 0x90, 0xaa, 0xbe, 0x15, 0x26, 0x5b, 0x77, + 0x7c, 0xb0, 0xf8, 0x08, 0x68, 0xb6, 0xb8, 0xd4, 0xdd, 0xd8, 0xa8, 0x4f, + 0xdd, 0xf6, 0x93, 0xe5, 0xa1, 0x88, 0x1b, 0x7a, 0x05, 0x81, 0xc5, 0x98, + 0x34, 0x1d, 0x88, 0x63, 0x55, 0xaf, 0x9a, 0xa1, 0xcb, 0x4b, 0xaf, 0x86, + 0xb3, 0x45, 0xda, 0xa4, 0xb4, 0xa5, 0x10, 0x7a, 0x50, 0x6a, 0xe5, 0xda, + 0x6f, 0x8f, 0xc0, 0x1d, 0x95, 0xb1, 0x91, 0x48, 0x53, 0xc3, 0xe5, 0x1f, + 0x0e, 0x05, 0x75, 0xaa, 0xc7, 0xd8, 0x36, 0xd0, 0x6d, 0x50, 0x48, 0xd4, + 0xe6, 0xbd, 0xd0, 0x2d, 0x97, 0x17, 0x2d, 0xb3, 0x46, 0xab, 0x19, 0x0e, + 0xe4, 0xac, 0xfd, 0x93, 0xab, 0x0c, 0x4c, 0xad, 0xbf, 0x58, 0x1b, 0xaa, + 0x26, 0xcd, 0x0d, 0xda, 0xaf, 0xcb, 0xeb, 0xb0, 0x19, 0x5c, 0x46, 0x1f, + 0x9b, 0xb0, 0xb8, 0x12, 0x6c, 0xa7, 0x4e, 0xb8, 0xa7, 0x1f, 0x12, 0x6b, + 0xf8, 0xbe, 0x4b, 0xa9, 0x04, 0xb4, 0xf9, 0x36, 0xcc, 0xd9, 0xd5, 0x91, + 0xac, 0x7e, 0xe9, 0x13, 0xc0, 0x7f, 0xca, 0xd7, 0xdc, 0xbe, 0xa9, 0xb0, + 0xd6, 0x28, 0x17, 0x2f, 0xd6, 0xdf, 0x0e, 0x6b, 0x48, 0x11, 0xd6, 0x51, + 0xc7, 0x6d, 0x87, 0xf6, 0x08, 0xb7, 0x6c, 0x69, 0xf7, 0xd6, 0x28, 0x50, + 0x7e, 0x74, 0xad, 0x96, 0x6a, 0x0c, 0xca, 0x6b, 0xb1, 0xf1, 0xde, 0xa3, + 0x5f, 0x23, 0xf5, 0x2a, 0x44, 0x11, 0x0f, 0xa3, 0xf7, 0x24, 0x36, 0x1b, + 0x33, 0xe6, 0x7e, 0xd9, 0x0e, 0xa5, 0x8b, 0xa0, 0xb8, 0x8b, 0x85, 0xee, + 0xd0, 0xe4, 0x69, 0x43, 0xc6, 0xf9, 0x5f, 0x27, 0xa5, 0xc9, 0x61, 0x3b, + 0x8e, 0xaf, 0x62, 0x77, 0x42, 0xb6, 0x27, 0x5f, 0xed, 0x96, 0x86, 0xb3, + 0xef, 0x32, 0x31, 0x43, 0x2e, 0x7b, 0xaf, 0x5b, 0xe2, 0x75, 0x82, 0x72, + 0xad, 0x3b, 0x5d, 0x92, 0xc1, 0x15, 0xaa, 0xfb, 0x21, 0x07, 0xe9, 0xaa, + 0xc4, 0xe2, 0xd7, 0x99, 0x83, 0x6c, 0x72, 0x39, 0x6f, 0x35, 0x20, 0x9d, + 0xe0, 0xd8, 0xf8, 0xdb, 0x72, 0x24, 0xe5, 0x8d, 0x29, 0xfd, 0x24, 0x7b, + 0xbc, 0x48, 0xe9, 0xbb, 0xc2, 0x84, 0xc7, 0xb9 +}; +static unsigned int keyblock_len = sizeof(keyblock); + +/* + * RSA 2048-bit key from vboot_reference: + * tests/devkeys/kernel_data_key.vbprivk, minus the 8-byte custom header. + */ +static const unsigned char privk[] = { + 0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, + 0xcb, 0xd6, 0x54, 0x2b, 0xbf, 0xec, 0x42, 0x27, 0xb1, 0x3c, 0x70, 0x81, + 0x72, 0xe2, 0xc2, 0xd0, 0x12, 0x10, 0x52, 0x53, 0x90, 0xd7, 0x72, 0x2b, + 0x90, 0x23, 0xbb, 0x32, 0x1d, 0x86, 0x89, 0x23, 0x7b, 0x1c, 0x94, 0x05, + 0xc3, 0xd4, 0x06, 0xd9, 0xe8, 0x2c, 0x5c, 0x9c, 0x66, 0x4b, 0x38, 0xe3, + 0x10, 0x04, 0x14, 0x45, 0x26, 0x7d, 0x49, 0xa8, 0xa2, 0x98, 0x86, 0x65, + 0xfe, 0x2c, 0x3d, 0xe4, 0x1c, 0x76, 0xda, 0xda, 0xda, 0xd3, 0x6a, 0x37, + 0x88, 0xa2, 0xe5, 0x20, 0x11, 0x96, 0x40, 0x6b, 0x05, 0x02, 0xc5, 0x0a, + 0x5f, 0x09, 0xc6, 0xe6, 0x20, 0xc6, 0x01, 0xc6, 0x54, 0x08, 0x0b, 0x1e, + 0xb4, 0xa9, 0x3f, 0xc9, 0x67, 0x81, 0xd9, 0x2b, 0xd0, 0xdc, 0x7d, 0xa7, + 0x97, 0x6f, 0x8b, 0x78, 0x33, 0xb7, 0xd7, 0x52, 0x2a, 0x41, 0x69, 0x48, + 0x69, 0x96, 0x8f, 0xc5, 0x0a, 0x1b, 0x06, 0x88, 0x1f, 0xfb, 0xe8, 0xb0, + 0x97, 0xbd, 0x6d, 0x3d, 0x28, 0x82, 0xfe, 0xd5, 0x6e, 0xa1, 0x57, 0x1e, + 0xcb, 0x43, 0x7e, 0xba, 0x11, 0x8c, 0xc5, 0x6a, 0xf0, 0x92, 0x53, 0x7b, + 0xb2, 0x21, 0x26, 0xdb, 0xf8, 0x8c, 0x5a, 0x1b, 0x9f, 0x1d, 0x81, 0xa9, + 0xea, 0xa4, 0xa6, 0x83, 0xd6, 0xd1, 0xcc, 0x8a, 0xdb, 0xaf, 0x99, 0x64, + 0x6c, 0x9d, 0x8b, 0x83, 0xd1, 0x82, 0x44, 0xe7, 0x3a, 0xb4, 0x9f, 0x71, + 0xd0, 0xaf, 0x15, 0x72, 0x6d, 0x1c, 0x2e, 0x43, 0x8c, 0x7d, 0x4e, 0x01, + 0xe9, 0x70, 0xcc, 0x59, 0xc7, 0xbd, 0x65, 0x2a, 0xf0, 0x2c, 0x88, 0x46, + 0x5a, 0x67, 0xaf, 0xaf, 0x8a, 0x16, 0x98, 0x5e, 0x5b, 0x3d, 0xba, 0x94, + 0x0c, 0x65, 0x03, 0x9c, 0x1d, 0x78, 0xfe, 0x21, 0x12, 0xa5, 0x72, 0x3a, + 0xc2, 0xc4, 0x22, 0xdc, 0xca, 0x1b, 0x9b, 0xa7, 0xcc, 0xcc, 0x53, 0x6d, + 0x0f, 0x86, 0x2d, 0x1d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, + 0x00, 0x4d, 0xb8, 0xea, 0x9d, 0x47, 0xef, 0xf1, 0x05, 0xab, 0x79, 0xed, + 0x38, 0x1e, 0xb3, 0x42, 0x2f, 0x0e, 0x44, 0x34, 0xef, 0xf2, 0x31, 0x84, + 0x32, 0x02, 0x22, 0xed, 0xb4, 0xdd, 0x37, 0x38, 0x41, 0x54, 0x27, 0x00, + 0x75, 0xf6, 0x46, 0x79, 0x5a, 0x4b, 0x41, 0xe7, 0x0a, 0x27, 0xa3, 0x15, + 0x0c, 0xd7, 0x45, 0x86, 0xe9, 0x1b, 0x14, 0xf8, 0xaa, 0x19, 0x5d, 0x69, + 0x19, 0xa8, 0xc1, 0xfb, 0xd3, 0x67, 0xdb, 0x15, 0xf6, 0x0f, 0x2c, 0x3f, + 0xba, 0xef, 0x19, 0x95, 0x9e, 0x15, 0xb6, 0xa1, 0xd7, 0x6c, 0xb0, 0xb2, + 0xab, 0x12, 0xb3, 0xea, 0xa8, 0x42, 0xe4, 0xdd, 0x36, 0x5f, 0x42, 0x35, + 0xe3, 0x3e, 0x65, 0xae, 0x91, 0xc0, 0x2a, 0xed, 0xc0, 0xdc, 0x41, 0xc6, + 0x93, 0xc9, 0x95, 0x59, 0xab, 0xba, 0xa4, 0xa5, 0xb0, 0x89, 0xb6, 0x29, + 0x4b, 0xd8, 0x1e, 0xf5, 0xb0, 0xde, 0xfa, 0x91, 0x11, 0x55, 0xd6, 0x9d, + 0xe1, 0xa7, 0x9c, 0xf2, 0xf4, 0x9d, 0x7f, 0x96, 0x49, 0x7a, 0xab, 0xe9, + 0x9a, 0x0c, 0xcb, 0x10, 0x5c, 0x67, 0xf0, 0x1d, 0xf3, 0x33, 0x84, 0xae, + 0x6e, 0xe4, 0xbb, 0xa7, 0x57, 0x98, 0x99, 0x2b, 0xf3, 0x1d, 0xab, 0xec, + 0x01, 0xa2, 0x2e, 0x3c, 0x10, 0x5c, 0xff, 0xe8, 0xcc, 0x50, 0x45, 0x21, + 0x2f, 0x04, 0x69, 0xdd, 0x02, 0x5b, 0x10, 0xd6, 0x54, 0x36, 0x4c, 0x73, + 0x0c, 0x1e, 0xc1, 0xff, 0xac, 0x60, 0x5d, 0xbc, 0x13, 0x84, 0xe8, 0xa4, + 0xbd, 0x66, 0xca, 0xca, 0xaf, 0x55, 0x8a, 0xf8, 0x87, 0x17, 0x93, 0xbf, + 0x66, 0xa4, 0x97, 0xe9, 0x47, 0x81, 0x03, 0xfa, 0x4c, 0x32, 0xf6, 0xec, + 0x7a, 0x03, 0xbb, 0x2d, 0x3b, 0x9b, 0xea, 0xdc, 0x6c, 0x61, 0x7f, 0x05, + 0xc8, 0x2d, 0x50, 0x89, 0xe9, 0x10, 0x3d, 0x3c, 0x02, 0xb0, 0x5d, 0x3e, + 0x25, 0x71, 0xd2, 0xa1, 0xe1, 0x02, 0x81, 0x81, 0x00, 0xf6, 0x3c, 0x7f, + 0x15, 0x63, 0x04, 0x0a, 0xd4, 0x68, 0xe8, 0xd9, 0x4b, 0x7f, 0xbc, 0xca, + 0xb5, 0x84, 0x01, 0x71, 0x11, 0x33, 0x4d, 0xe1, 0x0a, 0xe8, 0xa7, 0x95, + 0xcc, 0x23, 0x59, 0x19, 0xb5, 0x82, 0xaa, 0xae, 0xe4, 0x90, 0x33, 0x95, + 0x20, 0x1a, 0xfd, 0xef, 0x8e, 0x36, 0xc1, 0x57, 0xde, 0x94, 0xdd, 0x99, + 0x6f, 0x14, 0x0c, 0x8e, 0x30, 0xe0, 0xe7, 0x64, 0x33, 0xa7, 0x1d, 0xfd, + 0x99, 0xdc, 0x58, 0x49, 0x4e, 0x56, 0x82, 0x43, 0xea, 0xd9, 0xf7, 0xcc, + 0x1a, 0xf5, 0x09, 0x38, 0x4c, 0xf6, 0x87, 0x8f, 0xa6, 0x40, 0x96, 0xd1, + 0x81, 0x62, 0xbb, 0x49, 0x53, 0x69, 0x56, 0xdf, 0x4a, 0x85, 0xfd, 0x72, + 0x34, 0x21, 0x56, 0xa3, 0x7b, 0xda, 0x50, 0x24, 0x88, 0xc6, 0x0b, 0x03, + 0x94, 0x0d, 0xe2, 0x03, 0x2a, 0x3c, 0x5a, 0xdd, 0x73, 0xe7, 0x07, 0x01, + 0x7d, 0xdd, 0x38, 0x81, 0x19, 0x02, 0x81, 0x81, 0x00, 0xd3, 0xeb, 0x72, + 0x3f, 0xf6, 0x9b, 0x03, 0x8c, 0xab, 0xd9, 0x41, 0x47, 0xbe, 0x6c, 0x07, + 0x7f, 0xd7, 0xcb, 0xee, 0xbf, 0x45, 0x13, 0x1e, 0x53, 0x35, 0xd2, 0xe4, + 0x6a, 0x13, 0xe9, 0xd8, 0xe3, 0xf4, 0x28, 0x5e, 0xeb, 0xd8, 0xd2, 0x87, + 0x60, 0xdc, 0xa7, 0x21, 0xd8, 0x33, 0xce, 0xca, 0x60, 0x50, 0x1b, 0x87, + 0xbf, 0x71, 0x88, 0x90, 0x71, 0x6f, 0xde, 0xdb, 0x33, 0x1d, 0x3c, 0xb1, + 0x2f, 0x1b, 0x41, 0xb8, 0x55, 0xa1, 0x5c, 0xa8, 0xb2, 0x73, 0x1b, 0x39, + 0x69, 0x5c, 0xa1, 0x57, 0x9b, 0x2e, 0xcd, 0x0d, 0x71, 0x42, 0xdf, 0x2a, + 0xd3, 0x4f, 0x51, 0xdc, 0x35, 0x5c, 0x14, 0x86, 0x16, 0xb8, 0x22, 0x8c, + 0x73, 0x37, 0x7a, 0x6c, 0xb7, 0xfe, 0x01, 0x1b, 0xa8, 0xc5, 0xf1, 0xff, + 0xda, 0xd4, 0x63, 0x58, 0x81, 0xe1, 0x6a, 0xaf, 0xc2, 0x3d, 0xbb, 0x17, + 0x3f, 0x2c, 0xf9, 0xb8, 0xa5, 0x02, 0x81, 0x81, 0x00, 0xd1, 0x1e, 0x6b, + 0xa7, 0x54, 0x22, 0x18, 0xb8, 0x70, 0x28, 0x60, 0x72, 0x98, 0x17, 0x53, + 0xe8, 0x78, 0x25, 0x69, 0x4a, 0xfc, 0x51, 0x45, 0xb0, 0x28, 0x0a, 0x3b, + 0x53, 0xd5, 0x29, 0x54, 0x86, 0x2c, 0x64, 0x9c, 0x87, 0x8c, 0x57, 0xe2, + 0x6c, 0x13, 0xc0, 0x59, 0x74, 0x63, 0xd8, 0x2b, 0xb1, 0xe2, 0xa7, 0x98, + 0x29, 0x17, 0xd3, 0xd9, 0xe6, 0x74, 0xfa, 0xce, 0xc4, 0x77, 0x47, 0x27, + 0x1b, 0x46, 0x60, 0xcc, 0x50, 0xf5, 0x73, 0x48, 0x0e, 0xe9, 0xf2, 0x62, + 0xaa, 0xfa, 0x33, 0x4c, 0x57, 0x40, 0x7f, 0xbc, 0x65, 0xab, 0x30, 0xea, + 0xd8, 0x81, 0x6b, 0x21, 0x48, 0xef, 0x8b, 0x51, 0xb3, 0x4e, 0xbc, 0x02, + 0x03, 0x77, 0xd4, 0xc6, 0x9e, 0xe6, 0xb7, 0x6d, 0x6f, 0xa3, 0x11, 0xb3, + 0x86, 0x47, 0x8c, 0x0c, 0xb8, 0x0f, 0xed, 0xf3, 0x68, 0xfd, 0x69, 0x9b, + 0xc0, 0xb2, 0xe1, 0xcb, 0xf1, 0x02, 0x81, 0x80, 0x46, 0xc6, 0xdb, 0xe1, + 0x80, 0xfb, 0x44, 0xb4, 0x36, 0xb0, 0xd8, 0x9c, 0x9d, 0x7c, 0x77, 0x04, + 0xbb, 0x8d, 0xe0, 0xaf, 0x00, 0xe2, 0xe1, 0xbd, 0xe8, 0xbc, 0x06, 0x8d, + 0x67, 0x19, 0x32, 0xd6, 0xef, 0x34, 0x8c, 0x7f, 0x38, 0x6b, 0x17, 0xcb, + 0xc1, 0xe6, 0x0f, 0xe7, 0xa5, 0x65, 0xeb, 0x31, 0x3f, 0x8f, 0xf2, 0x46, + 0x7e, 0x24, 0x9e, 0x19, 0x44, 0xc3, 0xa9, 0x71, 0xe8, 0xd1, 0xdc, 0x5b, + 0x5f, 0x3f, 0x13, 0xd1, 0x85, 0x92, 0xec, 0xc4, 0xac, 0xac, 0xea, 0xff, + 0xc5, 0x70, 0x1d, 0x52, 0x36, 0xcf, 0x45, 0x2e, 0x0e, 0xa7, 0x7a, 0x26, + 0x18, 0xd7, 0xbe, 0x34, 0x14, 0x0c, 0xc6, 0xbb, 0xcf, 0xc3, 0xba, 0x24, + 0xc0, 0xe2, 0xa2, 0x6c, 0xd0, 0xe8, 0x8d, 0xd4, 0x50, 0x48, 0x02, 0xab, + 0x93, 0x43, 0x9a, 0xcb, 0xc5, 0xfd, 0x5b, 0xb6, 0x03, 0xe7, 0xf8, 0x5b, + 0xa1, 0x29, 0xc6, 0x01, 0x02, 0x81, 0x80, 0x0e, 0x18, 0xbc, 0x00, 0xa3, + 0x81, 0xda, 0xc2, 0xc8, 0xfb, 0x0a, 0xbd, 0x7f, 0xb7, 0x7f, 0xa1, 0x18, + 0x7f, 0x49, 0xb8, 0x32, 0x83, 0x4b, 0x71, 0x35, 0x59, 0x51, 0x7b, 0xee, + 0x8e, 0x4e, 0xd2, 0x42, 0xa8, 0x6c, 0x82, 0x57, 0xf7, 0x34, 0xf6, 0x82, + 0x59, 0xe9, 0x75, 0x7a, 0x8f, 0x0a, 0x8d, 0x46, 0x1e, 0xa1, 0x77, 0xa1, + 0x4c, 0xb3, 0x9e, 0x86, 0x93, 0x18, 0xdf, 0x3e, 0xfb, 0x81, 0xd0, 0xbc, + 0x65, 0xa2, 0xb3, 0x80, 0xf0, 0x8f, 0x73, 0x2f, 0xb5, 0xc4, 0xc0, 0x03, + 0xac, 0x24, 0xfa, 0x4f, 0x05, 0xe3, 0x16, 0x29, 0x7c, 0xff, 0x63, 0xd5, + 0x0a, 0x0a, 0xbd, 0xd7, 0x65, 0x3a, 0xb5, 0x5e, 0xe7, 0x23, 0xfc, 0x3d, + 0x08, 0xea, 0x62, 0xc2, 0xe3, 0x4a, 0xbb, 0x86, 0x5a, 0xc5, 0x93, 0xd7, + 0xbc, 0xb4, 0x4c, 0xcf, 0xcf, 0x78, 0x9f, 0x52, 0x6e, 0xa1, 0x49, 0x21, + 0xf7, 0x20, 0x42 +}; +static const unsigned int privk_len = sizeof(privk); + +/* Signature data (a secure hash, possibly signed) */ +struct vb2_signature { + /* Offset of signature data from start of this struct */ + uint32_t sig_offset; + uint32_t reserved0; + + /* Size of signature data in bytes */ + uint32_t sig_size; + uint32_t reserved1; + + /* Size of the data block which was signed in bytes */ + uint32_t data_size; + uint32_t reserved2; +} __attribute__((packed)); + +/* + * Preamble block for kernel, version 2.2 + * + * This should be followed by: + * 1) The signature data for the kernel body, pointed to by + * body_signature.sig_offset. + * 2) The signature data for (vb2_kernel_preamble + body signature data), + * pointed to by preamble_signature.sig_offset. + * 3) The 16-bit vmlinuz header, which is used for reconstruction of + * vmlinuz image. + */ +struct vb2_kernel_preamble { + /* + * Size of this preamble, including keys, signatures, vmlinuz header, + * and padding, in bytes + */ + uint32_t preamble_size; + uint32_t reserved0; + + /* Signature for this preamble (header + body signature) */ + struct vb2_signature preamble_signature; + + /* Version of this header format */ + uint32_t header_version_major; + uint32_t header_version_minor; + + /* Kernel version */ + uint32_t kernel_version; + uint32_t reserved1; + + /* Load address for kernel body */ + uint64_t body_load_address; + + /* Address of bootloader, after body is loaded at body_load_address */ + uint64_t bootloader_address; + + /* Size of bootloader in bytes */ + uint32_t bootloader_size; + uint32_t reserved2; + + /* Signature for the kernel body */ + struct vb2_signature body_signature; + + /* Address of 16-bit header for vmlinuz reassembly. */ + uint64_t vmlinuz_header_address; + + /* Size of 16-bit header for vmlinuz in bytes. */ + uint32_t vmlinuz_header_size; + uint32_t reserved3; + + uint32_t flags; +} __attribute__((packed)); + +/* + * Order matters. |data| may overlap with |siginfo|, so we need to fill out + * |siginfo| before computing the signature. + */ +static int sign(const void *data, size_t len, struct vb2_signature *siginfo, + void *sigout) +{ + unsigned char hash[SHA256_DIGEST_LENGTH]; + SHA256_CTX sha256; + int ret; + + memset(siginfo, 0, sizeof(*siginfo)); + siginfo->sig_offset = (uintptr_t)(void *)sigout - (uintptr_t)(void *)siginfo; + siginfo->sig_size = SIG_SIZE; + siginfo->data_size = len; + + const unsigned char *p = privk; + char digest_info[] = { + 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20, + }; + + uint8_t digest[sizeof(digest_info) + sizeof(hash)]; + + SHA256_Init(&sha256); + SHA256_Update(&sha256, data, len); + SHA256_Final(hash, &sha256); + + memcpy(digest, digest_info, sizeof(digest_info)); + memcpy(digest + sizeof(digest_info), hash, sizeof(hash)); + + RSA *key = d2i_RSAPrivateKey(0, &p, privk_len); + if (!key) { + fprintf(stderr, "Failed d2i_RSAPrivateKey()\n"); + return -1; + } + + ret = RSA_private_encrypt(sizeof(digest), digest, sigout, key, + RSA_PKCS1_PADDING); + if (ret == -1) { + fprintf(stderr, "%s: RSA_private_encrypt() failed\n", __func__); + return -1; + } + + return 0; +} + +static struct vb2_kernel_preamble * +generate_preamble(const void *kblob, size_t kblob_len, + size_t kernel_len, size_t config_len) +{ + struct vb2_kernel_preamble *h; + uint32_t signed_size = sizeof(struct vb2_kernel_preamble) + SIG_SIZE; + uint32_t block_size = signed_size + SIG_SIZE; + int ret; + + if (block_size + keyblock_len < BLOCK_PAD) + block_size = BLOCK_PAD - keyblock_len; + h = (struct vb2_kernel_preamble *)calloc(block_size, 1); + if (!h) { + perror("calloc"); + return NULL; + } + + /* Sign the body, place the signature in the preamble */ + ret = sign(kblob, kblob_len, &h->body_signature, h + 1); + if (ret) { + fprintf(stderr, "sign() failed: %d\n", ret); + return NULL; + } + + h->header_version_major = 2; + h->header_version_minor = 2; + h->preamble_size = block_size; + h->kernel_version = 1; + h->body_load_address = 0x100000; + /* + * "Bootloder" area (currently empty) is after kernel + config + + * parameter page. + */ + h->bootloader_address = h->body_load_address + + ROUNDUP(kernel_len) + + ROUNDUP(config_len) + + ALIGN; + h->bootloader_size = 0x1000; + h->vmlinuz_header_address = 0; + h->vmlinuz_header_size = 0; + h->flags = 0; + + ret = sign(h, signed_size, &h->preamble_signature, + (void *)(h + 1) + SIG_SIZE); + if (ret) { + fprintf(stderr, "failed to sign preamble: %d\n", ret); + return NULL; + } + return h; +} + + +/* + * Distilled from vboot_reference futility/cmd_vbutil_kernel.c pack command. + * + * NB: "config" is the kernel cmdline + */ +static int vbutil_pack(const char *kernel, size_t kernel_len, + const char *config, size_t config_len, + void **out, size_t *out_len) +{ + int ret; + size_t kblob_len = ROUNDUP(kernel_len) + ROUNDUP(config_len) + ALIGN + ALIGN; + void *kblob = malloc(kblob_len); + if (!kblob) { + perror("malloc"); + return -1; + } + void *kp = kblob; + memset(kblob, 0, kblob_len); + + /* Kernel */ + memcpy(kp, kernel, kernel_len); + kp += ROUNDUP(kernel_len); + + /* Kernel command line */ + memcpy(kp, config, config_len); + kp += ROUNDUP(config_len); + + /* "Parameters" -- empty, 4K-aligned */ + /* "Bootloader" region -- empty, 4K-aligned */ + /* Vmlinuz header -- only for x86 (not currently supported), empty */ + + struct vb2_kernel_preamble *h; + h = generate_preamble(kblob, kblob_len, kernel_len, config_len); + if (!h) { + fprintf(stderr, "Failed to generate preamble\n"); + return -1; + } + size_t outlen = sizeof(keyblock) + h->preamble_size + kblob_len; + void *outbuf = malloc(outlen); + if (!outbuf) + return -1; + + void *p = outbuf; + memcpy(p, keyblock, sizeof(keyblock)); + p += sizeof(keyblock); + + memcpy(p, h, h->preamble_size); + p += h->preamble_size; + + memcpy(p, kblob, kblob_len); + p += kblob_len; + + if (outbuf) { + *out = outbuf; + *out_len = outlen; + } + + return 0; +} + +static void * read_file(const char *path, size_t *out_len) +{ + struct stat st; + int fd = open(path, O_RDONLY); + if (fd == -1) { + perror("failed to open"); + return NULL; + } + + if (fstat(fd, &st) < 0) { + perror("fstat"); + return NULL; + } + + size_t len = st.st_size; + void *p = malloc(len); + if (!p) + return NULL; + + size_t count = 0; + while (count < len) { + ssize_t ret = read(fd, p + count, len - count); + if (ret < 0) { + perror("read"); + return NULL; + } + count += ret; + } + + close(fd); + + *out_len = len; + return p; +} + +int main(int argc, char * const argv[]) +{ + int i, ret; + const char *kernel_file = NULL; + const char *out_file = NULL; + const char *cmdline = NULL; + size_t cmdline_len; + void *kernel; + size_t kernel_len; + void *out; + size_t out_len; + + int opt; + while ((opt = getopt(argc, argv, "k:c:o:")) != -1) { + switch (opt) { + case 'k': + kernel_file = optarg; + break; + case 'c': + cmdline = optarg; + break; + case 'o': + out_file = optarg; + break; + default: + fprintf(stderr, "Usage [-k ] [-c ] -o \n"); + return -1; + } + } + if (optind < argc) { + fprintf(stderr, "Unexpected args?\n"); + return -1; + } + if (!out_file || !cmdline || !kernel_file) { + fprintf(stderr, "Missing required argument\n"); + return -1; + } + + /* Include the \0 terminator */ + cmdline_len = strlen(cmdline) + 1; + + kernel = read_file(kernel_file, &kernel_len); + if (!kernel) { + fprintf(stderr, "failed to read kernel file: %s\n", kernel_file); + return -1; + } + + ret = vbutil_pack(kernel, kernel_len, cmdline, cmdline_len, &out, &out_len); + if (ret) + return ret; + + int fd = open(out_file, O_RDWR|O_CREAT, 0644); + if (fd == -1) { + perror("open"); + return -1; + } + + ret = write(fd, out, out_len); + if (ret == -1) { + perror("write"); + return -1; + } + close(fd); + + return 0; +} From patchwork Sun Jan 17 03:07:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Norris X-Patchwork-Id: 1427676 X-Patchwork-Delegate: mail@aparcar.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.openwrt.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=fWxsJS//; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=mI1xWMdV; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DJKfM4X2Mz9sWL for ; Sun, 17 Jan 2021 14:10:03 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=m7gwG12zOO4MrgEZpmgH/DzfR5u9n+eovIUOJPiB0dM=; b=fWxsJS//7tEP2lryvK2v1OWdO vpc3uZDNDO9cG3lRj7PnBAFyPdTrrOKWv/TbiYC/rpXXhs1at5vjkywzORllFaOhWMrr4a6/FQ/Do olxiv1Zipu2m08BIP2JrFtRSMx/hAjbeN4l97IUx5tQkO4Gq3opIw+/eyh+zK+9HZVFyZelvX3+E3 oKUX1KD18Cf+6qwoLuJG2tyy+NlsvJM2E9tk2I9qCF0/zZQ3HMQ4RcmYOrE26LhONAQPQlp1xlxpZ oWBzk3neWFrnwBPLedCuKwq8e5Ywwco7hc0mfNg5PvPwezk14Q4U0dYcctuw7Jv9Fj3hXwuBXVpjq 4rw99keXA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0yPf-00048j-F6; Sun, 17 Jan 2021 03:07:35 +0000 Received: from mail-pf1-x434.google.com ([2607:f8b0:4864:20::434]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0yPZ-00046c-Fw for openwrt-devel@lists.openwrt.org; Sun, 17 Jan 2021 03:07:31 +0000 Received: by mail-pf1-x434.google.com with SMTP id f63so276717pfa.13 for ; Sat, 16 Jan 2021 19:07:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=l7ndJ8tvIcBoYc9vAK4sloQynq52nSYYMLqxmNPOYf4=; b=mI1xWMdVsqE4/jTzq7w75Mypl9MhMcO5U63PYZIUS3azfP3Z7i4nuiEO1nZRm2uUCU ihBad0mMznbv8isJQunCr4EzNOGlboQvX1TLWuU6KhT34dASAfCzx8LinOHTMrDoANEF bJGwWVFhZ8UIYaTmE8B6C+tJ7AEZdxJc0xTdX/xTbpBa3j4Z1aLDQZgP5Q/9vToHCuZU ZLCekOSHo+AATpsKPm2W5iA7mfST3fk3j748V2atl/EInS1JEXhB5PQ/8CgEHGpdKmsx N0XuUOGyA9GzPKy04tEaWYLMoSZDXvDGRQRKMnGLl3JDuLva0SWcVl5x3P16NC/6NIvJ bhQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=l7ndJ8tvIcBoYc9vAK4sloQynq52nSYYMLqxmNPOYf4=; b=HwvJ6yyJDKKIEmE4A9Tka8u60Gxu/FaNYC0qqAc+Pq1w6KYqytJ/sYw2n/ULEpUCFD NNmtXORfxzg7L7uXEACTd8SFLsi8hquTcWr94KOfsZtBDvC0R+9N3FzUpyHo7s91Axmw Gk/AknP6It5kR2V8rvsRp9PxWv3Z0HybQc9qopXMFHRzBW7QPu2jbkBruW85bkDvi7U7 bncgT7ZpvRzICAb+lnX7yz3J0AT7THvh0b6YQox2OizORcW8FJ143Po4GDxb0KJQo3Pd Vo0INYUS5TLNtumTBSZFmu28p6i36tOaPRwjWgianFVuGL+/waRmv6FT1n15aym+n+XC Lhjg== X-Gm-Message-State: AOAM532M2iVbqVRjS+E1F8A7tWa3DJP+bcMTPqgxNw/OWrNRCzBOPOdA Fpt3gGm1jeskm4V4Z9X2jqXX/WPaFTM= X-Google-Smtp-Source: ABdhPJxDLQpML7mlwslA4kmJlWOiBG/TqbhHen/ruaC7a96qYKOdOKwseruVq0tw5VS9rN9dkvxcww== X-Received: by 2002:a63:d814:: with SMTP id b20mr20121148pgh.202.1610852843851; Sat, 16 Jan 2021 19:07:23 -0800 (PST) Received: from localhost ([2601:647:5800:2ac5:9eef:d5ff:fefc:64ae]) by smtp.gmail.com with ESMTPSA id d7sm2390235pfd.160.2021.01.16.19.07.23 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 16 Jan 2021 19:07:23 -0800 (PST) From: Brian Norris To: openwrt-devel@lists.openwrt.org Subject: [PATCH v2 3/4] image-commands: support Chromium OS image-type creation Date: Sat, 16 Jan 2021 19:07:05 -0800 Message-Id: <20210117030707.1251501-4-computersforpeace@gmail.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210117030707.1251501-1-computersforpeace@gmail.com> References: <20210117030707.1251501-1-computersforpeace@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210116_220730_217524_52BA8D1C X-CRM114-Status: GOOD ( 15.64 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:434 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [computersforpeace[at]gmail.com] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Brian Norris Sender: "openwrt-devel" Errors-To: openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org See the previous patches, which implemented the cros-vbutil verified-boot payload-packing tool, and extended ptgen for the CrOS kernel partition type. With these, it's now possible to package kernel + rootfs to make disk images that can boot a Chrome OS-based system (e.g., Chromebooks, or even a few AP models). gen_image_vboot.sh borrows a bit of structure from gen_image_generic.sh, but I didn't feel it fit well to try and add new flags to the latter, given the difference in its FAT kernel packaging and our raw kernel partition packing. Signed-off-by: Brian Norris --- include/image-commands.mk | 18 ++++++++++ .../base-files/files/lib/upgrade/common.sh | 4 ++- scripts/gen_image_vboot.sh | 36 +++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100755 scripts/gen_image_vboot.sh diff --git a/include/image-commands.mk b/include/image-commands.mk index 979eafb15734..f02d8e79fce6 100644 --- a/include/image-commands.mk +++ b/include/image-commands.mk @@ -172,6 +172,24 @@ define Build/fit @mv $@.new $@ endef +define Build/cros-image + $(SCRIPT_DIR)/gen_image_vboot.sh \ + $@ \ + $(CONFIG_TARGET_KERNEL_PARTSIZE) \ + $(CONFIG_TARGET_KERNEL_PARTSIZE) $(IMAGE_KERNEL) \ + $(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS) +endef + +# NB: Chrome OS bootloaders replace the '%U' in command lines with the UUID of +# the kernel partition it chooses to boot from. This gives a flexible way to +# consistently build and sign kernels that always use the subsequent +# (PARTNROFF=1) partition as their rootfs. +define Build/cros-vboot + $(STAGING_DIR_HOST)/bin/cros-vbutil \ + -k $@ -c "root=PARTUUID=%U/PARTNROFF=1" -o $@.new + @mv $@.new $@ +endef + define Build/gzip gzip -f -9n -c $@ $(1) > $@.new @mv $@.new $@ diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh index c28bae48a15c..a2ee8d1675a6 100644 --- a/package/base-files/files/lib/upgrade/common.sh +++ b/package/base-files/files/lib/upgrade/common.sh @@ -178,9 +178,11 @@ export_bootdevice() { fi done ;; + PARTUUID=????????-????-????-????-??????????01/PARTNROFF=1 | \ PARTUUID=????????-????-????-????-??????????02) uuid="${rootpart#PARTUUID=}" - uuid="${uuid%02}00" + uuid="${uuid%/PARTNROFF=1}" + uuid="${uuid%0?}00" for disk in $(find /dev -type b); do set -- $(dd if=$disk bs=1 skip=568 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"') if [ "$4$3$2$1-$6$5-$8$7-$9" = "$uuid" ]; then diff --git a/scripts/gen_image_vboot.sh b/scripts/gen_image_vboot.sh new file mode 100755 index 000000000000..ae267ba3fbb9 --- /dev/null +++ b/scripts/gen_image_vboot.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# Copyright (C) 2021 OpenWrt.org +set -e -x +[ $# == 6 ] || { + echo "SYNTAX: $0 " + exit 1 +} + +OUTPUT="$1" +BOOTPARTSIZE="$2" +KERNELSIZE="$3" +KERNELIMAGE="$4" +ROOTFSSIZE="$5" +ROOTFSIMAGE="$6" + +rm -f "${OUTPUT}" + +head=16 +sect=63 + +# create partition table +set $(ptgen -o "${OUTPUT}" -h $head -s $sect -g -p ${BOOTPARTSIZE}m -T cros_kernel -p ${KERNELSIZE}m -p ${ROOTFSSIZE}m) + +BOOTOFFSET="$(($1 / 512))" +BOOTSIZE="$2" +KERNELOFFSET="$(($3 / 512))" +KERNELSIZE="$4" +ROOTFSOFFSET="$(($5 / 512))" +ROOTFSSIZE="$(($6 / 512))" + +mkfs.fat -n boot -C "${OUTPUT}.boot" -S 512 "$((BOOTSIZE / 1024))" + +dd if="${OUTPUT}.boot" of="${OUTPUT}" bs=512 seek="${BOOTOFFSET}" conv=notrunc +rm -f "${OUTPUT}.boot" +dd if="${KERNELIMAGE}" of="${OUTPUT}" bs=512 seek="${KERNELOFFSET}" conv=notrunc +dd if="${ROOTFSIMAGE}" of="${OUTPUT}" bs=512 seek="${ROOTFSOFFSET}" conv=notrunc From patchwork Sun Jan 17 03:07:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Norris X-Patchwork-Id: 1427679 X-Patchwork-Delegate: mail@aparcar.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.openwrt.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=sj0dictn; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=XfhGsmaB; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DJKfL2JHTz9sWF for ; Sun, 17 Jan 2021 14:10:01 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=87jWnwOUULRPnxKeSn2TGFt8dzaHfoiZ6Ep4PwKYdBg=; b=sj0dictn40HajvP9ktbrySrAb Iyp44afdioyfe0lniRm7wQHpTH7p742DWBgop0M0fGEc69gff2xD6vpMXFg9gJqR2pygJo8zMQggQ d0G0PRmlRmol6kMxwPH23OD46433FE0E7DILIbHaP/lcu1dx7X0iJA01iBNjaDmo3z9glEfqPcLqc 7APE2mFxnuHT42gJk2x1kUAiBDcEFyKeaheoSEBosehJiYkWyQYPMxjmWbikWl0IXN6gbJ8BIwXxS bemuawaxm3+MmgHcOx0YaKR7UjgMbAg0CJ36OLOG65XKmdy8XT1M8EZxm+fM5I+ItdO6FPjWdtg// wjKfD57ug==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0yPk-00049n-Gm; Sun, 17 Jan 2021 03:07:40 +0000 Received: from mail-pg1-x52a.google.com ([2607:f8b0:4864:20::52a]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0yPZ-00046h-6w for openwrt-devel@lists.openwrt.org; Sun, 17 Jan 2021 03:07:34 +0000 Received: by mail-pg1-x52a.google.com with SMTP id i7so8746428pgc.8 for ; Sat, 16 Jan 2021 19:07:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=wSnG2QKxLxf4G0mXusY5b7B+rQXr+gjNOY6xGWQSj7U=; b=XfhGsmaB27c6gtpfy/RN7Yp9fx7QzpZRWmkGsnqhFI3enaij+xoznXmZtTl9vidrwo FJGe9owZ0JJq8Le6KUu1ZHw9WeZ0IeY7oVBABqVIetx4MkpVDRe2PgB37OO8V08vN6YM 6gVvkSKQI6IBDDPp2essvGHsuu+4OiRdqP7r2tVyZX858WhnzbAyB96davI3mzKTWHRo YeGpga/hpWnEyP9VXTiPNXJm8+nPrUG6JgE5DRV/YdHavfsQe4Yett0L/YgfnGAaU0f5 5P1VUiUARJY3pOUmoBLiAdoRAGVOcVN6wcTpI+QEjUiSpLNEhf8mSM/O1rvbvuPvhq7X DD9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wSnG2QKxLxf4G0mXusY5b7B+rQXr+gjNOY6xGWQSj7U=; b=DcffOkmlnELQaKLm5ubCSXNr2ZEQcUHTm8TNLKsiIbAXsA+fcwXlsZGbAn/47LKNPL R6fHaXwEi12azlNcr1gccEspJ4Rl0RZF3u0ZG9YdEnH6HoMNJt4ygkpLCFRPRY8ul5BT V7KGqxJL420rGQ9vgALaJTmYzzERrRCMUQ4Od6In8nETGbfTn8ifd9X+nj+sd+xTHEsf hZzVP2zkwWU+1RNnOsOch3RNJ3OC6BKkP3OKm8h6dIxvDuIrPBkbNMouPAxatkShCxhN 3spG134Y7qrVHM/zsythmqN29GrcK27cYMk2jaWuc9VphEo7/WKV0y/nrtqxH0TiRoPK coFw== X-Gm-Message-State: AOAM531z0cU7xOuxEKM5p+bL7fPkBmNBXNNnxp7bq9usxtIMV4A7lYB8 du1WO6tZV/dplgbZ3MY9lKirLnLbG9E= X-Google-Smtp-Source: ABdhPJzk5dx8wOKmvt4DT9MSfovmTTg7hiq7uxSUXJzZAa0TsDxi2kyZpEElTdh0TwgwdWDGSftrMA== X-Received: by 2002:a63:ca51:: with SMTP id o17mr20327026pgi.314.1610852845688; Sat, 16 Jan 2021 19:07:25 -0800 (PST) Received: from localhost ([2601:647:5800:2ac5:9eef:d5ff:fefc:64ae]) by smtp.gmail.com with ESMTPSA id u4sm8109199pjv.22.2021.01.16.19.07.24 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 16 Jan 2021 19:07:25 -0800 (PST) From: Brian Norris To: openwrt-devel@lists.openwrt.org Subject: [PATCH v2 4/4] ipq40xx: add target for Google WiFi (Gale) Date: Sat, 16 Jan 2021 19:07:06 -0800 Message-Id: <20210117030707.1251501-5-computersforpeace@gmail.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210117030707.1251501-1-computersforpeace@gmail.com> References: <20210117030707.1251501-1-computersforpeace@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210116_220730_237681_DCCE5B11 X-CRM114-Status: GOOD ( 25.27 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:52a listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [computersforpeace[at]gmail.com] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Brian Norris Sender: "openwrt-devel" Errors-To: openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org Google WiFi (codename: Gale) is an IPQ4019-based AP, with 2 Ethernet ports, 2x2 2.4+5GHz WiFi, 512 MB RAM, 4 GB eMMC, and a USB type C port. In its stock configuration, it runs a Chromium OS-based system, but you wouldn't know it, since you can only manage it via a "cloud" + mobile-app system. The "v2" label is coded into the bootloader, which prefers the "google,gale-v2" compatible string. I believe "v1" must have been pre-release hardware. Note: this is *not* the Google Nest WiFi, released in 2019. I include "factory.bin" support, where we generate a GPT-based disk image with 3 partitions -- a spare FAT partition, a kernel partition (using the custom "Chrome OS kernel" GUID type) and a root filesystem partition. See below for flashing instructions. Sysupgrade is only partially working. "FEATURES=boot-part rootfs-part" is required to get kernel and rootfs partition sizes established. This adds extra (unused) configuration parameters for other ipq40xx targets, so I'm not sure if this is the "right" thing to do either. Flashing instructions ===================== [ NB: you may still need to tweak which drivers are built-in, if you want to boot from a USB disk. ] Chrome OS systems allow booting custom images only when transitioned into Developer Mode. Existing sources document how to enter Developer Mode on a Google WiFi system: https://github.com/marcosscriven/galeforce#how-to-apply-an-image The OpenWRT-relevant summary: 1. Flash factory.bin to a USB storage device (e.g., with 'dd') 2. Pop off the case 3. Attach a USB-C hub with power delivery 4. Press the reset button on the back until light blinks orange (>16 seconds) 5. Once blinking orange, hit the tiny bubble switch (SW7) found on the board 6. Device will start blinking purple and restart 7. Wait until device restarts and starts blinking purple again 7. Plug in USB stick 8. Hit bubble switch again The device should boot to OpenWRT. If you want to persist to the eMMC, flash factory.bin to /dev/mmcblk0. Features ======== I've tested: * Ethernet, both WAN and LAN ports * eMMC * USB-C (hub, power-delivery, peripherals) * LED0 (R/G/B) * WiFi (limited testing) * SPI flash * Serial console: once in developer mode, console can be accessed via the USB-C port with SuzyQable, or other similar "Closed Case Debugging" tools: https://chromium.googlesource.com/chromiumos/third_party/hdctools/+/master/docs/ccd.md#suzyq-suzyqable Not tested: * TPM * LED1, LED2: I'm not even confident they are actually populated anywhere Known not working: * Reboot: this requires some additional TrustZone / SCM configuration to disable Qualcomm's SDI. I have a proposal upstream, and based on IRC chats, this might be acceptable with additional DT logic: [RFC PATCH] firmware: qcom_scm: disable SDI at boot https://lore.kernel.org/linux-arm-msm/20200721080054.2803881-1-computersforpeace@gmail.com/ * SMP: enabling secondary CPUs doesn't currently work using the stock bootloader, as the qcom_scm driver assumes newer features than this TrustZone firmware has. I posted notes here: [RFC] qcom_scm: IPQ4019 firmware does not support atomic API? https://lore.kernel.org/linux-arm-msm/20200913201608.GA3162100@bDebian/ * There's a single external button, and a few useful internal GPIO switches. I haven't hooked them up. Additional notes ================ Much of the DTS is pulled from the Chrome OS kernel 3.18 branch, which the manufacturer image uses. Note: the manufacturer bootloader knows how to patch in calibration data via the wifi{0,1} aliases in the DTB, so while these properties aren't present in the DTS, they are available at runtime: # ls -l /sys/firmware/devicetree/base/soc/wifi@a*/qcom,ath10k-pre-calibration-data -r--r--r-- 1 root root 12064 Jul 15 19:11 /sys/firmware/devicetree/base/soc/wifi@a000000/qcom,ath10k-pre-calibration-data -r--r--r-- 1 root root 12064 Jul 15 19:11 /sys/firmware/devicetree/base/soc/wifi@a800000/qcom,ath10k-pre-calibration-data Ethernet MAC addresses are similarly patched in via the ethernet{0,1} aliases. Signed-off-by: Brian Norris --- v2: * include more verbose flashing instructions * rename to "google_wifi" in most contexts, with "gale" only used as a secondary name, so the bootloader can find the DTB * other formalities (alphabetization, etc.) --- target/linux/ipq40xx/Makefile | 2 +- .../ipq40xx/base-files/etc/board.d/02_network | 1 + .../base-files/lib/upgrade/platform.sh | 16 + .../arch/arm/boot/dts/qcom-ipq4019-wifi.dts | 402 ++++++++++++++++++ target/linux/ipq40xx/image/Makefile | 13 + .../901-arm-boot-add-dts-files.patch | 3 +- 6 files changed, 435 insertions(+), 2 deletions(-) create mode 100644 target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-wifi.dts diff --git a/target/linux/ipq40xx/Makefile b/target/linux/ipq40xx/Makefile index 4d9b2debcaed..7f4c084da6b4 100644 --- a/target/linux/ipq40xx/Makefile +++ b/target/linux/ipq40xx/Makefile @@ -3,7 +3,7 @@ include $(TOPDIR)/rules.mk ARCH:=arm BOARD:=ipq40xx BOARDNAME:=Qualcomm Atheros IPQ40XX -FEATURES:=squashfs fpu ramdisk nand +FEATURES:=squashfs fpu ramdisk nand boot-part rootfs-part CPU_TYPE:=cortex-a7 CPU_SUBTYPE:=neon-vfpv4 SUBTARGETS:=generic diff --git a/target/linux/ipq40xx/base-files/etc/board.d/02_network b/target/linux/ipq40xx/base-files/etc/board.d/02_network index fe21dc80352e..59f849092841 100755 --- a/target/linux/ipq40xx/base-files/etc/board.d/02_network +++ b/target/linux/ipq40xx/base-files/etc/board.d/02_network @@ -43,6 +43,7 @@ ipq40xx_setup_interfaces() cilab,meshpoint-one|\ edgecore,ecw5211|\ edgecore,oap100|\ + google,wifi|\ openmesh,a42|\ openmesh,a62) ucidef_set_interfaces_lan_wan "eth1" "eth0" diff --git a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh index 558269675935..5142907f7baa 100644 --- a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh +++ b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh @@ -40,6 +40,19 @@ askey_do_upgrade() { nand_do_upgrade "$1" } +vboot_do_upgrade() { + local tar_file="$1" + + local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$') + board_dir=${board_dir%/} + + echo "Preparing to flash \"${board_dir}\" to /dev/mmcblk0p{1,2}" + ask_bool 0 "Abort" && exit 1 + + tar Oxf "${tar_file}" "${board_dir}/kernel" | dd of=/dev/mmcblk0p2 bs=1M + tar Oxf "${tar_file}" "${board_dir}/root" | dd of=/dev/mmcblk0p3 bs=1M +} + zyxel_do_upgrade() { local tar_file="$1" @@ -102,6 +115,9 @@ platform_do_upgrade() { compex,wpj419) nand_do_upgrade "$1" ;; + google,wifi) + vboot_do_upgrade "$1" + ;; linksys,ea6350v3 |\ linksys,ea8300 |\ linksys,mr8300) diff --git a/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-wifi.dts b/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-wifi.dts new file mode 100644 index 000000000000..732b10886c64 --- /dev/null +++ b/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-wifi.dts @@ -0,0 +1,402 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2016, 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016 Google, Inc + */ + +#include "qcom-ipq4019.dtsi" +#include +#include + +/ { + model = "Google WiFi (Gale)"; + compatible = "google,wifi", "google,gale-v2", "qcom,ipq4019"; + + chosen { + stdout-path = &blsp1_uart1; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x20000000>; /* 512MB */ + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + rsvd@87000000 { + /* Reserved for other subsystem */ + reg = <0x87000000 0x01000000>; + no-map; + }; + }; + + soc { + blsp_dma: dma@7884000 { + status = "okay"; + }; + + usb3: usb3@8af8800 { + status = "okay"; + }; + + usb2: usb2@60f8800 { + status = "okay"; + }; + + rng@22000 { + status = "okay"; + }; + + ess-switch@c000000 { + status = "okay"; + }; + + edma@c080000 { + status = "okay"; + }; + + ess-psgmii@98000 { + status = "okay"; + }; + + watchdog@b017000 { + status = "okay"; + }; + }; +}; + +&tlmm { + fw_pinmux { + wp { + pins = "gpio53"; + output-low; + }; + recovery { + pins = "gpio57"; + bias-none; + }; + developer { + pins = "gpio41"; + bias-none; + }; + }; + + reset802_15_4 { + pins = "gpio60"; + }; + + led_reset { + pins = "gpio22"; + output-high; + }; + + sys_reset { + pins = "gpio19"; + output-high; + }; + + rx_active { + pins = "gpio43"; + bias-pull,down; + }; + + spi_0_pins: spi_0_pinmux { + pinmux { + function = "blsp_spi0"; + pins = "gpio13", "gpio14","gpio15"; + }; + pinmux_cs { + function = "gpio"; + pins = "gpio12"; + }; + pinconf { + pins = "gpio13", "gpio14","gpio15"; + drive-strength = <12>; + bias-disable; + }; + pinconf_cs { + pins = "gpio12"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + + spi_1_pins: spi_1_pinmux { + pinmux { + function = "blsp_spi1"; + pins = "gpio44", "gpio46","gpio47"; + }; + pinmux_cs { + function = "gpio"; + pins = "gpio45"; + }; + pinconf { + pins = "gpio44", "gpio46","gpio47"; + drive-strength = <12>; + bias-disable; + }; + pinconf_cs { + pins = "gpio45"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + + serial_0_pins: serial0_pinmux { + mux { + pins = "gpio16", "gpio17"; + function = "blsp_uart0"; + bias-disable; + }; + }; + + serial_1_pins: serial1_pinmux { + mux { + pins = "gpio8", "gpio9", "gpio10", "gpio11"; + function = "blsp_uart1"; + bias-disable; + }; + }; + + i2c_0_pins: i2c_0_pinmux { + mux { + pins = "gpio20", "gpio21"; + function = "blsp_i2c0"; + drive-open-drain; + }; + }; + + i2c_1_pins: i2c_1_pinmux { + mux { + pins = "gpio34", "gpio35"; + function = "blsp_i2c1"; + drive-open-drain; + }; + }; + + sd_0_pins: sd_0_pinmux { + sd0 { + pins = "gpio23", "gpio24", "gpio25", "gpio26", "gpio29", "gpio30", "gpio31", "gpio32"; + function = "sdio"; + drive-strength = <10>; + bias-pull-up; + pull-up-res = <0>; + }; + sdclk { + pins = "gpio27"; + function = "sdio"; + drive-strength = <2>; + bias-pull-up; + pull-up-res = <0>; + }; + sdcmd { + pins = "gpio28"; + function = "sdio"; + drive-strength = <10>; + bias-pull-up; + pull-up-res = <0>; + }; + }; + + mdio_pins: mdio_pinmux { + mux_1 { + pins = "gpio6"; + function = "mdio"; + bias-disable; + }; + mux_2 { + pins = "gpio7"; + function = "mdc"; + bias-disable; + }; + mux_3 { + pins = "gpio40"; + function = "gpio"; + bias-disable; + output-high; + }; + }; + + wifi1_1_pins: wifi2_pinmux { + mux { + pins = "gpio58"; + output-low; + }; + }; +}; + +&blsp1_i2c3 { + pinctrl-0 = <&i2c_0_pins>; + pinctrl-names = "default"; + status = "okay"; + + trusted-platform-module@20 { + compatible = "infineon,slb9645tt"; + reg = <0x20>; + powered-while-suspended; + }; +}; + +&blsp1_i2c4 { + pinctrl-0 = <&i2c_1_pins>; + pinctrl-names = "default"; + status = "okay"; + + lp55231@32 { + compatible = "national,lp5523"; + reg = <0x32>; + clock-mode = [01]; + + chan0 { + chan-name = "LED0_Red"; + led-cur = [64]; + max-cur = [78]; + }; + + chan1 { + chan-name = "LED0_Green"; + led-cur = [64]; + max-cur = [78]; + }; + + chan2 { + chan-name = "LED0_Blue"; + led-cur = [64]; + max-cur = [78]; + }; + + chan3 { + chan-name = "LED1_Red"; + led-cur = [64]; + max-cur = [78]; + }; + + chan4 { + chan-name = "LED1_Green"; + led-cur = [64]; + max-cur = [78]; + }; + + chan5 { + chan-name = "LED1_Blue"; + led-cur = [64]; + max-cur = [78]; + }; + + chan6 { + chan-name = "LED2_Red"; + led-cur = [64]; + max-cur = [78]; + }; + + chan7 { + chan-name = "LED2_Green"; + led-cur = [64]; + max-cur = [78]; + }; + + chan8 { + chan-name = "LED2_Blue"; + led-cur = [64]; + max-cur = [78]; + }; + }; +}; + +&blsp1_spi1 { + pinctrl-0 = <&spi_0_pins>; + pinctrl-names = "default"; + status = "okay"; + cs-gpios = <&tlmm 12 0>; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <24000000>; + }; +}; + +&blsp1_spi2 { + pinctrl-0 = <&spi_1_pins>; + pinctrl-names = "default"; + status = "okay"; + cs-gpios = <&tlmm 45 0>; + + spidev@0 { + compatible = "spidev"; + reg = <0>; + spi-max-frequency = <24000000>; + }; +}; + +&blsp1_uart1 { + pinctrl-0 = <&serial_0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&blsp1_uart2 { + pinctrl-0 = <&serial_1_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&gmac0 { + qcom,phy_mdio_addr = <4>; + qcom,poll_required = <1>; + qcom,forced_speed = <1000>; + qcom,forced_duplex = <1>; + vlan_tag = <2 0x20>; +}; + +&gmac1 { + qcom,phy_mdio_addr = <3>; + qcom,forced_duplex = <1>; + vlan_tag = <1 0x10>; +}; + +&mdio { + status = "okay"; + pinctrl-0 = <&mdio_pins>; + pinctrl-names = "default"; +}; + +&sdhci { + status = "okay"; + pinctrl-0 = <&sd_0_pins>; + pinctrl-names = "default"; + clock-frequency = <192000000>; + vqmmc-supply = <&vqmmc>; + non-removable; +}; + +&usb2_hs_phy { + status = "okay"; +}; + +&usb3_ss_phy { + status = "okay"; +}; + +&usb3_hs_phy { + status = "okay"; +}; + +&vqmmc { + status = "okay"; +}; + +&wifi0 { + status = "okay"; +}; + +&wifi1 { + status = "okay"; + pinctrl-0 = <&wifi1_1_pins>; + pinctrl-names = "default"; +}; diff --git a/target/linux/ipq40xx/image/Makefile b/target/linux/ipq40xx/image/Makefile index c19dcb40397d..81f2df61f8b4 100644 --- a/target/linux/ipq40xx/image/Makefile +++ b/target/linux/ipq40xx/image/Makefile @@ -522,6 +522,19 @@ define Device/glinet_gl-s1300 endef TARGET_DEVICES += glinet_gl-s1300 +define Device/google_wifi + DEVICE_VENDOR := Google + DEVICE_MODEL := WiFi (Gale) + SOC := qcom-ipq4019 + KERNEL_SUFFIX := -fit-zImage.itb.vboot + KERNEL = kernel-bin | fit none $$(DTS_DIR)/$$(DEVICE_DTS).dtb | cros-vboot + KERNEL_NAME := zImage + IMAGES += factory.bin + IMAGE/factory.bin := cros-image + DEVICE_PACKAGES := partx-utils mkf2fs e2fsprogs +endef +TARGET_DEVICES += google_wifi + define Device/linksys_ea6350v3 # The Linksys EA6350v3 has a uboot bootloader that does not # support either booting lzma kernel images nor booting UBI diff --git a/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch b/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch index a3d3341587d8..9a138c6ed720 100644 --- a/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch +++ b/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch @@ -10,7 +10,7 @@ Signed-off-by: John Crispin --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile -@@ -837,11 +837,58 @@ dtb-$(CONFIG_ARCH_QCOM) += \ +@@ -837,11 +837,59 @@ dtb-$(CONFIG_ARCH_QCOM) += \ qcom-apq8074-dragonboard.dtb \ qcom-apq8084-ifc6540.dtb \ qcom-apq8084-mtp.dtb \ @@ -57,6 +57,7 @@ Signed-off-by: John Crispin + qcom-ipq4019-pa2200.dtb \ + qcom-ipq4019-rtl30vw.dtb \ + qcom-ipq4019-u4019-32m.dtb \ ++ qcom-ipq4019-wifi.dtb \ + qcom-ipq4019-wpj419.dtb \ + qcom-ipq4019-wtr-m2133hp.dtb \ + qcom-ipq4028-wpj428.dtb \