Currently FIT image must be signed by all required conf keys. This means Verified Boot fails if there is a signature verification failure using any required key in U-boot DTB.
This patch introduces a new policy in DTB that can be set to any required conf key. This means if verified boot passes with one of the required keys, u-boot will continue the OS hand off. There were prior attempts to address this: https://lists.denx.de/pipermail/u-boot/2019-April/366047.html The above patch was failing "make tests". https://lists.denx.de/pipermail/u-boot/2020-January/396629.html Signed-off-by: Thirupathaiah Annapureddy <thir...@linux.microsoft.com> --- Changes in v2: - Modify fit_config_verify_required_sigs() to process required-mode policy variable in U-boot DTB. common/image-fit-sig.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/common/image-fit-sig.c b/common/image-fit-sig.c index cc1967109e..d9b1c93a9b 100644 --- a/common/image-fit-sig.c +++ b/common/image-fit-sig.c @@ -416,6 +416,10 @@ int fit_config_verify_required_sigs(const void *fit, int conf_noffset, { int noffset; int sig_node; + int verified = 0; + int reqd_sigs = 0; + bool reqd_policy_all = true; + const char *reqd_mode; /* Work out what we need to verify */ sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME); @@ -425,6 +429,14 @@ int fit_config_verify_required_sigs(const void *fit, int conf_noffset, return 0; } + /* Get required-mode policy property from DTB */ + reqd_mode = fdt_getprop(sig_blob, sig_node, "required-mode", NULL); + if (reqd_mode && !strcmp(reqd_mode, "any")) + reqd_policy_all = false; + + debug("%s: required-mode policy set to '%s'\n", __func__, + reqd_policy_all ? "all" : "any"); + fdt_for_each_subnode(noffset, sig_blob, sig_node) { const char *required; int ret; @@ -433,15 +445,27 @@ int fit_config_verify_required_sigs(const void *fit, int conf_noffset, NULL); if (!required || strcmp(required, "conf")) continue; + + reqd_sigs++; + ret = fit_config_verify_sig(fit, conf_noffset, sig_blob, noffset); if (ret) { - printf("Failed to verify required signature '%s'\n", - fit_get_name(sig_blob, noffset, NULL)); - return ret; + if (reqd_policy_all) { + printf("Failed to verify required signature '%s'\n", + fit_get_name(sig_blob, noffset, NULL)); + return ret; + } + } else { + verified++; + if (!reqd_policy_all) + break; } } + if (reqd_sigs && !verified) + return -EPERM; + return 0; } -- 2.25.2