From patchwork Tue Jan 21 07:55:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: 'Darko Komljenovic' via swupdate X-Patchwork-Id: 1226282 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=googlegroups.com (client-ip=2a00:1450:4864:20::13d; helo=mail-lf1-x13d.google.com; envelope-from=swupdate+bncbc6ynavgsakrbe65tlyqkgqeiu5f7aq@googlegroups.com; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=googlegroups.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=googlegroups.com header.i=@googlegroups.com header.a=rsa-sha256 header.s=20161025 header.b=PX3aKm9H; dkim-atps=neutral Received: from mail-lf1-x13d.google.com (mail-lf1-x13d.google.com [IPv6:2a00:1450:4864:20::13d]) (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 48217W2ksjz9sRK for ; Tue, 21 Jan 2020 18:56:07 +1100 (AEDT) Received: by mail-lf1-x13d.google.com with SMTP id t8sf612691lfc.21 for ; Mon, 20 Jan 2020 23:56:07 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1579593364; cv=pass; d=google.com; s=arc-20160816; b=qygkQyUsAQY4ekWpfmsQrIE0dtWLxvRT2mDxhXgderOq+wydzXqaHH1ySltGHui9pV G7aTTYOQDu7M2DIKFQqpdbA2kiOlD6Avv0zII/b1OR82XpXt3z4vbQkAehCRPIsgr5fS v+vYefX61Bvrhm7+1FAx1p1MLybtU536NR0XiwQg0l189KA6OonY9FRz01N/2d6AAvTH DSVwr8a/dR94WFtH8CQQKT+YjnYsHhoRb2Nxp1PxALZNT5dC6w1wyr6L2UF7mhNCgi4G XT7Qxf01QN+nZwd7cWUC7F5jALPIeJ/+Oy5mR+Lv9AuulkNQIiNJnJOcYO/LU9dH1CIy H9Iw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:reply-to:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature; bh=kUdX58E/iS5wMAAIC1OO56H0XLBJazDiFenwGyynpMk=; b=qBkSdMVtBV6FIkDTYYzHnH5N8CxDuBvVOeGxGRLdWvCLzbbe4WvSWxvqn0C408ZhGq 4l/gur3jBtEiAU9VgOmdJ3SAhi7xMTBNzKk25NL4ztGe/TepV7qrSgckHFfEjbD7UPsd m5xQnMXtl+3fNMoFqrrYPaETh6UxHpYI5QgDKzQh/lKxN268Wu771ogpVHjluZguQ+oK 3IUum14+K+Z+jKuIG60VReqaRtVgFGLeo2wX+ayTMF4XwCOgPtkgybpishkdwKqdgDjl c+Y9L88T264U/bxIBqW827Z/48lzG5vdVfgMvfYTFNUPAmoV9O/ARLvuwVopCut1PlaY J+vg== ARC-Authentication-Results: i=2; gmr-mx.google.com; dkim=pass header.i=@de.bosch.com header.s=key2-intmail header.b=4m525uQQ; spf=pass (google.com: domain of mark.jonas@de.bosch.com designates 139.15.230.186 as permitted sender) smtp.mailfrom=Mark.Jonas@de.bosch.com; dmarc=pass (p=REJECT sp=NONE dis=NONE) header.from=de.bosch.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:x-original-sender:x-original-authentication-results :reply-to:precedence:mailing-list:list-id:list-post:list-help :list-archive:list-subscribe:list-unsubscribe; bh=kUdX58E/iS5wMAAIC1OO56H0XLBJazDiFenwGyynpMk=; b=PX3aKm9HiSuKwRbOeKb3fEQkh8Jmf5iMSFKG6ig1M3qeKgMSUiIYHH70W6sBXpnmXZ NkYTfD7RGf4TlB7IebXJOjI6BmV9zCE1tSiTOiEiLu3ULQ1djmW8TGG4EjUtoO2j9dQm Vd8TFD8+QVB9nO8Xno/SQbAh3bbNiYZKIuXIh+Mdva2LwGupnA3n2QOCvm7MCY2fOLgr WutOCtue2PH2x4+ipE7+Qcidqq9/YbsmziXCxNgGFpgFDx9lW7yLSIwH0xmOwE3fd43C Ai91m12GR+i6lW5KVw82dOOpBQqqghy3j9Lfr5CvHRAUGpaMArJn4ohbnwVTwBFVsyMS 17EA== 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:x-original-sender :x-original-authentication-results:reply-to:precedence:mailing-list :list-id:x-spam-checked-in-group:list-post:list-help:list-archive :list-subscribe:list-unsubscribe; bh=kUdX58E/iS5wMAAIC1OO56H0XLBJazDiFenwGyynpMk=; b=P/r8gU2vj44NL6+jVILTsAvzyvkfISgyL2zBFulB+v/SKqaA11+QNxIz5naBj3qFVe FnE3FbyBBJ9weQuGRSK2dpVgmd3YhrjyMZ065KBpcVQuVYK8f/v/4LOy8OySKhZrPR3R pOXXzSWofdVk7vaefuLSrG3q/0LdXWV+VkjDeK3LBjmLTQQsRTRfmNK5FWPPdn3F5hjY i2LxO/AvwYENJ7nprvjFha66uB7ov49lPDqCfICqXXXs/4wApEliTV0p0GUih+Jk11eh bW8AhJKKEr2QnrJQI8BPo147VckTtcBoiW81pvLkgUKdTOBygP3CZi5BJIxFH41fHVYd tBVA== X-Gm-Message-State: APjAAAVAUk+Gxt9a0bDA8dSz3eIFcfXKG3w0bnu5djoaDpENX3ne8sW1 Ss7CWjDPGUBfhOHDJsdxJtg= X-Google-Smtp-Source: APXvYqxO9ghqYoCyiY9I1hhf+b9I3Twg8LPO5GrYBboPfeZzqtTJsqydJAWVXCTCQdKxd/xaH16YJA== X-Received: by 2002:a05:651c:239:: with SMTP id z25mr15481403ljn.48.1579593363849; Mon, 20 Jan 2020 23:56:03 -0800 (PST) X-BeenThere: swupdate@googlegroups.com Received: by 2002:a19:ec09:: with SMTP id b9ls682158lfa.6.gmail; Mon, 20 Jan 2020 23:56:03 -0800 (PST) X-Received: by 2002:ac2:5e36:: with SMTP id o22mr2014196lfg.124.1579593363153; Mon, 20 Jan 2020 23:56:03 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579593363; cv=none; d=google.com; s=arc-20160816; b=Ji4rXIZ9IxDLIMsEfbDB5ZFnFK+1nX1lLdgBsQ7zI/O9vtXzslHNxjsIQfEl1KY4fB TnK03DALNH0KZlRbEEHA0386J+/YJy/D0lGYy9tkMeHBSYydPifpOKGd86b+gD6xXdi8 FR7+YxVSQGQpVJWsyYjsDI672ElPI/uPSujWNWQ6WY7zp96tu7mtGjb9hts2VwmhARgo 24vJZBjLCb8zseqf6eTTM+/p3osuMkShuQeNGISWWtSR8nkLK+OpQSX7REBzY0hXccQm HTE0ntfFyuAyZh3BkTACH5bEaf4Iu9oTxQ7P5blnvDrySP/gRHj7oTgI4HH1J2KS+Hl/ byqw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=OwzZYVLPZoMiOEu/r8XPzi1G2+moElAcYPhO9azPjyU=; b=tv8H8SSMEtG0PvrCfOqn8X4dmyDaXlHYvbOfH8Ft/Rvk+kjLD4BGI2ztYQ8m7wJeea CSselYH6yhIo9lGcZx+kjUxMLpjly95HwkCWsk1DJ492VTOGtJVWuazFHrBRJ+YLwSqn Vxc+/HP3wuyASNl75Y0ZrJupBOKrspcSpPTfRUceOvxbjCOUvmTSVlvcr+rOndGr4KLJ 0YMJzitGvNWe82CDTSI90t0rim5JBN9CxwkGs5otritHieGVIZGhJfMygpkAM1IX1sUs MUpmijNH6fpesWkVCp77cxdscZnurEqU4jR+Ku2AbZF3qNHwtEl12o2XbHaqoXLw/UCw t7JQ== ARC-Authentication-Results: i=1; gmr-mx.google.com; dkim=pass header.i=@de.bosch.com header.s=key2-intmail header.b=4m525uQQ; spf=pass (google.com: domain of mark.jonas@de.bosch.com designates 139.15.230.186 as permitted sender) smtp.mailfrom=Mark.Jonas@de.bosch.com; dmarc=pass (p=REJECT sp=NONE dis=NONE) header.from=de.bosch.com Received: from de-out1.bosch-org.com (de-out1.bosch-org.com. [139.15.230.186]) by gmr-mx.google.com with ESMTPS id j30si1908594lfp.5.2020.01.20.23.56.03 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Jan 2020 23:56:03 -0800 (PST) Received-SPF: pass (google.com: domain of mark.jonas@de.bosch.com designates 139.15.230.186 as permitted sender) client-ip=139.15.230.186; Received: from si0vm1948.rbesz01.com (unknown [139.15.230.188]) by si0vms0217.rbdmz01.com (Postfix) with ESMTPS id 48217Q2p1Gz4f3lwM; Tue, 21 Jan 2020 08:56:02 +0100 (CET) Received: from fe0vm1740.rbesz01.com (unknown [10.58.172.176]) by si0vm1948.rbesz01.com (Postfix) with ESMTPS id 48217Q2CX8z3rJ; Tue, 21 Jan 2020 08:56:02 +0100 (CET) X-AuditID: 0a3aad14-a97ff700000047f7-32-5e26ae91e444 Received: from si0vm1950.rbesz01.com ( [10.58.173.29]) (using TLS with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by fe0vm1740.rbesz01.com (SMG Outbound) with SMTP id 37.77.18423.19EA62E5; Tue, 21 Jan 2020 08:56:01 +0100 (CET) Received: from FE-HUB2000.de.bosch.com (fe-hub2000.de.bosch.com [10.4.103.109]) by si0vm1950.rbesz01.com (Postfix) with ESMTPS id 48217P1lvSzW79; Tue, 21 Jan 2020 08:56:01 +0100 (CET) Received: from ninja.grb-fir.grb.de.bosch.com (10.19.187.97) by FE-HUB2000.de.bosch.com (10.4.103.109) with Microsoft SMTP Server id 15.1.1847.3; Tue, 21 Jan 2020 08:56:00 +0100 X-Patchwork-Original-From: "'Mark Jonas' via swupdate" From: 'Darko Komljenovic' via swupdate To: , CC: , , , Mark Jonas Subject: [swupdate] [PATCH v3 1/4] handlers: add readback handler Date: Tue, 21 Jan 2020 08:55:50 +0100 Message-ID: <20200121075553.6677-2-mark.jonas@de.bosch.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200121075553.6677-1-mark.jonas@de.bosch.com> References: <20200121075553.6677-1-mark.jonas@de.bosch.com> MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA22Sa0hTcRjG/Z8dt7Ppacfjpm/TKE9oZbdZmeJEok9BQhL0pYs187itvLGz WUmlXdSMtLTE1DJbVpC3igItUztmqREliTfCqCSWZUWWOpTszKnbh749//d5f+/DeTiEiM6R qAhDsok1JmsTGbEMl0XULFpdUBsUq67s8w/P6YwOL26YcN+EbSkvbce3NBZ0iGOwnbLIeDbR kMYa10btk+lftN0Qpb5fcfhM2WOUifiAs0hKALUBWgfy8LNIRtBUMQatnwcxx+MxAsvbOonj 8RDBu6rv7nZETAVDf3u9yK4VVAj0frdhdi2ijkJF6YkZ7U1thBPdzTMapwLB9q1TYtckpYHx Z+ckjujFUHW3ZeaOlIqEZv4ybte0sJM/NjW77wUdJUO44z7AU6tVdAHJS12sUherAmF3kDKB VaclhYRtUK8xxrFcujpkzf6UpPvIUZqiHk3yCTzCCMSjUAJjlGRAeVAsvSAuJf6IXsvp9xrN iSzHqMiMb7l7aO/5MWeOSzJwnCElmUdAiBgFWXEyMJYm47VH0lljigPjkR+BM76kjti2m6Z0 WhN7kGVTWeOcqyEIBkh1jRDoZWR17OEEQ6JpzmYWkcjNzY32cXVcYzFCyqP1hKeQrbSfILlU bRJn0M3iCx04PTd1op0oTOVLZuUKDGV39ebk+VSVPzmcIxhKF8NJDqM+RCDGm/xaLex4Cn+g Mw/ITHtFXrNDJ7SuUmAoiy9MVy2D0UcjCMrr/yCwTowjqBy1IbCNFGEw2vULg8ahKQzqmoZx +H21yB2s97PE8CArRwztvY/E0HP7igS+lHwloK/ikgfcu13nAc8shSS0VY+T0PG7aAE05Frk YHvSJYfyv71yyL8yIYdzN597wejALxrOd1z0huriAgVk5b1RQFN2nhIGsy/6wGD3c59hoUtM 6PLQqpkuTVrTf7qcnTo/TpWJonZtfHnnh9hUttTvoUYf+/FVUEtGaFiEOWLHsjS5f3R+MzPW E1pyXDetHrggPbk5SkqGvutvKwLNtQF6JdPU8IGZXMKbXvxU3jp2+lR4sJ8yxjNy5emPAT1l aUOFW/2jjj9Nz69+vW/7T03MdUth7aexv3ygtTW9b2Rp7nLW/OoAg3N6bUiwyMhp/wECijV6 GgQAAA== X-Original-Sender: mark.jonas@de.bosch.com X-Original-Authentication-Results: gmr-mx.google.com; dkim=pass header.i=@de.bosch.com header.s=key2-intmail header.b=4m525uQQ; spf=pass (google.com: domain of mark.jonas@de.bosch.com designates 139.15.230.186 as permitted sender) smtp.mailfrom=Mark.Jonas@de.bosch.com; dmarc=pass (p=REJECT sp=NONE dis=NONE) header.from=de.bosch.com X-Original-From: Mark Jonas Reply-To: Mark Jonas Precedence: list Mailing-list: list swupdate@googlegroups.com; contact swupdate+owners@googlegroups.com List-ID: X-Spam-Checked-In-Group: swupdate@googlegroups.com X-Google-Group-Id: 605343134186 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , From: Kevin Zhang To verify that an image was written properly, this readback handler calculates the sha256 hash of a partition (or part of it) and compares it against a given hash value. Signed-off-by: Kevin Zhang Signed-off-by: Mark Jonas Acked-by: Stefano Babic --- handlers/Config.in | 12 ++++ handlers/Makefile | 1 + handlers/readback_handler.c | 125 ++++++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 handlers/readback_handler.c diff --git a/handlers/Config.in b/handlers/Config.in index 41eac1c..347552b 100644 --- a/handlers/Config.in +++ b/handlers/Config.in @@ -106,6 +106,18 @@ config RDIFFHANDLER Add support for applying librsync's rdiff patches, see http://librsync.sourcefrog.net/ +config READBACKHANDLER + bool "readback" + depends on HASH_VERIFY + default n + help + To verify that an image was written properly, this readback handler + calculates the sha256 hash of a partition (or part of it) and compares + it against a given hash value. + + This is a post-install handler running at the same time as + post-install scripts. + config LUASCRIPTHANDLER bool "Lua Script" depends on LUA diff --git a/handlers/Makefile b/handlers/Makefile index 61e4f76..b756f31 100644 --- a/handlers/Makefile +++ b/handlers/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_CFIHAMMING1)+= flash_hamming1_handler.o obj-$(CONFIG_LUASCRIPTHANDLER) += lua_scripthandler.o obj-$(CONFIG_RAW) += raw_handler.o obj-$(CONFIG_RDIFFHANDLER) += rdiff_handler.o +obj-$(CONFIG_READBACKHANDLER) += readback_handler.o obj-$(CONFIG_REMOTE_HANDLER) += remote_handler.o obj-$(CONFIG_SHELLSCRIPTHANDLER) += shell_scripthandler.o obj-$(CONFIG_SSBLSWITCH) += ssbl_handler.o diff --git a/handlers/readback_handler.c b/handlers/readback_handler.c new file mode 100644 index 0000000..a86164f --- /dev/null +++ b/handlers/readback_handler.c @@ -0,0 +1,125 @@ +/* + * SPDX-FileCopyrightText: 2020 Bosch Sicherheitssysteme GmbH + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "swupdate.h" +#include "handler.h" +#include "sslapi.h" +#include "util.h" + +void readback_handler(void); +static int readback_postinst(struct img_type *img); + +static int readback(struct img_type *img, void *data) +{ + if (!data) + return -1; + + script_fn scriptfn = *(script_fn *)data; + switch (scriptfn) { + case POSTINSTALL: + return readback_postinst(img); + case PREINSTALL: + default: + return 0; + } +} + +static int readback_postinst(struct img_type *img) +{ + /* Get property: partition hash */ + unsigned char hash[SHA256_HASH_LENGTH]; + char *ascii_hash = dict_get_value(&img->properties, "sha256"); + if (!ascii_hash || ascii_to_hash(hash, ascii_hash) < 0 || !IsValidHash(hash)) { + ERROR("Invalid hash"); + return -EINVAL; + } + + /* Get property: partition size */ + unsigned int size = 0; + char *value = dict_get_value(&img->properties, "size"); + if (value) { + size = strtoul(value, NULL, 10); + } else { + TRACE("Property size not found, use partition size"); + } + + /* Get property: offset */ + unsigned long offset = 0; + value = dict_get_value(&img->properties, "offset"); + if (value) { + offset = strtoul(value, NULL, 10); + } else { + TRACE("Property offset not found, use default 0"); + } + + /* Open the device (partition) */ + int fdin = open(img->device, O_RDONLY); + if (fdin < 0) { + ERROR("Failed to open %s: %s", img->device, strerror(errno)); + return -ENODEV; + } + + /* Get the real size of the partition, if size is not set. */ + if (size == 0) { + if (ioctl(fdin, BLKGETSIZE64, &size) < 0) { + ERROR("Cannot get size of %s", img->device); + close(fdin); + return -EFAULT; + } + TRACE("Partition size: %u", size); + } + + /* + * Seek the file descriptor before passing it to copyfile(). + * This is necessary because copyfile() only accepts streams, + * so the file descriptor shall be already at the right position. + */ + if (lseek(fdin, offset, SEEK_SET) < 0) { + ERROR("Seek %lu bytes failed: %s", offset, strerror(errno)); + close(fdin); + return -EFAULT; + } + + /* + * Perform hash verification. We do not need to pass an output device to + * the copyfile() function, because we only want it to verify the hash of + * the input device. + */ + unsigned long offset_out = 0; + int status = copyfile(fdin, + NULL, /* no output */ + size, + &offset_out, + 0, /* no output seek */ + 1, /* skip file, do not write to the output */ + 0, /* no compressed */ + NULL, /* no checksum */ + hash, + 0, /* no encrypted */ + NULL); /* no callback */ + if (status == 0) { + INFO("Readback verification success"); + } else { + ERROR("Readback verification failed, status=%d", status); + } + + close(fdin); + return status; +} + +__attribute__((constructor)) +void readback_handler(void) +{ + register_handler("readback", readback, SCRIPT_HANDLER | NO_DATA_HANDLER, NULL); +}