From patchwork Thu Jan 16 16:12:03 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: 1224321 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::23c; helo=mail-lj1-x23c.google.com; envelope-from=swupdate+bncbc6ynavgsakrbcmxqlyqkgqeprx5zwa@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=RAuWLoaS; dkim-atps=neutral Received: from mail-lj1-x23c.google.com (mail-lj1-x23c.google.com [IPv6:2a00:1450:4864:20::23c]) (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 47z8P911J0z9sP3 for ; Fri, 17 Jan 2020 03:13:00 +1100 (AEDT) Received: by mail-lj1-x23c.google.com with SMTP id w6sf5339018ljo.20 for ; Thu, 16 Jan 2020 08:13:00 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1579191178; cv=pass; d=google.com; s=arc-20160816; b=IqvIlnbgvOVLYb8paopNuqfQtcGIwM7Bc9o8Hlu33QH/JkCAzHXuXb3fXZSQkId7sr T20RSCYPzbi665V029bDAY5ZAM6V/aKkLnwmaAZ0NUoz4D5INiGijfQ6tKCLoA/zaZwe SGd4r0XX8DBj7jMVkZ6gfPMJlt8DWEn5OJhJWgJDRSJANqv+E1zP+2/2c+keVHfZh4CW AvPho7NAJXFyv7EwjtlR2FhrYOwQdfea9GNFkm6sHrXkFdrfYLTp/zHcqnDYCZNKKTpy HFkIZp/wYfLduZ8wKk2gbzFFOHaDqlzKzi76KnvJ6K9hRTbOHJlFLRfuyE8MSGGMp/MZ VBUA== 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=p5JF0zPkJBKdH7IdUYhjJbGEnc/TXJPGW1f0LCcQmHY=; b=fczvnshS3rHlndvst0CG/uYLkauF/On0MwNW//a81B/3Kug2eWQGt02I5fETO2bNSQ sp9X0kHphjQwW6ncvrh2lr48PDVoHEsHwfqLZRdG1AgCZukR06zU5hgiWkjkOwA0H7hO eq+7sYbwA3iSC1slVSIsQ4YWAo4sNC8MDSxKFiC4MiykmlnTzNjKNjqJj+ARkuYXvP0c U8CW6OzPYdAn1JkOyhUx1of3k4sWLkrhBHz7G2kONt2XW5l1OZzCji++VwDjfMtlgKfo 8uVsTUdMF8eWATczH/zfuX05YhIwuh7axRa8GeNmdJvLXhwNUxusheB8PG3h8HzLRwH+ TW/g== ARC-Authentication-Results: i=2; gmr-mx.google.com; dkim=pass header.i=@de.bosch.com header.s=key2-intmail header.b=KI5+KB+4; 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=p5JF0zPkJBKdH7IdUYhjJbGEnc/TXJPGW1f0LCcQmHY=; b=RAuWLoaSu6Z63N83Q4I0kK5l+pQGPndnsknGX7ZwNVOXPIh/E6ZaEBq4JIu6054L85 ym8HFwZEvcShMywvPBPJGvZKe1V2vNfW8ixxFf96OKQ/Jj1/mWsRexzl9jQ3BaoLw25Y IpGYUiP2U3W2cR0GPSf0XnodO5YSuzFfz2erDmTErHqGwGJ5bzAElN4uJA+43vS54Jrk rhs/sUVAwwNzEvU10ORUY2L7DNxXhfGsAjHgzxByONBBDIY1KNgrlgf5SN4Ul5Ugb+PC dzch9mawNLuwmkIhJOhM+S+ALDvAJR81R5hSQxeBTHsrP6oy1rnLnAx3sQtsR02Sqt9X Yj+w== 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=p5JF0zPkJBKdH7IdUYhjJbGEnc/TXJPGW1f0LCcQmHY=; b=R7H36CyJClrPcNVcxUrG7pC/8pUq1yHYE7URSTAV9UaBU0t8vJclALKA5eBlwt8MPt 8osZEjQU15TwgLW0TNgsM5QETM0vowvWA6R8Q1kOQReq6eQNhDSZNi4o7Pt4TnU1wphq lGPGo+EWnOnMVEEvFvVq7WIGwSfMLAldZ1JpDpJ8KnNp95hH2TKxsyB306XCI5RPRWjX K/3bk3S3ZCDU6V5qT6N4wfoneBqSgt7Zr7CDIYUisOALld1ieeI7d6MSygsyZ/2AcKQ8 cwDi37ubQlVa9UBxqlgjj8+yx4KsE9KbXt9BOS3dB5Cc2fVmR68IQwjR0QaOOVp/EQZw tVSg== X-Gm-Message-State: APjAAAXbih/FcWkds/IQrdJODzOaspLyM0ZqVyTkaLEsgTWKMC6E6anN fQoJXfFc+Ue5tWnj4FD/Bes= X-Google-Smtp-Source: APXvYqwLqcIY53pgoaHGCNauqILq3BnmO+PESYfeW8zBTqlKeFI8w9uag4cuYdgeQjBp9MMYzodbJg== X-Received: by 2002:a2e:9cc:: with SMTP id 195mr2781310ljj.130.1579191177896; Thu, 16 Jan 2020 08:12:57 -0800 (PST) X-BeenThere: swupdate@googlegroups.com Received: by 2002:a2e:988d:: with SMTP id b13ls3185787ljj.6.gmail; Thu, 16 Jan 2020 08:12:57 -0800 (PST) X-Received: by 2002:a2e:b017:: with SMTP id y23mr2848047ljk.229.1579191177017; Thu, 16 Jan 2020 08:12:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579191177; cv=none; d=google.com; s=arc-20160816; b=KO0d/2PNgP+LM/XCv3kys7UgT/M3gNPF6oAel32IW293AHjh6ULpDA+0S3/CWgUe/l fc5i5RxDT5METVnhtBRD2vxJHC2yYZUN9r7b92vJ1DoHl4UZOSATsEpTT5sz40wG4meN Rz4mo4Kh6Ve7+nFFKysKqcKHhDRDPJFSJgxrnKYHa5n3tiIDtAxi4szoSlk48tqLbbK+ jWBX7WDzD8MsUEbt9ryjM9jYj/udCn7QknDU2+RitFKtJqpkKNbGmdEGdCh/V3AUBaOg WPbCNy5j20zvCCQc0J6EV0JexDLpxsYmXfTbaKPPejRETR+CEd/cjYlHVhq1XFpfJxX2 Pcwg== 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=rGlAbyxUqRMxCHU/rlTqiIAgOoxj4R1lOhjD7SAw4NU=; b=IJg2VrBHimRSsn9bSpin7Xyvd85cD78br5sByOZmzFqv9fmakxT6TZvOxsyI5dt0Pi 5aQdYbc9s2HQD2VC1YgGeV7/vGmVxDC2c20ElF3Xj+exnQr6pX2YG/zCKA7ouddR4M7K xPyTIKKbg4OElJi8CtzKApVvxsXi3V4QImrjMTFNT/d/3lnzdDM9eOc5EQWeAvejzxES tPh3SNw7slN7C1fB0EKyDUrlL9SRQBd7IQoMwE/qgUSQvhf8HLEUgzC7oVVFPWNzUJHF P9txLUAiQ4s/PebmuGmD+Mrtah5Oas1LjOFKaZrohYgmO4/9i9kUC4cvKvdZgL+SjVil xVLQ== ARC-Authentication-Results: i=1; gmr-mx.google.com; dkim=pass header.i=@de.bosch.com header.s=key2-intmail header.b=KI5+KB+4; 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 u5si898761lfm.0.2020.01.16.08.12.56 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 16 Jan 2020 08:12:56 -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 fe0vm1649.rbesz01.com (unknown [139.15.230.188]) by si0vms0217.rbdmz01.com (Postfix) with ESMTPS id 47z8P42tjpz4f3m1Q; Thu, 16 Jan 2020 17:12:56 +0100 (CET) Received: from fe0vm1741.rbesz01.com (unknown [10.58.172.176]) by fe0vm1649.rbesz01.com (Postfix) with ESMTPS id 47z8P42Wbgz1Mg; Thu, 16 Jan 2020 17:12:56 +0100 (CET) X-AuditID: 0a3aad15-12fff70000004734-d5-5e208b88d9ce 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 fe0vm1741.rbesz01.com (SMG Outbound) with SMTP id FB.78.18228.88B802E5; Thu, 16 Jan 2020 17:12:56 +0100 (CET) Received: from SI-HUB2000.de.bosch.com (si-hub2000.de.bosch.com [10.4.103.108]) by si0vm1950.rbesz01.com (Postfix) with ESMTPS id 47z8P40N7zzW79; Thu, 16 Jan 2020 17:12:56 +0100 (CET) Received: from ninja.grb-fir.grb.de.bosch.com (10.19.187.97) by SI-HUB2000.de.bosch.com (10.4.103.108) with Microsoft SMTP Server id 15.1.1847.3; Thu, 16 Jan 2020 17:12:55 +0100 X-Patchwork-Original-From: "'Mark Jonas' via swupdate" From: 'Darko Komljenovic' via swupdate To: , CC: , , Mark Jonas Subject: [swupdate] [PATCH 1/3] handlers: add readback handler Date: Thu, 16 Jan 2020 17:12:03 +0100 Message-ID: <20200116161205.12973-2-mark.jonas@de.bosch.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200116161205.12973-1-mark.jonas@de.bosch.com> References: <20200116161205.12973-1-mark.jonas@de.bosch.com> MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA22Sa0wTWRzFudMy3BbGTge6/K2iZIxuopFtFd/4SDRqfMTGRDFmLRYZ6MTy SKf4+mJVKi8jKJIKKaioMT6Rxy5U8NVlpSWrG7NZ2DUbsz5igGhFKpEaFacUbD/47d5z7u9/ 7j25WMLYotSYz7Fw5hyDiSXlUvni6wmzi0oT9ZoCB15Y2LVhod05HLmCWFtb7ZaubT/hIXXE dnlKBmfi93Dmn5btlBttw/WSvCuz9r0dtJNWVDCtBMkw0MnwqvMwUYLkmKHtBDw50h0V3LQh eOD4f8z5BcGhzx1EACHpmfCvu1USWMfRWujx+kd1Cb0Lfu1qjgysY+m58OKvKlHHWEpPh6HO NQGZolOg5u5nMpg8Fa7evDc6RkYvBfsZ3+gYRjzzsMqKgueV4Kl6KQ2OB7jf2yspR4rqMKs6 zDqLiCtIlclp9mRrFyRrk8zpnHBAo03alZvdiIKdqVrRQF+mCxEYudA8TLAqKq49Qc9MSM/N 2G80CMY0c76JE1g1dfB18Q4m9pss5Kdn84LA5+a4EGAJG0d5TosclWHYf4Az5wYxF5qEpWw8 lYU3/czQWQYLt5vj8jjzuLsEYxYoWUminlGauSxuXyZvsozbbAKFIiIimB/CnfBYAstcaC6O EbOdxeIISsgzZAt81hg+MYgz42oI7UIL1PEUXyQydMA15ud8S1VPptbXTNEzqjAjRPajHoQR G0uVBu4cI37AUB5Q1kBFyjExBM05LzL0s3h4/ocKRq7+CE5vGQLfrTcIaluHEFzw+cXt40EC Kg/5Cai/0y+Fut+8UnhfUxkJvY02EppthSS4e26RMFI2IoN/zp6KhoZL9dHgaW6IBueNihjo qDtJweluHwW/X/tAged95QRwFtcpwH/7sQKOO4YVMPRfOw3HLj5QQmNDFQO+J4MMlHkqYqGp sSWuX6ySEKssXzklUKXFYPlOlWNq6G1qK3J33pm/6t1HV1/barJs1tO9f6ZUK5N1JyI063Zu mdOdLDF9sc93VCi2ObTO3U2LOuqOZVzzFW0efra1Tddy+XlpqvFlzRvtwPFpVn77UpuX1x1N O+9d3hV5pCVhlbqErxhK+7twwP/hrW5jan6BXrPE3fdINqPnnOxV1CebLunL03JWKhgN2pkS s2D4Cs1Rp6oYBAAA 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=KI5+KB+4; 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 --- handlers/Config.in | 7 ++ handlers/Makefile | 1 + handlers/readback_handler.c | 161 ++++++++++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 handlers/readback_handler.c diff --git a/handlers/Config.in b/handlers/Config.in index 41eac1c..5a03740 100644 --- a/handlers/Config.in +++ b/handlers/Config.in @@ -106,6 +106,13 @@ config RDIFFHANDLER Add support for applying librsync's rdiff patches, see http://librsync.sourcefrog.net/ +config READBACKHANDLER + bool "readback" + select HASH_VERIFY + default n + help + Use sha256 hash to verify a target partition. + 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..2e4faa8 --- /dev/null +++ b/handlers/readback_handler.c @@ -0,0 +1,161 @@ +/* + * SPDX-FileCopyrightText: 2020 Bosch Sicherheitssysteme GmbH + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#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 verify_file_hash(const char* filename, size_t size, long offset, unsigned char *hash); + +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 file hash */ + char *ascii_hash = dict_get_value(&img->properties, "sha256"); + if (!ascii_hash) { + ERROR("Property sha256 not found"); + return -EINVAL; + } + + /* Get file size */ + char *value = dict_get_value(&img->properties, "size"); + if (!value) { + ERROR("Property size not found"); + return -EINVAL; + } + unsigned long long size = ustrtoull(value, 10); + + /* Get file offset */ + value = dict_get_value(&img->properties, "offset"); + if (!value) { + ERROR("Property offset not found"); + return -EINVAL; + } + unsigned long long offset = ustrtoull(value, 10); + + /* Convert the ascii hash to binary */ + unsigned char hash[SHA256_HASH_LENGTH]; + ascii_to_hash(hash, ascii_hash); + + return verify_file_hash(img->device, size, offset, hash); +} + +#define BUF_SIZE 4096 + +static int verify_file_hash(const char* filename, size_t size, long offset, unsigned char *hash) +{ + int status = 0; + FILE *fp = NULL; + unsigned char *buf = NULL; + struct swupdate_digest *dgst = NULL; + + if (IsValidHash(hash) == 0) { + ERROR("Invalid hash"); + return -EINVAL; + } + + if (!filename) { + ERROR("Invalid file name"); + return -EINVAL; + } + + fp = fopen(filename, "rb"); + if (!fp) { + ERROR("Failed to open %s: %s", filename, strerror(errno)); + status = -ENODEV; + goto cleanup; + } + + if (fseek(fp, offset, SEEK_SET)) { + ERROR("Failed to seek to position %ld: %s", offset, strerror(errno)); + status = -ENODEV; + goto cleanup; + } + + dgst = swupdate_HASH_init(SHA_DEFAULT); + if (!dgst) { + status = -EFAULT; + goto cleanup; + } + + buf = malloc(BUF_SIZE); + if (!buf) { + status = -ENOMEM; + goto cleanup; + } + + size_t totalread = 0; + while (totalread < size) { + memset(buf, 0, BUF_SIZE); + + size_t readsize = ((size - totalread) > BUF_SIZE) ? + BUF_SIZE : (size - totalread); + + if (fread(buf, 1, readsize, fp) != readsize) { + ERROR("Failed to read %s: %s", filename, strerror(errno)); + status = -EIO; + goto cleanup; + } + totalread += readsize; + + if (swupdate_HASH_update(dgst, buf, readsize) < 0) { + status = -EFAULT; + goto cleanup; + } + } + + unsigned int hash_len = 0; + unsigned char hash_value[SHA256_HASH_LENGTH]; + if (swupdate_HASH_final(dgst, hash_value, &hash_len) < 0) { + status = -EFAULT; + goto cleanup; + } + + if (hash_len != SHA256_HASH_LENGTH || swupdate_HASH_compare(hash_value, hash) < 0) { + ERROR("Hash does not match"); + status = -EFAULT; + goto cleanup; + } + + INFO("Verify file hash success: %s", filename); + +cleanup: + if (fp) + fclose(fp); + if (buf) + free(buf); + if (dgst) + swupdate_HASH_cleanup(dgst); + + return status; +} + +__attribute__((constructor)) +void readback_handler(void) +{ + register_handler("readback", readback, SCRIPT_HANDLER | NO_DATA_HANDLER, NULL); +}