From: seanedmond@linux.microsoft.com
To: u-boot@lists.denx.de
Cc: sjg@chromium.org, stcarlso@linux.microsoft.com,
ilias.apalodimas@linaro.org
Subject: [PATCH 3/8] common: Add OS anti-rollback validation using rollback devices
Date: Tue, 12 Sep 2023 02:47:26 -0700 [thread overview]
Message-ID: <20230912094731.51413-4-seanedmond@linux.microsoft.com> (raw)
In-Reply-To: <20230912094731.51413-1-seanedmond@linux.microsoft.com>
From: Stephen Carlson <stcarlso@linux.microsoft.com>
New config CONFIG_ROLLBACK_CHECK to enable enforcement of OS anti-rollback
counter during image loading.
Images with an anti-rollback counter value "rollback" 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 <stcarlso@linux.microsoft.com>
Signed-off-by: Sean Edmond <seanedmond@microsoft.com>
---
boot/Kconfig | 9 +++++
boot/image-fit-sig.c | 92 ++++++++++++++++++++++++++++++++++++++++++++
boot/image-fit.c | 31 +++++++++++++++
include/image.h | 6 ++-
4 files changed, 137 insertions(+), 1 deletion(-)
diff --git a/boot/Kconfig b/boot/Kconfig
index e8fb03b801..9180a1c8dc 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_ROLLBACK_CHECK
+ 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..91eaf4baa8 100644
--- a/boot/image-fit-sig.c
+++ b/boot/image-fit-sig.c
@@ -11,6 +11,8 @@
#include <log.h>
#include <malloc.h>
#include <asm/global_data.h>
+#include <dm.h>
+#include <rollback.h>
DECLARE_GLOBAL_DATA_PTR;
#endif /* !USE_HOSTCC*/
#include <fdt_region.h>
@@ -63,6 +65,44 @@ struct image_region *fit_region_make_list(const void *fit,
return region;
}
+static int fit_image_verify_rollback(const void *fit, int image_noffset)
+{
+#if !defined(USE_HOSTCC)
+ u64 image_rollback;
+ u64 plat_rollback = 0ULL;
+ struct udevice *dev;
+ int ret;
+
+ ret = fit_image_get_rollback(fit, image_noffset, &image_rollback);
+
+ /* If the FIT doesn't contain the rollback property, assume an
+ * anti-rollback version number of 0. This ensures failure
+ * if the platform anti-rollback version number is non-zero
+ */
+ if (ret)
+ image_rollback = 0;
+
+ ret = uclass_first_device_err(UCLASS_ROLLBACK, &dev);
+ if (ret)
+ return ret;
+
+ ret = rollback_idx_get(dev, &plat_rollback);
+ if (ret)
+ return -EIO;
+
+ if (image_rollback < plat_rollback) {
+ return -EPERM;
+ } else if (image_rollback > plat_rollback) {
+ ret = rollback_idx_set(dev, image_rollback);
+ printf(" Updating OS anti-rollback to %llu from %llu\n",
+ image_rollback, plat_rollback);
+ return ret;
+ }
+#endif
+
+ return 0;
+}
+
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 +215,16 @@ static int fit_image_verify_sig(const void *fit, int image_noffset,
goto error;
}
+ if (!tools_build()) {
+ if (FIT_IMAGE_ENABLE_ROLLBACK_CHECK && verified) {
+ ret = fit_image_verify_rollback(fit, image_noffset);
+ if (ret) {
+ err_msg = "Anti-rollback verification failed";
+ goto error;
+ }
+ }
+ }
+
return verified ? 0 : -EPERM;
error:
@@ -385,6 +435,38 @@ static int fit_config_check_sig(const void *fit, int noffset, int conf_noffset,
return 0;
}
+static int fit_config_verify_rollback(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_rollback(fit, image_noffset);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
/**
* fit_config_verify_key() - Verify that a configuration is signed with a key
*
@@ -444,6 +526,16 @@ static int fit_config_verify_key(const void *fit, int conf_noffset,
goto error;
}
+ if (!tools_build()) {
+ if (FIT_IMAGE_ENABLE_ROLLBACK_CHECK && verified) {
+ ret = fit_config_verify_rollback(fit, conf_noffset, noffset);
+ if (ret) {
+ err_msg = "Anti-rollback verification failed";
+ goto error;
+ }
+ }
+ }
+
if (verified)
return 0;
diff --git a/boot/image-fit.c b/boot/image-fit.c
index 3cc556b727..510cb51cd5 100644
--- a/boot/image-fit.c
+++ b/boot/image-fit.c
@@ -1084,6 +1084,37 @@ int fit_image_get_data_and_size(const void *fit, int noffset,
return ret;
}
+/**
+ * fit_image_get_rollback - get anti-rollback counter
+ * @fit: pointer to the FIT image header
+ * @noffset: component image node offset
+ * @rollback: holds the rollback property value
+ *
+ * returns:
+ * 0, on success
+ * -ENOENT if the property could not be found
+ */
+int fit_image_get_rollback(const void *fit, int noffset, uint64_t *rollback)
+{
+ const fdt64_t *val;
+ int len;
+
+ val = fdt_getprop(fit, noffset, FIT_ROLLBACK_PROP, &len);
+
+ if (!val) {
+ printf("error! Can't find property %s in FIT\n", FIT_ROLLBACK_PROP);
+ return -ENOENT;
+ }
+ if (len != sizeof(uint64_t)) {
+ printf("Property %s must be 64-bits\n", FIT_ROLLBACK_PROP);
+ return -ENOENT;
+ }
+
+ *rollback = 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..3283cd7717 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_ROLLBACK_PROP "rollback"
/* 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_rollback(const void *fit, int noffset, uint64_t *rollback_idx);
/**
* 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_ROLLBACK_CHECK 0
# if defined(CONFIG_FIT_SIGNATURE)
# define IMAGE_ENABLE_SIGN 1
# define FIT_IMAGE_ENABLE_VERIFY 1
@@ -1399,7 +1402,8 @@ int calculate_hash(const void *data, int data_len, const char *algo,
# endif
#else
# define IMAGE_ENABLE_SIGN 0
-# define FIT_IMAGE_ENABLE_VERIFY CONFIG_IS_ENABLED(FIT_SIGNATURE)
+# define FIT_IMAGE_ENABLE_VERIFY CONFIG_IS_ENABLED(FIT_SIGNATURE)
+# define FIT_IMAGE_ENABLE_ROLLBACK_CHECK CONFIG_IS_ENABLED(FIT_ROLLBACK_CHECK)
#endif
#ifdef USE_HOSTCC
--
2.40.0
next prev parent reply other threads:[~2023-09-12 9:47 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-12 9:47 [PATCH 0/5] Add anti-rollback validation feature seanedmond
2023-09-12 9:47 ` [PATCH 1/8] drivers: rollback: Add rollback devices to driver model seanedmond
2023-12-01 14:16 ` Ilias Apalodimas
2023-12-01 18:32 ` Simon Glass
2023-09-12 9:47 ` [PATCH 2/8] drivers: rollback: Add TPM2 implementation of rollback devices seanedmond
2023-12-01 14:52 ` Ilias Apalodimas
2023-12-01 18:32 ` Simon Glass
2023-09-12 9:47 ` seanedmond [this message]
2023-09-12 9:47 ` [PATCH 4/8] common: Add OS anti-rollback grace version seanedmond
2023-09-12 9:47 ` [PATCH 5/8] dm: test: Add a test for rollback driver seanedmond
2023-09-12 9:47 ` [PATCH 6/8] tpm: Fix issues relating to NV Indexes seanedmond
2023-09-12 9:47 ` [PATCH 7/8] sandbox: tpm: Fix TPM2_CC_NV_DEFINE_SPACE command seanedmond
2023-09-12 9:47 ` [PATCH 8/8] doc: rollback: anti-rollback verification seanedmond
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230912094731.51413-4-seanedmond@linux.microsoft.com \
--to=seanedmond@linux.microsoft.com \
--cc=ilias.apalodimas@linaro.org \
--cc=sjg@chromium.org \
--cc=stcarlso@linux.microsoft.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.