On Sun, Mar 26, 2017 at 04:44:59AM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote: > request confirmation before booting an unsigned image > > with a default timeout > > Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@xxxxxxxxxxxx> > --- > commands/go.c | 9 +++++++-- > common/Kconfig | 8 ++++++++ > common/boot_verify.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- > common/bootm.c | 6 ++++++ > common/image-fit.c | 1 + > common/uimage.c | 1 + > include/boot_verify.h | 7 +++++++ > 7 files changed, 74 insertions(+), 5 deletions(-) > > diff --git a/commands/go.c b/commands/go.c > index e0385a977..919bcddc7 100644 > --- a/commands/go.c > +++ b/commands/go.c > @@ -38,8 +38,13 @@ static int do_go(int argc, char *argv[]) > if (argc < 2) > return COMMAND_ERROR_USAGE; > > - if (boot_get_verify_mode() < BOOT_VERIFY_AVAILABLE) > - return -ESECVIOLATION; > + if (boot_get_verify_mode() < BOOT_VERIFY_AVAILABLE) { > + int is_sec; > + > + is_sec = boot_can_start_unsigned(); > + if (is_sec) > + return is_sec; > + } > > if (!isdigit(*argv[1])) { > fd = open(argv[1], O_RDONLY); > diff --git a/common/Kconfig b/common/Kconfig > index 00e98e859..2588651ae 100644 > --- a/common/Kconfig > +++ b/common/Kconfig > @@ -648,6 +648,14 @@ config BOOT_FORCE_SIGNED_IMAGES > are refused to boot. Effectively this means only Signed images can > be booted. > > +config BOOT_FORCE_USER_SIGNED_IMAGES > + bool > + prompt "Force booting of signed images or confirm them" > + depends on HAS_SECURE_BOOT > + help > + With this option enabled only signed images can be booted, unsigned images > + need a user confirmation to boot. > + > config BLSPEC > depends on BLOCK > depends on FLEXIBLE_BOOTARGS > diff --git a/common/boot_verify.c b/common/boot_verify.c > index 9cbeb7a65..07ae07e16 100644 > --- a/common/boot_verify.c > +++ b/common/boot_verify.c > @@ -1,9 +1,17 @@ > +/* > + * Copyright (c) 2016 Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>, Pengutronix > + * Copyright (c) 2017 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@xxxxxxxxxxxx> > + * > + * Under GPLv2 Only > + */ This belongs in the patch that introduces the file. Michael > #include <common.h> > #include <boot_verify.h> > +#include <console_countdown.h> > #include <globalvar.h> > #include <magicvar.h> > #include <init.h> > > +static unsigned int boot_verify_confirm_timeout = 10; > static enum boot_verify boot_verify_mode = BOOT_VERIFY_HASH; > > enum boot_verify boot_get_verify_mode(void) > @@ -14,6 +22,7 @@ enum boot_verify boot_get_verify_mode(void) > /* keep it for the most secure to the less */ > static const char * const boot_verify_names[] = { > [BOOT_VERIFY_SIGNATURE] = "signature", > + [BOOT_VERIFY_SIGNATURE_USER] = "signature-user", > [BOOT_VERIFY_AVAILABLE] = "available", > [BOOT_VERIFY_HASH] = "hash", > [BOOT_VERIFY_NONE] = "none", > @@ -40,6 +49,29 @@ void boot_set_is_secure_mode(int (*fn)(void)) > __is_secure_mode = fn; > } > > +int boot_can_start_unsigned(void) > +{ > + int ret; > + char c; > + int timeout = boot_verify_confirm_timeout; > + > + if (!is_secure_mode()) > + return 0; > + > + if (boot_verify_mode != BOOT_VERIFY_SIGNATURE_USER) > + return -ESECVIOLATION; > + > + printf("Are you sure you wish to run an unsigned binary\n"); > + printf("in a secure environment?\n"); > + printf("press y to confirm\n"); > + > + ret = console_countdown(timeout, CONSOLE_COUNTDOWN_ANYKEY, &c); > + if (ret != -EINTR) > + return -ESECVIOLATION; > + > + return c == 'y' ? 0 : -ESECVIOLATION; > +} > + > static int init_boot_verify(void) > { > int size; > @@ -47,16 +79,25 @@ static int init_boot_verify(void) > if (IS_ENABLED(CONFIG_BOOT_FORCE_SIGNED_IMAGES)) > boot_verify_mode = BOOT_VERIFY_SIGNATURE; > > - if (is_secure_mode()) > - size = 1; > - else > + if (is_secure_mode()) { > + if (IS_ENABLED(CONFIG_BOOT_FORCE_USER_SIGNED_IMAGES)) > + size = 2; > + else > + size = 1; > + } else { > size = ARRAY_SIZE(boot_verify_names); > + } > > globalvar_add_simple_enum("boot.verify", (unsigned int *)&boot_verify_mode, > boot_verify_names, size); > > + globalvar_add_simple_int("boot.verify_confirm_timeout", > + &boot_verify_confirm_timeout, "%u"); > + > return 0; > } > late_initcall(init_boot_verify); > > BAREBOX_MAGICVAR_NAMED(global_boot_verify, global.boot.verify, "boot default verify level"); > +BAREBOX_MAGICVAR_NAMED(global_boot_verify_confirm_timeout, global.boot.verify_confirm_timeout, > + "Secure Boot Comfirm timeout in seconds before booting an unsigned image"); > diff --git a/common/bootm.c b/common/bootm.c > index 1558f3c5d..73a3a99dd 100644 > --- a/common/bootm.c > +++ b/common/bootm.c > @@ -579,6 +579,12 @@ int bootm_boot(struct bootm_data *bootm_data) > printf("Passing control to %s handler\n", handler->name); > } > > + if (!handler->is_secure_supported && is_secure_mode()) { > + ret = boot_can_start_unsigned(); > + if (ret) > + goto err_out; > + } > + > ret = handler->bootm(data); > if (data->dryrun) > printf("Dryrun. Aborted\n"); > diff --git a/common/image-fit.c b/common/image-fit.c > index 53f3173fc..0df735062 100644 > --- a/common/image-fit.c > +++ b/common/image-fit.c > @@ -465,6 +465,7 @@ static int fit_config_verify_signature(struct fit_handle *handle, struct device_ > case BOOT_VERIFY_HASH: > return 0; > case BOOT_VERIFY_SIGNATURE: > + case BOOT_VERIFY_SIGNATURE_USER: > ret = -EINVAL; > break; > case BOOT_VERIFY_AVAILABLE: > diff --git a/common/uimage.c b/common/uimage.c > index d1947aa11..f25341c15 100644 > --- a/common/uimage.c > +++ b/common/uimage.c > @@ -30,6 +30,7 @@ > #include <rtc.h> > #include <filetype.h> > #include <memory.h> > +#include <bootm.h> > > static inline int uimage_is_multi_image(struct uimage_handle *handle) > { > diff --git a/include/boot_verify.h b/include/boot_verify.h > index ee830bf5c..12dcfbfdc 100644 > --- a/include/boot_verify.h > +++ b/include/boot_verify.h > @@ -3,6 +3,7 @@ > > enum boot_verify { > BOOT_VERIFY_SIGNATURE, > + BOOT_VERIFY_SIGNATURE_USER, > BOOT_VERIFY_AVAILABLE, > BOOT_VERIFY_HASH, > BOOT_VERIFY_NONE, > @@ -19,10 +20,16 @@ static int inline is_secure_mode(void) > return 0; > } > > +static int inline boot_can_start_unsigned(void) > +{ > + return 0; > +} > + > static void inline boot_set_is_secure_mode(int (*fn)(void)) {} > #else > enum boot_verify boot_get_verify_mode(void); > int is_secure_mode(void); > +int boot_can_start_unsigned(void); > void boot_set_is_secure_mode(int (*fn)(void)); > #endif > > -- > 2.11.0 > > > _______________________________________________ > barebox mailing list > barebox@xxxxxxxxxxxxxxxxxxx > http://lists.infradead.org/mailman/listinfo/barebox > -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox