From nobody Sat Nov 15 03:17:57 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass header.i=jan.kiszka@siemens.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=siemens.com ARC-Seal: i=1; a=rsa-sha256; t=1756020579; cv=none; d=zohomail.com; s=zohoarc; b=F1xBIXAGV3rJaCDL1aKm7113iVMdM14KqQN9i1EZ8aNL4iAiSDHpjYOwKhuRpSW/RjYvkrXeol8Rz9amOMnu2Fiqq7NMsD+S5i5lVPjF3jarpr0qKHKJsNlLv77JzVZbDG0Ipu+4NErtdAOo1u5mw/oox7yY9ZRJcrEH/Tooqd4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756020579; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=M2h/EoMUlU9fk3MINaoT2/hg0rjYpm0aZBDmEdaeq6E=; b=HhG6b3qgaF0Q9HobYkteGS9IZ3QWJIFsHi46xs6lhWj1xtjPJ2enAhbfwRNXcJHmYCWL+cvzMPEgoCjuwu0wngBVRtwm/x8kG2AzgZAUuCV4e74n2DFsk9DrQfMJ+UsUouEW79zVOt36wZTkUCwMoEBe6y2K7adOzF3UlscsZ2Q= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=jan.kiszka@siemens.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756020579436891.9384978287338; Sun, 24 Aug 2025 00:29:39 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uq59q-0006QG-Bt; Sun, 24 Aug 2025 03:28:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uq59o-0006Oy-Or for qemu-devel@nongnu.org; Sun, 24 Aug 2025 03:28:52 -0400 Received: from mta-65-227.siemens.flowmailer.net ([185.136.65.227]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uq59k-0005Mh-WE for qemu-devel@nongnu.org; Sun, 24 Aug 2025 03:28:52 -0400 Received: by mta-65-227.siemens.flowmailer.net with ESMTPSA id 202508240718414885864b8a27f75731 for ; Sun, 24 Aug 2025 09:18:41 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=jan.kiszka@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=M2h/EoMUlU9fk3MINaoT2/hg0rjYpm0aZBDmEdaeq6E=; b=dDE8NQQqtUaNtiY0QUNl2fun+T/hxXDbAlj5X6V5FoTv4DrAfVKvEJYLEUbE0ESzLnayQm biTH1JGqo1erMAtZQnCRpLkbAvZ9Q1ziK33bileGHm3qI/ITGO0Z+4Yjt278Lv8WEJlPymou rRVOuOBLEaHJ8vPL8DclpIBR0y02LeGlhEPVUnzy7QicZa8vVclZ890PCjMWB+SP7aFVmlvx mMUDguYBbQX+wZMS5fncyuk6kgwNMSklgwNLrbdYuauVmhUvnREaQTbQTUSUz/gYxAo5Pcm2 2fIwcTUy1xmlBJGFQ7bUIkU4kkXFyIenpieDHcKlI3+wixG86neyiYnA==; From: Jan Kiszka To: qemu-devel Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Bin Meng , qemu-block@nongnu.org, Ilias Apalodimas Subject: [PATCH 1/8] hw/sd/sdcard: Fix size check for backing block image Date: Sun, 24 Aug 2025 09:18:33 +0200 Message-ID: <0d95cffa6131a06404f3cd6ef5951720ce01c37e.1756019920.git.jan.kiszka@siemens.com> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-294854:519-21489:flowmailer Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=185.136.65.227; envelope-from=fm-294854-202508240718414885864b8a27f75731-l29l51@rts-flowmailer.siemens.com; helo=mta-65-227.siemens.flowmailer.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity jan.kiszka@siemens.com) X-ZM-MESSAGEID: 1756020581264124101 Content-Type: text/plain; charset="utf-8" From: Jan Kiszka The power-of-2 rule applies to the user data area, not the complete block image. The latter can be concatenation of boot partition images and the user data. Signed-off-by: Jan Kiszka Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- hw/sd/sd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 8c290595f0..16aee210b4 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -2789,7 +2789,7 @@ static void sd_realize(DeviceState *dev, Error **errp) return; } =20 - blk_size =3D blk_getlength(sd->blk); + blk_size =3D blk_getlength(sd->blk) - sd->boot_part_size * 2; if (blk_size > 0 && !is_power_of_2(blk_size)) { int64_t blk_size_aligned =3D pow2ceil(blk_size); char *blk_size_str; --=20 2.43.0 From nobody Sat Nov 15 03:17:57 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass header.i=jan.kiszka@siemens.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=siemens.com ARC-Seal: i=1; a=rsa-sha256; t=1756020650; cv=none; d=zohomail.com; s=zohoarc; b=RvZ/uhNizq62mKnhb1+HjzkN2e3RJZkTiV3ZBnplKwSceJYh9HWw6JJp1VDtgJ91cB7QdCo5USs6yZsm0wDEQm3J8HxDLl3NfbXJ4Q1SWJyjJx10OsyAGkwEx4MJasC1gfQvcgRSGHReQMlMjie7MNBTKXeW4G8zuyBLTDuoPD8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756020650; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=G+jTwrh/Tv10lyU83TPYT5+VrS51epr9jsr352ZMXzk=; b=n64mMM1u4JZ1lchATq2d7mEJGaWeeVg/KXvSxtLhfVsWCXcImJoWbYVVbx9GbL5OVTC494ZFhoqeQa5+TS0LfhdtIGqz42iNCLK0Hu3oiZkaX999JvhPu7Kcf66Z5eEigt9sGSBTHSP+53pYWwXBYcinvAogqpr7WVRfYi7tl7o= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=jan.kiszka@siemens.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756020650116428.7074442794776; Sun, 24 Aug 2025 00:30:50 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uq59p-0006Pb-Ca; Sun, 24 Aug 2025 03:28:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uq59n-0006Oe-A5 for qemu-devel@nongnu.org; Sun, 24 Aug 2025 03:28:51 -0400 Received: from mta-64-225.siemens.flowmailer.net ([185.136.64.225]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uq59k-0005Me-KT for qemu-devel@nongnu.org; Sun, 24 Aug 2025 03:28:51 -0400 Received: by mta-64-225.siemens.flowmailer.net with ESMTPSA id 202508240718413748b289bd8334bda8 for ; Sun, 24 Aug 2025 09:18:42 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=jan.kiszka@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=G+jTwrh/Tv10lyU83TPYT5+VrS51epr9jsr352ZMXzk=; b=hq0J2dXNanr2ZwiUa/vIEjLl+uGfbxwsY/guly6JU/8FnCOJ20tZNIGX7bcsSqbQE6+wke gQNVj+Uw6a0GXsC97wLtfwkiXCIn8/o4dVRJ74GAdNmj1Y3BegWbkdgQb1CiqLt2SAiOCXMq nZzIANE0jJemcNbVWDBYUx2g822cFEqM1u48Xlleqso/3wGBu9l2iVQijwR4htuZ77avyoiX u0WKTKFGFAzoFY3grscV2xUmVWj4Y4PXpsAh1iY3Aqq/hMKK0+IvkqNrs+nNQZxEcy1JNGxY DOFCQ8H2UH+WKmbV9G+s82Mz71wTfNBHp2/pPpWmGVfIzgEcc+RXdUAQ==; From: Jan Kiszka To: qemu-devel Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Bin Meng , qemu-block@nongnu.org, Ilias Apalodimas Subject: [PATCH 2/8] hw/sd/sdcard: Add validation for boot-partition-size Date: Sun, 24 Aug 2025 09:18:34 +0200 Message-ID: In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-294854:519-21489:flowmailer Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=185.136.64.225; envelope-from=fm-294854-202508240718413748b289bd8334bda8-BdXSN3@rts-flowmailer.siemens.com; helo=mta-64-225.siemens.flowmailer.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity jan.kiszka@siemens.com) X-ZM-MESSAGEID: 1756020651405124100 Content-Type: text/plain; charset="utf-8" From: Jan Kiszka Make sure we are not silently rounding down or even wrapping around, causing inconsistencies with the provided image. Signed-off-by: Jan Kiszka --- hw/sd/sd.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 16aee210b4..834392b0a8 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -2818,6 +2818,16 @@ static void sd_realize(DeviceState *dev, Error **err= p) } blk_set_dev_ops(sd->blk, &sd_block_ops, sd); } + if (sd->boot_part_size % (128 * KiB) || + sd->boot_part_size > 255 * 128 * KiB) { + char *size_str =3D size_to_str(sd->boot_part_size); + + error_setg(errp, "Invalid boot partition size: %s", size_str); + g_free(size_str); + error_append_hint(errp, + "The boot partition size must be multiples of 12= 8K" + "and not larger than 32640K.\n"); + } } =20 static void emmc_realize(DeviceState *dev, Error **errp) --=20 2.43.0 From nobody Sat Nov 15 03:17:57 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass header.i=jan.kiszka@siemens.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=siemens.com ARC-Seal: i=1; a=rsa-sha256; t=1756020579; cv=none; d=zohomail.com; s=zohoarc; b=lK9j1XsAzQSEmyZIIN9NR52ALY+IfMzhm5fEx3dRI+sKvg0+ypQ/hIls/ZCrZ6JOGYKynYab/8SetcZ1o2OSPZmb4DWIoOwW7toLGNUJ9Xbfuvv8bEZckja0TIVPeQyI0p8/0rBNi55ktwoKNlxJuitcOnRNmNUwvprmtWdFjsc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756020579; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=xFI1VA5/EHO61KzQO5OccwT8cCfNkw46hYpCrq2jLa0=; b=D0UlydqCeLGBlW03ETBJSs+yg3Ncb/Mph7524xwfF3cMiQagxymtoxzNBkf1RJHSxYZppUmB+XUrThw8j/7RO5HSZJt+HQhyEkkhxZc2Cn/p/gCslVqGaVqnn+GzLFzUAmn5z4EuK/iMDDQ9ugTvjMlW7cb7iJt0/K5amC5YMaI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=jan.kiszka@siemens.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756020579516216.13276131453438; Sun, 24 Aug 2025 00:29:39 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uq59w-0006TS-3G; Sun, 24 Aug 2025 03:29:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uq59r-0006RV-IE for qemu-devel@nongnu.org; Sun, 24 Aug 2025 03:28:56 -0400 Received: from mta-64-226.siemens.flowmailer.net ([185.136.64.226]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uq59k-0005Ma-Vw for qemu-devel@nongnu.org; Sun, 24 Aug 2025 03:28:55 -0400 Received: by mta-64-226.siemens.flowmailer.net with ESMTPSA id 20250824071842a0ee870884e7748f26 for ; Sun, 24 Aug 2025 09:18:42 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=jan.kiszka@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=xFI1VA5/EHO61KzQO5OccwT8cCfNkw46hYpCrq2jLa0=; b=VkFgVEFz3u/y3QKL+e5074X69mMHfJwiuUPPbLqvOHRg8OmlViy1BSF5heTTFzUZ0UJ7+i fvaUFdImDQIRvtEFMwwHf5/2jnNlQymcZo/rE6armZdwwID+wId6gwN69SjKQeHkrzX5E1tb 48Hl8MsG2Cz/V2kl+1vyLn+SNmVGTL2fXx2CohuNMceGZKI/nL5qRx215xXgFqYMMPM3fxe0 mw5TmFQkw6hxul4WQHjlZdb7jm9jX2hZr2nhbcMQ+dwkVzhgphj5vfONbXLeCvfqoFdA0zjC YSTKFJ+ry3U+lEdRnC0dC8e7OW3dJplX8oRGtYU1zDGbCVAxVcyFWpbQ==; From: Jan Kiszka To: qemu-devel Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Bin Meng , qemu-block@nongnu.org, Ilias Apalodimas Subject: [PATCH 3/8] hw/sd/sdcard: Allow user-instantiated eMMC Date: Sun, 24 Aug 2025 09:18:35 +0200 Message-ID: In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-294854:519-21489:flowmailer Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=185.136.64.226; envelope-from=fm-294854-20250824071842a0ee870884e7748f26-W4clp6@rts-flowmailer.siemens.com; helo=mta-64-226.siemens.flowmailer.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity jan.kiszka@siemens.com) X-ZM-MESSAGEID: 1756020581264124100 Content-Type: text/plain; charset="utf-8" From: Jan Kiszka Enable user-instantiation so that PCI-attached eMMCs can be created for virt machines, for QA purposes for the eMMC model itself and for complex firmware/OS integrations using the upcoming RPMB partition support. Signed-off-by: Jan Kiszka --- hw/sd/sd.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 834392b0a8..8a4f58295b 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -2912,8 +2912,6 @@ static void emmc_class_init(ObjectClass *klass, const= void *data) dc->desc =3D "eMMC"; dc->realize =3D emmc_realize; device_class_set_props(dc, emmc_properties); - /* Reason: Soldered on board */ - dc->user_creatable =3D false; =20 sc->proto =3D &sd_proto_emmc; =20 --=20 2.43.0 From nobody Sat Nov 15 03:17:57 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass header.i=jan.kiszka@siemens.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=siemens.com ARC-Seal: i=1; a=rsa-sha256; t=1756020645; cv=none; d=zohomail.com; s=zohoarc; b=fiiqRsRimjt1QQeby3ExmBO6ezH7JqE3UrdnltI3d7HPrVvqnB7BtB2moiml26K0naWGOVLFZYvrqyGuH24S8NraHhfqpSkw5/wPp6vJzokW6qTnOmyTfF1HOVuzPemBVhZYjVYBOibCjV0CNv1As0wx5Fw7R8v8STsmLAj5k3c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756020645; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=B/6oZFnmwCIpqTfzfVRrR5p/3zxY5QTA0qdDWoXlR60=; b=XK4VpWbBr0Yt24RIfipThnypD2zGQ7EOwH70jeeC9Y3Ii4dnuf8/8d4r2IR/ie+oUoD08Q36cQkkFf1uIW/F+gpNXZwEujZl21CCw19WvK8tl+i+54b3AQil6SHHPOGPnEfi746liPjXluZdSOWPi+rR5feRMreYgZ7S+vmoqe0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=jan.kiszka@siemens.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756020645123267.06470669912596; Sun, 24 Aug 2025 00:30:45 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uq59p-0006Py-V2; Sun, 24 Aug 2025 03:28:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uq59o-0006P4-Sc for qemu-devel@nongnu.org; Sun, 24 Aug 2025 03:28:52 -0400 Received: from mta-64-228.siemens.flowmailer.net ([185.136.64.228]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uq59l-0005Mj-00 for qemu-devel@nongnu.org; Sun, 24 Aug 2025 03:28:52 -0400 Received: by mta-64-228.siemens.flowmailer.net with ESMTPSA id 202508240718420868d079eb3c9494bb for ; Sun, 24 Aug 2025 09:18:42 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=jan.kiszka@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=B/6oZFnmwCIpqTfzfVRrR5p/3zxY5QTA0qdDWoXlR60=; b=OQknCdA4dCQiF/RVYFC5Swjys+RMaACiDrJdHKO5V9B8CADCMzhUOup7h0sE82XNZu8uEk 82ugVpu3vJufPt3A37kPn2i94ZX61kZCD3OvAwlknGrUI+CxPawuf4TPCT2bfD0WjZ5iImb8 img0oBajEEpxLfw2QODmBMeM4hHBJOYq/pSKS4WY8xcIiLx8QzX/vLjDaud0L9d0kLuiTt2L A3JlBSYdE95B3N7ohMcgs8wF+QOAryLAGNq58+bGIfbua2u1Bfe53UuetTh7GFX/SthHxK6p uNO8sukPhecPpxTFrGgFOCg24AuwgUpz/Kv0y41F/m101KxizjE6KpnA==; From: Jan Kiszka To: qemu-devel Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Bin Meng , qemu-block@nongnu.org, Ilias Apalodimas Subject: [PATCH 4/8] hw/sd/sdcard: Refactor sd_bootpart_offset Date: Sun, 24 Aug 2025 09:18:36 +0200 Message-ID: In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-294854:519-21489:flowmailer Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=185.136.64.228; envelope-from=fm-294854-202508240718420868d079eb3c9494bb-9ZY4a9@rts-flowmailer.siemens.com; helo=mta-64-228.siemens.flowmailer.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity jan.kiszka@siemens.com) X-ZM-MESSAGEID: 1756020646416124100 Content-Type: text/plain; charset="utf-8" From: Jan Kiszka This function provides the offset for any partition in the block image, not only the boot partitions, therefore rename it. Align the constant names with the numbering scheme in the standard and use constants for both boot partitions for consistency reasons. There is also no reason to return early if boot_part_size is zero because the existing code will provide the right value in that case as well. Signed-off-by: Jan Kiszka Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- hw/sd/sd.c | 16 ++++++++-------- hw/sd/sdmmc-internal.h | 3 ++- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 8a4f58295b..b727a37d06 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -838,14 +838,14 @@ static uint32_t sd_blk_len(SDState *sd) =20 /* * This requires a disk image that has two boot partitions inserted at the - * beginning of it. The size of the boot partitions is the "boot-size" - * property. + * beginning of it, followed by an RPMB partition. The size of the boot + * partitions is the "boot-partition-size" property. */ -static uint32_t sd_bootpart_offset(SDState *sd) +static uint32_t sd_part_offset(SDState *sd) { unsigned partition_access; =20 - if (!sd->boot_part_size || !sd_is_emmc(sd)) { + if (!sd_is_emmc(sd)) { return 0; } =20 @@ -854,9 +854,9 @@ static uint32_t sd_bootpart_offset(SDState *sd) switch (partition_access) { case EXT_CSD_PART_CONFIG_ACC_DEFAULT: return sd->boot_part_size * 2; - case EXT_CSD_PART_CONFIG_ACC_BOOT0: + case EXT_CSD_PART_CONFIG_ACC_BOOT1: return 0; - case EXT_CSD_PART_CONFIG_ACC_BOOT0 + 1: + case EXT_CSD_PART_CONFIG_ACC_BOOT2: return sd->boot_part_size * 1; default: g_assert_not_reached(); @@ -1057,7 +1057,7 @@ static const VMStateDescription sd_vmstate =3D { static void sd_blk_read(SDState *sd, uint64_t addr, uint32_t len) { trace_sdcard_read_block(addr, len); - addr +=3D sd_bootpart_offset(sd); + addr +=3D sd_part_offset(sd); if (!sd->blk || blk_pread(sd->blk, addr, len, sd->data, 0) < 0) { fprintf(stderr, "sd_blk_read: read error on host side\n"); } @@ -1066,7 +1066,7 @@ static void sd_blk_read(SDState *sd, uint64_t addr, u= int32_t len) static void sd_blk_write(SDState *sd, uint64_t addr, uint32_t len) { trace_sdcard_write_block(addr, len); - addr +=3D sd_bootpart_offset(sd); + addr +=3D sd_part_offset(sd); if (!sd->blk || blk_pwrite(sd->blk, addr, len, sd->data, 0) < 0) { fprintf(stderr, "sd_blk_write: write error on host side\n"); } diff --git a/hw/sd/sdmmc-internal.h b/hw/sd/sdmmc-internal.h index 91eb5b6b2f..ce6bc4e6ec 100644 --- a/hw/sd/sdmmc-internal.h +++ b/hw/sd/sdmmc-internal.h @@ -116,7 +116,8 @@ DECLARE_OBJ_CHECKERS(SDState, SDCardClass, SDMMC_COMMON= , TYPE_SDMMC_COMMON) =20 #define EXT_CSD_PART_CONFIG_ACC_MASK (0x7) #define EXT_CSD_PART_CONFIG_ACC_DEFAULT (0x0) -#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1) +#define EXT_CSD_PART_CONFIG_ACC_BOOT1 (0x1) +#define EXT_CSD_PART_CONFIG_ACC_BOOT2 (0x2) =20 #define EXT_CSD_PART_CONFIG_EN_MASK (0x7 << 3) #define EXT_CSD_PART_CONFIG_EN_BOOT0 (0x1 << 3) --=20 2.43.0 From nobody Sat Nov 15 03:17:57 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass header.i=jan.kiszka@siemens.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=siemens.com ARC-Seal: i=1; a=rsa-sha256; t=1756020630; cv=none; d=zohomail.com; s=zohoarc; b=k1hFy7zYm/IT0Ed7gXM4s1zP7xFc78rXZPJAB/V8/zI0ZLZjnSlmTftncsHxXhiEWMDhmavZn1J4rvqGwcq9v4XO85IQAEW9xydX/TploX4ILK4SVH4c5c5WH4J25/EufciyIVJwlWSOU9IXES45bJGQ+lvdiSbZXDdlqcVdRcw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756020630; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=+z876IVKQbxcKI2keIj2d6QC62FIgDDwiCyftDY94PU=; b=UAsZ1MzNE2pBsiyFlu5vlfIuseBFU8nXLUj4meCgZGlLkQGpfgpqRx+J/UAWPzfDE4AipdJgPer6fCmFqOwkB45x4/dTnQMrQ33SZKcfNvWIoo4QMavVufilGjQFb4eMRuu9/1eI7HvLcMYHuBVYmzR+r6Sgf4MS4nGeXh6ANjo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=jan.kiszka@siemens.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756020630852714.8273415303655; Sun, 24 Aug 2025 00:30:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uq59x-0006U4-9C; Sun, 24 Aug 2025 03:29:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uq59v-0006T6-GI for qemu-devel@nongnu.org; Sun, 24 Aug 2025 03:28:59 -0400 Received: from mta-65-227.siemens.flowmailer.net ([185.136.65.227]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uq59t-0005Md-96 for qemu-devel@nongnu.org; Sun, 24 Aug 2025 03:28:59 -0400 Received: by mta-65-227.siemens.flowmailer.net with ESMTPSA id 202508240718428cbe6e10ec3ff7237a for ; Sun, 24 Aug 2025 09:18:43 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=jan.kiszka@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=+z876IVKQbxcKI2keIj2d6QC62FIgDDwiCyftDY94PU=; b=aGILOMOIPzA73Wbt0i6fF76YZjJogsSmH6lN9rDvnGravpWWYGF34DPuzJbcgh04nnlCCT RP7LoNlkx252/NR1KiCa+xryxhP3JWL00Qzc5RmwLI8N1Q9KTEhLlQWKrfOog5V77bT70ueD xpu5/Sx9QspAZqbDMpinR8dvaJohtm8nyhimyN85t85W8qWofGiy98/Jjn3WsUZHdaPajIj9 0nKArIENvGLKApWsj/92T4xA7SS1pjUkHOncj2rkpF5iYU2TkyEPn+vzr4WmOkdg5d53agLN 833B6BHKWZ7j2T3kB8hq87qg2ric9EbFyr/W38+3gLKfJJG3c0UAH6BA==; From: Jan Kiszka To: qemu-devel Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Bin Meng , qemu-block@nongnu.org, Ilias Apalodimas Subject: [PATCH 5/8] hw/sd/sdcard: Add basic support for RPMB partition Date: Sun, 24 Aug 2025 09:18:37 +0200 Message-ID: <0412d9ab53dcff03a8ee3ea4a3f906e5f2e07255.1756019920.git.jan.kiszka@siemens.com> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-294854:519-21489:flowmailer Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=185.136.65.227; envelope-from=fm-294854-202508240718428cbe6e10ec3ff7237a-MgF7if@rts-flowmailer.siemens.com; helo=mta-65-227.siemens.flowmailer.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity jan.kiszka@siemens.com) X-ZM-MESSAGEID: 1756020631886124100 Content-Type: text/plain; charset="utf-8" From: Jan Kiszka The Replay Protected Memory Block (RPMB) is available since eMMC 4.4 which has been obsoleted by 4.41. Therefore lift the provided EXT_CSD_REV to 5 (4.41) and provide the basic logic to implement basic support for it. This allows to set the authentication key, read the write counter and authenticated perform data read and write requests. Those aren't actually authenticated yet, support for that will be added later. The RPMB image needs to be added to backing block images after potential boot partitions and before the user data. It's size is controlled by the rpmb-partition-size property. Also missing in this version (and actually not only for RPMB bits) is persistence of registers that are supposed to survive power cycles. Most prominent are the write counters or the authentication key. This feature can be added later, e.g. by append a state structure to the backing block image. Signed-off-by: Jan Kiszka --- hw/sd/sd.c | 198 +++++++++++++++++++++++++++++++++++++++-- hw/sd/sdmmc-internal.h | 21 +++++ hw/sd/trace-events | 2 + 3 files changed, 213 insertions(+), 8 deletions(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index b727a37d06..f9578c6e55 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -117,6 +117,20 @@ typedef struct SDProto { } cmd[SDMMC_CMD_MAX], acmd[SDMMC_CMD_MAX]; } SDProto; =20 +#define RPMB_KEY_MAC_LEN 32 + +typedef struct { + uint8_t stuff_bytes[196]; + uint8_t key_mac[RPMB_KEY_MAC_LEN]; + uint8_t data[256]; + uint8_t nonce[16]; + uint32_t write_counter; + uint16_t address; + uint16_t block_count; + uint16_t result; + uint16_t req_resp; +} RPMBDataFrame; + struct SDState { DeviceState parent_obj; =20 @@ -140,6 +154,7 @@ struct SDState { =20 uint8_t spec_version; uint64_t boot_part_size; + uint64_t rpmb_part_size; BlockBackend *blk; uint8_t boot_config; =20 @@ -172,6 +187,10 @@ struct SDState { uint32_t data_offset; size_t data_size; uint8_t data[512]; + RPMBDataFrame rpmb_result; + uint32_t rpmb_write_counter; + uint8_t rpmb_key[32]; + uint8_t rpmb_key_set; QEMUTimer *ocr_power_timer; uint8_t dat_lines; bool cmd_line; @@ -511,7 +530,9 @@ static void emmc_set_ext_csd(SDState *sd, uint64_t size) sd->ext_csd[205] =3D 0x46; /* Min read perf for 4bit@26Mhz */ sd->ext_csd[EXT_CSD_CARD_TYPE] =3D 0b11; sd->ext_csd[EXT_CSD_STRUCTURE] =3D 2; - sd->ext_csd[EXT_CSD_REV] =3D 3; + sd->ext_csd[EXT_CSD_REV] =3D 5; + sd->ext_csd[EXT_CSD_RPMB_MULT] =3D sd->rpmb_part_size / (128 * KiB); + sd->ext_csd[EXT_CSD_PARTITION_SUPPORT] =3D 0b111; =20 /* Mode segment (RW) */ sd->ext_csd[EXT_CSD_PART_CONFIG] =3D sd->boot_config; @@ -839,7 +860,8 @@ static uint32_t sd_blk_len(SDState *sd) /* * This requires a disk image that has two boot partitions inserted at the * beginning of it, followed by an RPMB partition. The size of the boot - * partitions is the "boot-partition-size" property. + * partitions is the "boot-partition-size" property, the one of the RPMB + * partition is 'rpmb-partition-size'. */ static uint32_t sd_part_offset(SDState *sd) { @@ -853,11 +875,13 @@ static uint32_t sd_part_offset(SDState *sd) & EXT_CSD_PART_CONFIG_ACC_MASK; switch (partition_access) { case EXT_CSD_PART_CONFIG_ACC_DEFAULT: - return sd->boot_part_size * 2; + return sd->boot_part_size * 2 + sd->rpmb_part_size; case EXT_CSD_PART_CONFIG_ACC_BOOT1: return 0; case EXT_CSD_PART_CONFIG_ACC_BOOT2: return sd->boot_part_size * 1; + case EXT_CSD_PART_CONFIG_ACC_RPMB: + return sd->boot_part_size * 2; default: g_assert_not_reached(); } @@ -896,7 +920,7 @@ static void sd_reset(DeviceState *dev) } size =3D sect << HWBLOCK_SHIFT; if (sd_is_emmc(sd)) { - size -=3D sd->boot_part_size * 2; + size -=3D sd->boot_part_size * 2 + sd->rpmb_part_size; } =20 sect =3D sd_addr_to_wpnum(size) + 1; @@ -984,6 +1008,34 @@ static const VMStateDescription sd_ocr_vmstate =3D { }, }; =20 +static bool vmstate_needed_for_rpmb(void *opaque) +{ + SDState *sd =3D opaque; + + return sd->rpmb_part_size > 0; +} + +static const VMStateDescription emmc_rpmb_vmstate =3D { + .name =3D "sd-card/ext_csd_modes-state", + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D vmstate_needed_for_rpmb, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT8_ARRAY(rpmb_result.key_mac, SDState, RPMB_KEY_MAC_LEN= ), + VMSTATE_UINT8_ARRAY(rpmb_result.data, SDState, 256), + VMSTATE_UINT8_ARRAY(rpmb_result.nonce, SDState, 16), + VMSTATE_UINT32(rpmb_result.write_counter, SDState), + VMSTATE_UINT16(rpmb_result.address, SDState), + VMSTATE_UINT16(rpmb_result.block_count, SDState), + VMSTATE_UINT16(rpmb_result.result, SDState), + VMSTATE_UINT16(rpmb_result.req_resp, SDState), + VMSTATE_UINT32(rpmb_write_counter, SDState), + VMSTATE_UINT8_ARRAY(rpmb_key, SDState, 32), + VMSTATE_UINT8(rpmb_key_set, SDState), + VMSTATE_END_OF_LIST() + }, +}; + static bool vmstate_needed_for_emmc(void *opaque) { SDState *sd =3D opaque; @@ -1050,6 +1102,7 @@ static const VMStateDescription sd_vmstate =3D { .subsections =3D (const VMStateDescription * const []) { &sd_ocr_vmstate, &emmc_extcsd_vmstate, + &emmc_rpmb_vmstate, NULL }, }; @@ -1072,6 +1125,96 @@ static void sd_blk_write(SDState *sd, uint64_t addr,= uint32_t len) } } =20 +static void emmc_rpmb_blk_read(SDState *sd, uint64_t addr, uint32_t len) +{ + uint16_t resp =3D be16_to_cpu(sd->rpmb_result.req_resp); + unsigned int curr_block =3D 0; + + if (be16_to_cpu(sd->rpmb_result.result) =3D=3D RPMB_RESULT_OK && + resp =3D=3D RPMB_RESP(RPMB_REQ_AUTH_DATA_READ)) { + curr_block =3D be16_to_cpu(sd->rpmb_result.address); + if (sd->rpmb_result.block_count =3D=3D 0) { + sd->rpmb_result.block_count =3D cpu_to_be16(sd->multi_blk_cnt); + } else { + curr_block +=3D be16_to_cpu(sd->rpmb_result.block_count) - + sd->multi_blk_cnt; + } + addr =3D curr_block * 256 + sd_part_offset(sd); + if (blk_pread(sd->blk, addr, 256, sd->rpmb_result.data, 0) < 0) { + fprintf(stderr, "sd_blk_read: read error on host side\n"); + memset(sd->rpmb_result.data, 0, sizeof(sd->rpmb_result.data)); + sd->rpmb_result.result =3D cpu_to_be16(RPMB_RESULT_READ_FAILUR= E); + } + } + memcpy(sd->data, &sd->rpmb_result, sizeof(sd->rpmb_result)); + + trace_sdcard_rpmb_read_block(resp, curr_block, + be16_to_cpu(sd->rpmb_result.result)); +} + +static void emmc_rpmb_blk_write(SDState *sd, uint64_t addr, uint32_t len) +{ + RPMBDataFrame *frame =3D (RPMBDataFrame *)sd->data; + uint16_t req =3D be16_to_cpu(frame->req_resp); + + if (req =3D=3D RPMB_REQ_READ_RESULT) { + /* just return the current result register */ + goto exit; + } + memset(&sd->rpmb_result, 0, sizeof(sd->rpmb_result)); + memcpy(sd->rpmb_result.nonce, frame->nonce, sizeof(sd->rpmb_result.non= ce)); + sd->rpmb_result.result =3D cpu_to_be16(RPMB_RESULT_OK); + sd->rpmb_result.req_resp =3D cpu_to_be16(RPMB_RESP(req)); + + if (!sd->rpmb_key_set && req !=3D RPMB_REQ_PROGRAM_AUTH_KEY) { + sd->rpmb_result.result =3D cpu_to_be16(RPMB_RESULT_NO_AUTH_KEY); + goto exit; + } + + switch (req) { + case RPMB_REQ_PROGRAM_AUTH_KEY: + if (sd->rpmb_key_set) { + sd->rpmb_result.result =3D cpu_to_be16(RPMB_RESULT_WRITE_FAILU= RE); + break; + } + memcpy(sd->rpmb_key, frame->key_mac, sizeof(sd->rpmb_key)); + sd->rpmb_key_set =3D 1; + break; + case RPMB_REQ_READ_WRITE_COUNTER: + sd->rpmb_result.write_counter =3D cpu_to_be32(sd->rpmb_write_count= er); + break; + case RPMB_REQ_AUTH_DATA_WRITE: + /* We only support single-block writes so far */ + if (sd->multi_blk_cnt !=3D 1) { + sd->rpmb_result.result =3D cpu_to_be16(RPMB_RESULT_GENERAL_FAI= LURE); + break; + } + if (be32_to_cpu(frame->write_counter) !=3D sd->rpmb_write_counter)= { + sd->rpmb_result.result =3D cpu_to_be16(RPMB_RESULT_COUNTER_FAI= LURE); + break; + } + sd->rpmb_result.address =3D frame->address; + addr =3D be16_to_cpu(frame->address) * 256 + sd_part_offset(sd); + if (blk_pwrite(sd->blk, addr, 256, frame->data, 0) < 0) { + fprintf(stderr, "sd_blk_write: write error on host side\n"); + sd->rpmb_result.result =3D cpu_to_be16(RPMB_RESULT_WRITE_FAILU= RE); + } else { + sd->rpmb_write_counter++; + } + sd->rpmb_result.write_counter =3D cpu_to_be32(sd->rpmb_write_count= er); + break; + case RPMB_REQ_AUTH_DATA_READ: + sd->rpmb_result.address =3D frame->address; + break; + default: + qemu_log_mask(LOG_UNIMP, "RPMB request %d not implemented\n", req); + sd->rpmb_result.result =3D cpu_to_be16(RPMB_RESULT_GENERAL_FAILURE= ); + break; + } +exit: + trace_sdcard_rpmb_write_block(req, be16_to_cpu(sd->rpmb_result.result)= ); +} + static void sd_erase(SDState *sd) { uint64_t erase_start =3D sd->erase_start; @@ -1185,6 +1328,19 @@ static void emmc_function_switch(SDState *sd, uint32= _t arg) break; } =20 + if (index =3D=3D EXT_CSD_PART_CONFIG) { + uint8_t part =3D b & EXT_CSD_PART_CONFIG_ACC_MASK; + + if (((part =3D=3D EXT_CSD_PART_CONFIG_ACC_BOOT1 || + part =3D=3D EXT_CSD_PART_CONFIG_ACC_BOOT2) && !sd->boot_part= _size) || + (part =3D=3D EXT_CSD_PART_CONFIG_ACC_RPMB && !sd->rpmb_part_si= ze)) { + qemu_log_mask(LOG_GUEST_ERROR, + "MMC switching to illegal partition\n"); + sd->card_status |=3D R_CSR_SWITCH_ERROR_MASK; + return; + } + } + trace_sdcard_ext_csd_update(index, sd->ext_csd[index], b); sd->ext_csd[index] =3D b; } @@ -2386,6 +2542,7 @@ static bool sd_generic_read_byte(SDState *sd, uint8_t= *value) =20 static void sd_write_byte(SDState *sd, uint8_t value) { + unsigned int partition_access; int i; =20 if (!sd->blk || !blk_is_inserted(sd->blk)) { @@ -2435,7 +2592,13 @@ static void sd_write_byte(SDState *sd, uint8_t value) if (sd->data_offset >=3D sd->blk_len) { /* TODO: Check CRC before committing */ sd->state =3D sd_programming_state; - sd_blk_write(sd, sd->data_start, sd->data_offset); + partition_access =3D sd->ext_csd[EXT_CSD_PART_CONFIG] + & EXT_CSD_PART_CONFIG_ACC_MASK; + if (partition_access =3D=3D EXT_CSD_PART_CONFIG_ACC_RPMB) { + emmc_rpmb_blk_write(sd, sd->data_start, sd->data_offset); + } else { + sd_blk_write(sd, sd->data_start, sd->data_offset); + } sd->blk_written++; sd->data_start +=3D sd->blk_len; sd->data_offset =3D 0; @@ -2518,6 +2681,7 @@ static uint8_t sd_read_byte(SDState *sd) { /* TODO: Append CRCs */ const uint8_t dummy_byte =3D 0x00; + unsigned int partition_access; uint8_t ret; uint32_t io_len; =20 @@ -2561,7 +2725,13 @@ static uint8_t sd_read_byte(SDState *sd) sd->data_start, io_len)) { return dummy_byte; } - sd_blk_read(sd, sd->data_start, io_len); + partition_access =3D sd->ext_csd[EXT_CSD_PART_CONFIG] + & EXT_CSD_PART_CONFIG_ACC_MASK; + if (partition_access =3D=3D EXT_CSD_PART_CONFIG_ACC_RPMB) { + emmc_rpmb_blk_read(sd, sd->data_start, io_len); + } else { + sd_blk_read(sd, sd->data_start, io_len); + } } ret =3D sd->data[sd->data_offset ++]; =20 @@ -2789,7 +2959,8 @@ static void sd_realize(DeviceState *dev, Error **errp) return; } =20 - blk_size =3D blk_getlength(sd->blk) - sd->boot_part_size * 2; + blk_size =3D blk_getlength(sd->blk) - sd->boot_part_size * 2 - + sd->rpmb_part_size; if (blk_size > 0 && !is_power_of_2(blk_size)) { int64_t blk_size_aligned =3D pow2ceil(blk_size); char *blk_size_str; @@ -2828,13 +2999,23 @@ static void sd_realize(DeviceState *dev, Error **er= rp) "The boot partition size must be multiples of 12= 8K" "and not larger than 32640K.\n"); } + if (sd->rpmb_part_size % (128 * KiB) || + sd->rpmb_part_size > 128 * 128 * KiB) { + char *size_str =3D size_to_str(sd->boot_part_size); + + error_setg(errp, "Invalid boot partition size: %s", size_str); + g_free(size_str); + error_append_hint(errp, + "The RPMB partition size must be multiples of 12= 8K" + "and not larger than 16384K.\n"); + } } =20 static void emmc_realize(DeviceState *dev, Error **errp) { SDState *sd =3D SDMMC_COMMON(dev); =20 - sd->spec_version =3D SD_PHY_SPECv3_01_VERS; /* Actually v4.3 */ + sd->spec_version =3D SD_PHY_SPECv3_01_VERS; /* Actually v4.5 */ =20 sd_realize(dev, errp); } @@ -2851,6 +3032,7 @@ static const Property sd_properties[] =3D { static const Property emmc_properties[] =3D { DEFINE_PROP_UINT64("boot-partition-size", SDState, boot_part_size, 0), DEFINE_PROP_UINT8("boot-config", SDState, boot_config, 0x0), + DEFINE_PROP_UINT64("rpmb-partition-size", SDState, rpmb_part_size, 0), }; =20 static void sdmmc_common_class_init(ObjectClass *klass, const void *data) diff --git a/hw/sd/sdmmc-internal.h b/hw/sd/sdmmc-internal.h index ce6bc4e6ec..c4a9aa8edf 100644 --- a/hw/sd/sdmmc-internal.h +++ b/hw/sd/sdmmc-internal.h @@ -118,9 +118,30 @@ DECLARE_OBJ_CHECKERS(SDState, SDCardClass, SDMMC_COMMO= N, TYPE_SDMMC_COMMON) #define EXT_CSD_PART_CONFIG_ACC_DEFAULT (0x0) #define EXT_CSD_PART_CONFIG_ACC_BOOT1 (0x1) #define EXT_CSD_PART_CONFIG_ACC_BOOT2 (0x2) +#define EXT_CSD_PART_CONFIG_ACC_RPMB (0x3) =20 #define EXT_CSD_PART_CONFIG_EN_MASK (0x7 << 3) #define EXT_CSD_PART_CONFIG_EN_BOOT0 (0x1 << 3) #define EXT_CSD_PART_CONFIG_EN_USER (0x7 << 3) =20 +#define RPMB_REQ_PROGRAM_AUTH_KEY (1) +#define RPMB_REQ_READ_WRITE_COUNTER (2) +#define RPMB_REQ_AUTH_DATA_WRITE (3) +#define RPMB_REQ_AUTH_DATA_READ (4) +#define RPMB_REQ_READ_RESULT (5) +#define RPMB_REQ_AUTH_CONFIG_WRITE (6) +#define RPMB_REQ_AUTH_CONFIG_READ (7) + +#define RPMB_RESP(__req__) ((__req__) << 8) + +#define RPMB_RESULT_OK (0) +#define RPMB_RESULT_GENERAL_FAILURE (1) +#define RPMB_RESULT_AUTH_FAILURE (2) +#define RPMB_RESULT_COUNTER_FAILURE (3) +#define RPMB_RESULT_ADDRESS_FAILURE (4) +#define RPMB_RESULT_WRITE_FAILURE (5) +#define RPMB_RESULT_READ_FAILURE (6) +#define RPMB_RESULT_NO_AUTH_KEY (7) +#define RPMB_RESULT_COUTER_EXPIRED (0x80) + #endif diff --git a/hw/sd/trace-events b/hw/sd/trace-events index 8d49840917..d30daa2143 100644 --- a/hw/sd/trace-events +++ b/hw/sd/trace-events @@ -59,6 +59,8 @@ sdcard_read_data(const char *proto, const char *cmd_desc,= uint8_t cmd, uint32_t sdcard_set_voltage(uint16_t millivolts) "%u mV" sdcard_ext_csd_update(unsigned index, uint8_t oval, uint8_t nval) "index %= u: 0x%02x -> 0x%02x" sdcard_switch(unsigned access, unsigned index, unsigned value, unsigned se= t) "SWITCH acc:%u idx:%u val:%u set:%u" +sdcard_rpmb_read_block(uint16_t resp, uint16_t read_addr, uint16_t result)= "resp 0x%x read_addr 0x%x result 0x%x" +sdcard_rpmb_write_block(uint16_t req, uint16_t result) "req 0x%x result 0x= %x" =20 # pl181.c pl181_command_send(uint8_t cmd, uint32_t arg) "sending CMD%02d arg 0x%08" = PRIx32 --=20 2.43.0 From nobody Sat Nov 15 03:17:57 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass header.i=jan.kiszka@siemens.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=siemens.com ARC-Seal: i=1; a=rsa-sha256; t=1756020668; cv=none; d=zohomail.com; s=zohoarc; b=MDgo9EaiSNwpLY6ZWky9526TzTcLxoOujJxnXzinZ9awusD59JzNRLWVuGHJ38b8gfZAPy//odNFfwi+gR58X+3tILhkdVnC44phf5IF+DEVGGUrTHF4hpTog4Bb5s7A7NLyxndwM84YnU7TbGfEb6JPU5pplTgEodZ0AMI2N5g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756020668; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=SIKQRmNfznvZEbxFQHjPE4pGJUEzLHeeKpiYiSJr/po=; b=C9aUjACx5yXpCKDizE8iwsAwt2IO+6jNucELBPzJgCcqp0ClRk2/UL5q3Ak0QNES+CuA/2FGtpbXVKspB2tyYN0fgpAsYG7DmaCMQo+wEeRITmOCmgORb9ZEMpH+S4clOyZTwMKkOalLtVyaN7Cr/NajodR4WDYnCn0/fBslRrk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=jan.kiszka@siemens.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756020667787389.90638638186726; Sun, 24 Aug 2025 00:31:07 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uq59u-0006Sc-0e; Sun, 24 Aug 2025 03:28:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uq59r-0006RX-QX for qemu-devel@nongnu.org; Sun, 24 Aug 2025 03:28:56 -0400 Received: from mta-64-225.siemens.flowmailer.net ([185.136.64.225]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uq59k-0005Mm-Km for qemu-devel@nongnu.org; Sun, 24 Aug 2025 03:28:55 -0400 Received: by mta-64-225.siemens.flowmailer.net with ESMTPSA id 202508240718430f8a9a1b4a50f90b60 for ; Sun, 24 Aug 2025 09:18:43 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=jan.kiszka@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=SIKQRmNfznvZEbxFQHjPE4pGJUEzLHeeKpiYiSJr/po=; b=D6r87iljbI0hUpLzqLUnJrX4lpBpobqoGrdvhfKMRSFqvg3ky1kHXlZBeaLpEf/svJWoq2 gxR+sY+6FuqWaquv5tE2TaAtVk8iOdjgOeQ639MSOrrFHbnYbXHMN9Az+0MuVmzODF9GD7hS 6YifHSkEbVo3Km6x+2XEq8szbpUL+j+bl5ZiOfpBw+Ljmn8+AsZ9ZP8W8zUAqvSsOIumth4G QxQvHKmeBmMgWJNMvL/OPTaR4wRySFL5L7DEb8fx8ihI1zB5dUXSQYNZ4G6nS5AS+VhFUUSG e7C1wUCquzIm2VRLc2tVxLRy1/N8RH5W43HDoNAUcPglzM3tILVvGNUA==; From: Jan Kiszka To: qemu-devel Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Bin Meng , qemu-block@nongnu.org, Ilias Apalodimas , =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH 6/8] crypto/hmac: Allow to build hmac over multiple qcrypto_gnutls_hmac_bytes[v] calls Date: Sun, 24 Aug 2025 09:18:38 +0200 Message-ID: In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-294854:519-21489:flowmailer Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=185.136.64.225; envelope-from=fm-294854-202508240718430f8a9a1b4a50f90b60-rw1433@rts-flowmailer.siemens.com; helo=mta-64-225.siemens.flowmailer.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity jan.kiszka@siemens.com) X-ZM-MESSAGEID: 1756020670038116600 From: Jan Kiszka If the buffers that should be considered for building the hmac are not available at the same time, the current API is unsuitable. Extend it so that passing a NULL pointer as result_len is used as indicator that further buffers will be passed in succeeding calls to qcrypto_gnutls_hmac_bytes[v]. Signed-off-by: Jan Kiszka Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- Cc: "Daniel P. Berrang=C3=A9" --- crypto/hmac-gcrypt.c | 4 +++- crypto/hmac-glib.c | 4 +++- crypto/hmac-gnutls.c | 4 +++- crypto/hmac-nettle.c | 4 +++- include/crypto/hmac.h | 12 ++++++++++++ 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/crypto/hmac-gcrypt.c b/crypto/hmac-gcrypt.c index 5273086eb9..e428d17479 100644 --- a/crypto/hmac-gcrypt.c +++ b/crypto/hmac-gcrypt.c @@ -121,7 +121,9 @@ qcrypto_gcrypt_hmac_bytesv(QCryptoHmac *hmac, return -1; } =20 - if (*resultlen =3D=3D 0) { + if (resultlen =3D=3D NULL) { + return 0; + } else if (*resultlen =3D=3D 0) { *resultlen =3D ret; *result =3D g_new0(uint8_t, *resultlen); } else if (*resultlen !=3D ret) { diff --git a/crypto/hmac-glib.c b/crypto/hmac-glib.c index ea80c8d1b2..b845133a05 100644 --- a/crypto/hmac-glib.c +++ b/crypto/hmac-glib.c @@ -104,7 +104,9 @@ qcrypto_glib_hmac_bytesv(QCryptoHmac *hmac, return -1; } =20 - if (*resultlen =3D=3D 0) { + if (resultlen =3D=3D NULL) { + return 0; + } else if (*resultlen =3D=3D 0) { *resultlen =3D ret; *result =3D g_new0(uint8_t, *resultlen); } else if (*resultlen !=3D ret) { diff --git a/crypto/hmac-gnutls.c b/crypto/hmac-gnutls.c index 822995505c..3c5bcbe80b 100644 --- a/crypto/hmac-gnutls.c +++ b/crypto/hmac-gnutls.c @@ -119,7 +119,9 @@ qcrypto_gnutls_hmac_bytesv(QCryptoHmac *hmac, return -1; } =20 - if (*resultlen =3D=3D 0) { + if (resultlen =3D=3D NULL) { + return 0; + } else if (*resultlen =3D=3D 0) { *resultlen =3D ret; *result =3D g_new0(uint8_t, *resultlen); } else if (*resultlen !=3D ret) { diff --git a/crypto/hmac-nettle.c b/crypto/hmac-nettle.c index dd5b2ab7a1..2cff7931e1 100644 --- a/crypto/hmac-nettle.c +++ b/crypto/hmac-nettle.c @@ -164,7 +164,9 @@ qcrypto_nettle_hmac_bytesv(QCryptoHmac *hmac, } } =20 - if (*resultlen =3D=3D 0) { + if (resultlen =3D=3D NULL) { + return 0; + } else if (*resultlen =3D=3D 0) { *resultlen =3D qcrypto_hmac_alg_map[hmac->alg].len; *result =3D g_new0(uint8_t, *resultlen); } else if (*resultlen !=3D qcrypto_hmac_alg_map[hmac->alg].len) { diff --git a/include/crypto/hmac.h b/include/crypto/hmac.h index da8a1e3ceb..af3d5f8feb 100644 --- a/include/crypto/hmac.h +++ b/include/crypto/hmac.h @@ -90,6 +90,12 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoHmac, qcrypto_hmac_= free) * The memory referenced in @result must be released with a call * to g_free() when no longer required by the caller. * + * If @result_len is set to a NULL pointer, no result will be returned, and + * the hmac object can be used for further invocations of qcrypto_hmac_byt= es() + * or qcrypto_hmac_bytesv() until a non-NULL pointer is provided. This all= ows + * to build the hmac across memory regions that are not available at the s= ame + * time. + * * Returns: * 0 on success, -1 on error */ @@ -123,6 +129,12 @@ int qcrypto_hmac_bytesv(QCryptoHmac *hmac, * The memory referenced in @result must be released with a call * to g_free() when no longer required by the caller. * + * If @result_len is set to a NULL pointer, no result will be returned, and + * the hmac object can be used for further invocations of qcrypto_hmac_byt= es() + * or qcrypto_hmac_bytesv() until a non-NULL pointer is provided. This all= ows + * to build the hmac across memory regions that are not available at the s= ame + * time. + * * Returns: * 0 on success, -1 on error */ --=20 2.43.0 From nobody Sat Nov 15 03:17:57 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass header.i=jan.kiszka@siemens.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=siemens.com ARC-Seal: i=1; a=rsa-sha256; t=1756020610; cv=none; d=zohomail.com; s=zohoarc; b=bcQNyYZI9mJfvdUG251qM9JMcUpNqlxMJlgYdb8Sh97KivwhC4PBUqOxTxSNgViKESKlB0ECQIiyUh7H32F8nkCjvpbS0UezFAMeP8b2rXZwnK3BKFSCN3vp8OuibFW1Uyjv4Nk3Uy3RUjr62f7NXkeTZqsUs0uM9RYrtKxKvtE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756020610; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=E/UaUmCNNfxda8g655r57Chd4oQH6RUgHLfZO5tpmo0=; b=SzkfOf46Z9IqAKc2dOtq+zk9EtyGj3DnG6wHvaMC9O/xoCU117dmmOZ2O3CSkljRd0cngNejTrMBS7heItp5mJJ12mqhN2868ykpC3fYvd+pOTy38v3gbiKX6/0l3uzMhVsrPeDmBRGybTYgsVZ4lMf7efDVjy3juEtP+CszHwE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=jan.kiszka@siemens.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756020610528859.2070716642506; Sun, 24 Aug 2025 00:30:10 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uq59r-0006RH-5D; Sun, 24 Aug 2025 03:28:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uq59p-0006Pd-72 for qemu-devel@nongnu.org; Sun, 24 Aug 2025 03:28:53 -0400 Received: from mta-65-227.siemens.flowmailer.net ([185.136.65.227]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uq59k-0005N5-KH for qemu-devel@nongnu.org; Sun, 24 Aug 2025 03:28:52 -0400 Received: by mta-65-227.siemens.flowmailer.net with ESMTPSA id 2025082407184384f1672652338a15ec for ; Sun, 24 Aug 2025 09:18:43 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=jan.kiszka@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=E/UaUmCNNfxda8g655r57Chd4oQH6RUgHLfZO5tpmo0=; b=F2S7W+cKil2wQSMhzEokdB4ol8gmEJwA5C0vsEqSHPFNrr0DwwjHTihjLfkhaQqY19NTZZ MqJGpxUU+/K2VMXeuKZFjYpx32vSNQwsM64OO0d0A+P8zeMTZ2bxTzb1wkoAPSuDmXkpgnwo rSsbHWvdDPeMeJjBIthckoDGIz8sWJlyaGIXwtvfk5VhlvDPpqc4h/WQC6ZlWpSJ4Rhlvz3o x6LFPP7kZfV5wvagRyCtSGlprqGjq8N0Fa8rIugNqmPyDGLes1U8iN2eKRUMlqFzJ13yv6NR /Qdr+jtDKjw60muAUFsKWqyDdehuxjsW1NGpFJkl9D8pFBgpGPKQI+eA==; From: Jan Kiszka To: qemu-devel Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Bin Meng , qemu-block@nongnu.org, Ilias Apalodimas Subject: [PATCH 7/8] hw/sd/sdcard: Handle RPMB MAC field Date: Sun, 24 Aug 2025 09:18:39 +0200 Message-ID: <8ea56ae040ef1037e44fc864c159e2f96f23f059.1756019920.git.jan.kiszka@siemens.com> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-294854:519-21489:flowmailer Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=185.136.65.227; envelope-from=fm-294854-2025082407184384f1672652338a15ec-pYYX9F@rts-flowmailer.siemens.com; helo=mta-65-227.siemens.flowmailer.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity jan.kiszka@siemens.com) X-ZM-MESSAGEID: 1756020611570116600 Content-Type: text/plain; charset="utf-8" From: Jan Kiszka Implement correct setting of the MAC field when passing RPMB frames back to the guest. Also check the MAC on authenticated write requests. As this depends on HMAC support for QCRYPTO_HASH_ALGO_SHA256, only register the eMMC class if that is available. Signed-off-by: Jan Kiszka Tested-by: Jerome Forissier --- hw/sd/sd.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index f9578c6e55..1acf9f5306 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -51,6 +51,7 @@ #include "qemu/module.h" #include "sdmmc-internal.h" #include "trace.h" +#include "crypto/hmac.h" =20 //#define DEBUG_SD 1 =20 @@ -118,6 +119,7 @@ typedef struct SDProto { } SDProto; =20 #define RPMB_KEY_MAC_LEN 32 +#define RPMB_HASH_LEN 284 =20 typedef struct { uint8_t stuff_bytes[196]; @@ -1125,6 +1127,66 @@ static void sd_blk_write(SDState *sd, uint64_t addr,= uint32_t len) } } =20 +static bool rpmb_calc_hmac(SDState *sd, RPMBDataFrame *frame, + unsigned int num_blocks, uint8_t *mac) +{ + size_t mac_len =3D RPMB_KEY_MAC_LEN; + bool success =3D true; + Error *err =3D NULL; + QCryptoHmac *hmac; + uint64_t addr; + + hmac =3D qcrypto_hmac_new(QCRYPTO_HASH_ALGO_SHA256, sd->rpmb_key, + RPMB_KEY_MAC_LEN, &err); + if (!hmac) { + error_report_err(err); + return false; + } + + /* + * This implies a read request because we only support single-block wr= ite + * requests so far. + */ + if (num_blocks > 1) { + /* + * Unfortunately, the underlying crypto libraries do not allow us = to + * migrate an active QCryptoHmac state. Therefore, we have to calc= ulate + * the HMAC in one run. To avoid buffering a complete read sequenc= e in + * SDState, reconstruct all frames except for the last one. + */ + char *buf =3D (char *)sd->data; + + memcpy(buf, frame->data, RPMB_HASH_LEN); + addr =3D be16_to_cpu(frame->address) * 256 + sd_part_offset(sd); + do { + if (blk_pread(sd->blk, addr, 256, buf, 0) < 0) { + fprintf(stderr, "sd_blk_read: read error on host side\n"); + success =3D false; + break; + } + if (qcrypto_hmac_bytes(hmac, buf, RPMB_HASH_LEN, NULL, NULL, + &err) < 0) { + error_report_err(err); + success =3D false; + break; + } + addr +=3D 256; + } while (--num_blocks > 1); + } + + if (success && + qcrypto_hmac_bytes(hmac, (const char*)frame->data, RPMB_HASH_LEN, = &mac, + &mac_len, &err) < 0) { + error_report_err(err); + success =3D false; + } + assert(!success || mac_len =3D=3D RPMB_KEY_MAC_LEN); + + qcrypto_hmac_free(hmac); + + return success; +} + static void emmc_rpmb_blk_read(SDState *sd, uint64_t addr, uint32_t len) { uint16_t resp =3D be16_to_cpu(sd->rpmb_result.req_resp); @@ -1145,6 +1207,17 @@ static void emmc_rpmb_blk_read(SDState *sd, uint64_t= addr, uint32_t len) memset(sd->rpmb_result.data, 0, sizeof(sd->rpmb_result.data)); sd->rpmb_result.result =3D cpu_to_be16(RPMB_RESULT_READ_FAILUR= E); } + if (sd->multi_blk_cnt =3D=3D 1 && + !rpmb_calc_hmac(sd, &sd->rpmb_result, + be16_to_cpu(sd->rpmb_result.block_count), + sd->rpmb_result.key_mac)) { + memset(sd->rpmb_result.data, 0, sizeof(sd->rpmb_result.data)); + sd->rpmb_result.result =3D cpu_to_be16(RPMB_RESULT_AUTH_FAILUR= E); + } + } else if (!rpmb_calc_hmac(sd, &sd->rpmb_result, 1, + sd->rpmb_result.key_mac)) { + memset(sd->rpmb_result.data, 0, sizeof(sd->rpmb_result.data)); + sd->rpmb_result.result =3D cpu_to_be16(RPMB_RESULT_AUTH_FAILURE); } memcpy(sd->data, &sd->rpmb_result, sizeof(sd->rpmb_result)); =20 @@ -1156,6 +1229,7 @@ static void emmc_rpmb_blk_write(SDState *sd, uint64_t= addr, uint32_t len) { RPMBDataFrame *frame =3D (RPMBDataFrame *)sd->data; uint16_t req =3D be16_to_cpu(frame->req_resp); + uint8_t mac[RPMB_KEY_MAC_LEN]; =20 if (req =3D=3D RPMB_REQ_READ_RESULT) { /* just return the current result register */ @@ -1189,6 +1263,11 @@ static void emmc_rpmb_blk_write(SDState *sd, uint64_= t addr, uint32_t len) sd->rpmb_result.result =3D cpu_to_be16(RPMB_RESULT_GENERAL_FAI= LURE); break; } + if (!rpmb_calc_hmac(sd, frame, 1, mac) || + memcmp(frame->key_mac, mac, RPMB_KEY_MAC_LEN) !=3D 0) { + sd->rpmb_result.result =3D cpu_to_be16(RPMB_RESULT_AUTH_FAILUR= E); + break; + } if (be32_to_cpu(frame->write_counter) !=3D sd->rpmb_write_counter)= { sd->rpmb_result.result =3D cpu_to_be16(RPMB_RESULT_COUNTER_FAI= LURE); break; @@ -3122,6 +3201,7 @@ static const TypeInfo sd_types[] =3D { .parent =3D TYPE_SD_CARD, .class_init =3D sd_spi_class_init, }, + /* must be last element */ { .name =3D TYPE_EMMC, .parent =3D TYPE_SDMMC_COMMON, @@ -3129,4 +3209,12 @@ static const TypeInfo sd_types[] =3D { }, }; =20 -DEFINE_TYPES(sd_types) +static void sd_register_types(void) +{ + int num =3D ARRAY_SIZE(sd_types); + if (!qcrypto_hmac_supports(QCRYPTO_HASH_ALGO_SHA256)) { + num--; + } + type_register_static_array(sd_types, num); +} +type_init(sd_register_types); --=20 2.43.0 From nobody Sat Nov 15 03:17:57 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass header.i=jan.kiszka@siemens.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=siemens.com ARC-Seal: i=1; a=rsa-sha256; t=1756020580; cv=none; d=zohomail.com; s=zohoarc; b=FWksVJFqRpmWBfxM4UYr9XOicXEWq5SHECHVEdNzuIIKzooYKLFwpLVp5sU+YDZrgzRFtq6UfWRBYBcIOFwtOb53mHbPH52XQMiOlohF3GYif/6Wj3/SHcAC/vsGd4a/wEEmtpvoe00e8vG0Q/QFDb2lU1UGu0fqfnHkaxdVkOI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756020580; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=CVIXsupJNACaWiTwdbR77+pfM2Ps0ipPrIV6ynyD/ms=; b=UCdXAwd7NIpzvK7tM7XCvJdio/1lLkTDd4XdJydOju4x5dYeNPANXbkO+InpuljAtDVrdPvymgKki7756Ks3xYBRJ10viLWaYO0KRyVH1Hxy7Utc3rtnX/IWwft7UFee3tHp06HeYnVf7IytSvm8so97JU5vHY9DTkeKFN1Eiic= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=jan.kiszka@siemens.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756020579663862.2377806303946; Sun, 24 Aug 2025 00:29:39 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uq59w-0006Tm-OI; Sun, 24 Aug 2025 03:29:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uq59r-0006RY-Va for qemu-devel@nongnu.org; Sun, 24 Aug 2025 03:28:56 -0400 Received: from mta-65-225.siemens.flowmailer.net ([185.136.65.225]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uq59l-0005NP-0H for qemu-devel@nongnu.org; Sun, 24 Aug 2025 03:28:55 -0400 Received: by mta-65-225.siemens.flowmailer.net with ESMTPSA id 202508240718433823a3068e910e7522 for ; Sun, 24 Aug 2025 09:18:43 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=jan.kiszka@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=CVIXsupJNACaWiTwdbR77+pfM2Ps0ipPrIV6ynyD/ms=; b=fV9+eyfmSyeEesnP50t3DKF+EhejhLwCbfi638b0VHpaPBt8PfT2o9nXWMa/y5YT15UkSM uM094eM8Z2RSa8syS7sRbjK4i/1pOsGZNVap7j5kIT4HYQ7CJYW+BoPg0k+tPWY99s7DXXIy 830GSrkHl4Sg9rfPX14Qc1FvWtCqWi0cHDBwg49dPgYV26HLKcwM3RRu4Wthjj1nnA0Ll/TK 5DNlzbbWM7iVWVonvxZL+L25QSlr+5vD9A1EoL3Z3Ioo3BTCs+HiFttYTUTXKqZZovppUE6l S4E4WMrTGoNlDDcgdEzjDneWkWefBDogWxAt2f+Nm2Hqr7FO59vc9zeQ==; From: Jan Kiszka To: qemu-devel Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Bin Meng , qemu-block@nongnu.org, Ilias Apalodimas Subject: [PATCH 8/8] scripts: Add helper script to generate eMMC block device images Date: Sun, 24 Aug 2025 09:18:40 +0200 Message-ID: In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-294854:519-21489:flowmailer Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=185.136.65.225; envelope-from=fm-294854-202508240718433823a3068e910e7522-3KawAb@rts-flowmailer.siemens.com; helo=mta-65-225.siemens.flowmailer.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity jan.kiszka@siemens.com) X-ZM-MESSAGEID: 1756020582743116600 Content-Type: text/plain; charset="utf-8" From: Jan Kiszka As an eMMC block device image may consist of more than just the user data partition, provide a helper script that can compose the image from boot partitions, an RPMB partition and the user data image. The script also does the required size validation and/or rounding. Signed-off-by: Jan Kiszka --- scripts/mkemmc.sh | 185 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100755 scripts/mkemmc.sh diff --git a/scripts/mkemmc.sh b/scripts/mkemmc.sh new file mode 100755 index 0000000000..5d40c2889b --- /dev/null +++ b/scripts/mkemmc.sh @@ -0,0 +1,185 @@ +#!/bin/sh -e +# +# Create eMMC block device image from boot, RPMB and user data images +# +# Copyright (c) Siemens, 2025 +# +# Authors: +# Jan Kiszka +# +# This work is licensed under the terms of the GNU GPL version 2. +# See the COPYING file in the top-level directory. +# + +usage() { + echo "$0 [OPTIONS] USER_IMG[:SIZE] OUTPUT_IMG" + echo "" + echo "SIZE must be a power of 2. If no SIZE is specified, the size of = USER_ING will" + echo "be used (rounded up)." + echo "" + echo "Supported options:" + echo " -b BOOT1_IMG[:SIZE] Add boot partitions. SIZE must be multip= les of 128K. If" + echo " no SIZE is specified, the size of BOOT= _IMG will be" + echo " used (rounded up). BOOT1_IMG will be s= tored in boot" + echo " partition 1, and a boot partition 2 of= the same size" + echo " will be created as empty (all zeros) u= nless -B is" + echo " specified as well." + echo " -B BOOT2_IMG Fill boot partition 2 with BOOT2_IMG. Mu= st be combined" + echo " with -b which is also defining the par= tition size." + echo " -r RPMB_IMG[:SIZE] Add RPMB partition. SIZE must be multipl= es of 128K. If" + echo " no SIZE is specified, the size of RPMB= _IMG will be" + echo " used (rounded up)." + echo " -h, --help This help" + echo "" + echo "All SIZE parameters support the units K, M, G. If SIZE is smalle= r than the" + echo "associated image, it will be truncated in the output image." + exit "$1" +} + +process_size() { + if [ "${4#*:}" =3D "$4" ]; then + if ! size=3D$(stat -L -c %s "$2" 2>/dev/null); then + echo "Missing $1 image '$2'." >&2 + exit 1 + fi + if [ "$3" =3D 128 ]; then + size=3D$(( (size + 128 * 1024 - 1) & ~(128 * 1024 - 1) )) + elif [ $(( size & (size - 1) )) -gt 0 ]; then + n=3D0 + while [ "$size" -gt 0 ]; do + size=3D$((size >> 1)) + n=3D$((n + 1)) + done + size=3D$((1 << n)) + fi + else + value=3D"${4#*:}" + if [ "${value%K}" !=3D "$value" ]; then + size=3D${value%K} + multiplier=3D1024 + elif [ "${value%M}" !=3D "$value" ]; then + size=3D${value%M} + multiplier=3D$((1024 * 1024)) + elif [ "${value%G}" !=3D "$value" ]; then + size=3D${value%G} + multiplier=3D$((1024 * 1024 * 1024)) + else + size=3D$value + multiplier=3D1 + fi + if [ "$size" -eq "$size" ] 2>/dev/null; then + size=3D$((size * multiplier)) + else + echo "Invalid value '$value' specified for $2 image size." >&2 + exit 1 + fi + if [ "$3" =3D 128 ]; then + if [ $(( size & (128 * 1024 - 1) )) -ne 0 ]; then + echo "The $2 image size must be multiples of 128K." >&2 + exit 1 + fi + elif [ $(( size & (size - 1) )) -gt 0 ]; then + echo "The %2 image size must be power of 2." >&2 + exit 1 + fi + fi + echo $size +} + +userimg=3D +outimg=3D +bootimg1=3D +bootimg2=3D/dev/zero +bootsz=3D0 +rpmbimg=3D +rpmbsz=3D0 + +while [ $# -gt 0 ]; do + case "$1" in + -b) + shift + [ $# -ge 1 ] || usage 1 + bootimg1=3D${1%%:*} + bootsz=3D$(process_size boot "$bootimg1" 128 "$1") + shift + ;; + -B) + shift + [ $# -ge 1 ] || usage 1 + bootimg2=3D$1 + shift + ;; + -r) + shift + [ $# -ge 1 ] || usage 1 + rpmbimg=3D${1%%:*} + rpmbsz=3D$(process_size RPMB "$rpmbimg" 128 "$1") + shift + ;; + -h|--help) + usage 0 + ;; + *) + if [ -z "$userimg" ]; then + userimg=3D${1%%:*} + usersz=3D$(process_size user "$userimg" 2 "$1") + elif [ -z "$outimg" ]; then + outimg=3D$1 + else + usage 1 + fi + shift + ;; + esac +done + +[ -n "$outimg" ] || usage 1 + +if [ "$bootsz" -gt $((32640 * 1024)) ]; then + echo "Boot image size is larger than 32640K." >&2 + exit 1 +fi +if [ "$rpmbsz" -gt $((16384 * 1024)) ]; then + echo "RPMB image size is larger than 16384K." >&2 + exit 1 +fi + +echo "Creating eMMC image" + +truncate "$outimg" -s 0 +pos=3D0 + +if [ "$bootsz" -gt 0 ]; then + echo " Boot partition 1 and 2: $((bootsz / 1024))K each" + blocks=3D$(( bootsz / (128 * 1024) )) + dd if=3D"$bootimg1" of=3D"$outimg" conv=3Dsparse bs=3D128K count=3D$bl= ocks \ + status=3Dnone + dd if=3D"$bootimg2" of=3D"$outimg" conv=3Dsparse bs=3D128K count=3D$bl= ocks \ + seek=3D$blocks status=3Dnone + pos=3D$((2 * bootsz)) +fi + +if [ "$rpmbsz" -gt 0 ]; then + echo " RPMB partition: $((rpmbsz / 1024))K" + blocks=3D$(( rpmbsz / (128 * 1024) )) + dd if=3D"$rpmbimg" of=3D"$outimg" conv=3Dsparse bs=3D128K count=3D$blo= cks \ + seek=3D$(( pos / (128 * 1024) )) status=3Dnone + pos=3D$((pos + rpmbsz)) +fi + +if [ "$usersz" -lt 1024 ]; then + echo " User data: $usersz bytes" +elif [ "$usersz" -lt $((1024 * 1024)) ]; then + echo " User data: $(( (usersz + 1023) / 1024 ))K ($use= rsz)" +elif [ "$usersz" -lt $((1024 * 1024 * 1024)) ]; then + echo " User data: $(( (usersz + 1048575) / 1048576))M = ($usersz)" +else + echo " User data: $(( (usersz + 1073741823) / 10737418= 24))G ($usersz)" +fi +dd if=3D"$userimg" of=3D"$outimg" conv=3Dsparse bs=3D128K seek=3D$(( pos /= (128 * 1024) )) \ + count=3D$(( (usersz + 128 * 1024 - 1) / (128 * 1024) )) status=3Dnone +pos=3D$((pos + usersz)) +truncate "$outimg" -s $pos + +echo "" +echo "Instantiate via '-device emmc,boot-partition-size=3D$bootsz,rpmb-par= tition-size=3D$rpmbsz,drive=3D$outimg'" --=20 2.43.0