From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 75DBBC0015E for ; Sat, 12 Aug 2023 00:29:16 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 764A386973; Sat, 12 Aug 2023 02:28:37 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="mMUmdtKG"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 236CA86942; Sat, 12 Aug 2023 02:28:35 +0200 (CEST) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by phobos.denx.de (Postfix) with ESMTP id 542B986949 for ; Sat, 12 Aug 2023 02:28:31 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=seanedmond@linux.microsoft.com Received: from ovlvm106.redmond.corp.microsoft.com (unknown [131.107.147.185]) by linux.microsoft.com (Postfix) with ESMTPSA id 60A8B20FD0EC; Fri, 11 Aug 2023 17:28:30 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 60A8B20FD0EC DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1691800110; bh=7661GUk9XZQTP2FCpfNKSFPtknOKhkKJiB4kGISpYVY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mMUmdtKGYsNnRr9gYCDQNYWkX/ObGMkeLQAwzNd0mNFL0gza763igTTUJhJOHSMQ2 IUUVVvPEa2MpDBly2jS+OXoaY7kXiJOyRE/kB5olSz+PrZT/u4dNFS4VCya99oDYE0 qZqKjucLdA10fVwAqQ7g0KPdEnZxEXgRHmpOe3lg= From: seanedmond@linux.microsoft.com To: u-boot@lists.denx.de Cc: sjg@chromium.org, stcarlso@linux.microsoft.com, ilias.apalodimas@linaro.org, abdellatif.elkhlifi@arm.com Subject: [PATCH 3/5] common: Add OS anti-rollback validation using security devices Date: Fri, 11 Aug 2023 17:28:21 -0700 Message-Id: <20230812002823.82576-4-seanedmond@linux.microsoft.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230812002823.82576-1-seanedmond@linux.microsoft.com> References: <20230812002823.82576-1-seanedmond@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean From: Stephen Carlson New config CONFIG_ARBP to enable enforcement of OS anti-rollback counter during image loading. Images with an anti-rollback counter value "arbvn" declared in the FDT will be compared against the current device anti-rollback counter value, and older images will not pass signature validation. If the image is newer, the device anti-rollback counter value will be updated. Signed-off-by: Stephen Carlson --- boot/Kconfig | 9 +++++ boot/image-fit-sig.c | 89 ++++++++++++++++++++++++++++++++++++++++++++ boot/image-fit.c | 23 ++++++++++++ include/image.h | 4 ++ 4 files changed, 125 insertions(+) diff --git a/boot/Kconfig b/boot/Kconfig index e8fb03b801..e08c274b7c 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -103,6 +103,15 @@ config FIT_CIPHER Enable the feature of data ciphering/unciphering in the tool mkimage and in the u-boot support of the FIT image. +config FIT_ARBP + bool "Enable Anti rollback version check for FIT images" + depends on FIT_SIGNATURE + default n + help + Enables FIT image anti-rollback protection. This feature is required + when a platform needs to retire previous versions of FIT images due to + security flaws and prevent devices from being reverted to them. + config FIT_VERBOSE bool "Show verbose messages when FIT images fail" depends on FIT diff --git a/boot/image-fit-sig.c b/boot/image-fit-sig.c index 12369896fe..bf3b81a3a3 100644 --- a/boot/image-fit-sig.c +++ b/boot/image-fit-sig.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include DECLARE_GLOBAL_DATA_PTR; #endif /* !USE_HOSTCC*/ #include @@ -63,6 +65,39 @@ struct image_region *fit_region_make_list(const void *fit, return region; } +#if !defined(USE_HOSTCC) +static int fit_image_verify_arbvn(const void *fit, int image_noffset) +{ + u64 image_arbvn; + u64 plat_arbvn = 0ULL; + struct udevice *dev; + int ret; + + ret = fit_image_get_arbvn(fit, image_noffset, &image_arbvn); + if (ret) + return 0; + + ret = uclass_first_device_err(UCLASS_SECURITY, &dev); + if (ret) + return -ENODEV; + + ret = dm_security_arbvn_get(dev, &plat_arbvn); + if (ret) + return -EIO; + + if (image_arbvn < plat_arbvn) { + return -EPERM; + } else if (image_arbvn > plat_arbvn) { + ret = dm_security_arbvn_set(dev, image_arbvn); + printf(" Updating OS anti-rollback to %llu from %llu\n", + image_arbvn, plat_arbvn); + return ret; + } + + return 0; +} +#endif + static int fit_image_setup_verify(struct image_sign_info *info, const void *fit, int noffset, const void *key_blob, int required_keynode, @@ -175,6 +210,16 @@ static int fit_image_verify_sig(const void *fit, int image_noffset, goto error; } +#if !defined(USE_HOSTCC) + if (FIT_IMAGE_ENABLE_ARBP && verified) { + ret = fit_image_verify_arbvn(fit, image_noffset); + if (ret) { + err_msg = "Anti-rollback verification failed"; + goto error; + } + } +#endif + return verified ? 0 : -EPERM; error: @@ -385,6 +430,40 @@ static int fit_config_check_sig(const void *fit, int noffset, int conf_noffset, return 0; } +#if !defined(USE_HOSTCC) +static int fit_config_verify_arbvn(const void *fit, int conf_noffset, + int sig_offset) +{ + static const char default_list[] = FIT_KERNEL_PROP "\0" + FIT_FDT_PROP; + int ret, len; + const char *prop, *iname, *end; + int image_noffset; + + /* If there is "sign-images" property, use that */ + prop = fdt_getprop(fit, sig_offset, "sign-images", &len); + if (!prop) { + prop = default_list; + len = sizeof(default_list); + } + + /* Locate the images */ + end = prop + len; + for (iname = prop; iname < end; iname += strlen(iname) + 1) { + image_noffset = fit_conf_get_prop_node(fit, conf_noffset, + iname, IH_PHASE_NONE); + if (image_noffset < 0) + return -ENOENT; + + ret = fit_image_verify_arbvn(fit, image_noffset); + if (ret) + return ret; + } + + return 0; +} +#endif + /** * fit_config_verify_key() - Verify that a configuration is signed with a key * @@ -444,6 +523,16 @@ static int fit_config_verify_key(const void *fit, int conf_noffset, goto error; } +#if !defined(USE_HOSTCC) + if (FIT_IMAGE_ENABLE_ARBP && verified) { + ret = fit_config_verify_arbvn(fit, conf_noffset, noffset); + if (ret) { + err_msg = "Anti-rollback verification failed"; + goto error; + } + } +#endif + if (verified) return 0; diff --git a/boot/image-fit.c b/boot/image-fit.c index 3cc556b727..d4e324752a 100644 --- a/boot/image-fit.c +++ b/boot/image-fit.c @@ -1084,6 +1084,29 @@ int fit_image_get_data_and_size(const void *fit, int noffset, return ret; } +/** + * fit_image_get_arbvn - get anti-rollback counter + * @fit: pointer to the FIT image header + * @noffset: component image node offset + * @arbvn: holds the arbvn property value + * + * returns: + * 0, on success + * -ENOENT if the property could not be found + */ +int fit_image_get_arbvn(const void *fit, int noffset, uint64_t *arbvn) +{ + const fdt64_t *val; + + val = fdt_getprop(fit, noffset, FIT_ARBVN_PROP, NULL); + if (!val) + return -ENOENT; + + *arbvn = fdt64_to_cpu(*val); + + return 0; +} + /** * fit_image_hash_get_algo - get hash algorithm name * @fit: pointer to the FIT format image header diff --git a/include/image.h b/include/image.h index 01a6787d21..497772fb4b 100644 --- a/include/image.h +++ b/include/image.h @@ -1024,6 +1024,7 @@ int booti_setup(ulong image, ulong *relocated_addr, ulong *size, #define FIT_COMP_PROP "compression" #define FIT_ENTRY_PROP "entry" #define FIT_LOAD_PROP "load" +#define FIT_ARBVN_PROP "arbvn" /* configuration node */ #define FIT_KERNEL_PROP "kernel" @@ -1105,6 +1106,7 @@ int fit_image_get_data_size_unciphered(const void *fit, int noffset, size_t *data_size); int fit_image_get_data_and_size(const void *fit, int noffset, const void **data, size_t *size); +int fit_image_get_arbvn(const void *fit, int noffset, uint64_t *arbvn); /** * fit_get_data_node() - Get verified image data for an image @@ -1389,6 +1391,7 @@ int calculate_hash(const void *data, int data_len, const char *algo, * device */ #if defined(USE_HOSTCC) +# define FIT_IMAGE_ENABLE_ARBP 0 # if defined(CONFIG_FIT_SIGNATURE) # define IMAGE_ENABLE_SIGN 1 # define FIT_IMAGE_ENABLE_VERIFY 1 @@ -1400,6 +1403,7 @@ int calculate_hash(const void *data, int data_len, const char *algo, #else # define IMAGE_ENABLE_SIGN 0 # define FIT_IMAGE_ENABLE_VERIFY CONFIG_IS_ENABLED(FIT_SIGNATURE) +# define FIT_IMAGE_ENABLE_ARBP CONFIG_IS_ENABLED(FIT_ARBP) #endif #ifdef USE_HOSTCC -- 2.40.0