Hi Steffen, On Mon, 26 Apr 2021 at 05:19, Steffen Jaeckel <jaeckel-fl...@eyet-services.de> wrote: > > Hook into the autoboot flow as an alternative to the existing > mechanisms. > > Signed-off-by: Steffen Jaeckel <jaeckel-fl...@eyet-services.de> > --- > > common/Kconfig.boot | 23 +++++++++--- > common/autoboot.c | 85 ++++++++++++++++++++++++++++++++++++++++----- > 2 files changed, 95 insertions(+), 13 deletions(-) > > diff --git a/common/Kconfig.boot b/common/Kconfig.boot > index 5a18d62d78..d8012ead3e 100644 > --- a/common/Kconfig.boot > +++ b/common/Kconfig.boot > @@ -812,10 +812,16 @@ config AUTOBOOT_ENCRYPTION > depends on AUTOBOOT_KEYED > help > This option allows a string to be entered into U-Boot to stop the > - autoboot. The string itself is hashed and compared against the hash > - in the environment variable 'bootstopkeysha256'. If it matches then > - boot stops and a command-line prompt is presented. > - > + autoboot. > + The behavior depends whether CONFIG_CRYPT_PW is enabled or not. > + In case CONFIG_CRYPT_PW is enabled, the string will be forwarded > + to the crypt-based functionality and be compared against the > + string in the environment variable 'bootstopkeycrypt'. > + In case CONFIG_CRYPT_PW is disabled the string itself is hashed > + and compared against the hash in the environment variable > + 'bootstopkeysha256'. > + If it matches in either case then boot stops and > + a command-line prompt is presented. > This provides a way to ship a secure production device which can > also > be accessed at the U-Boot command line. > > @@ -853,6 +859,15 @@ config AUTOBOOT_KEYED_CTRLC > Setting this variable provides an escape sequence from the > limited "password" strings. > > +config AUTOBOOT_STOP_STR_CRYPT > + string "Stop autobooting via crypt-hashed password" > + depends on AUTOBOOT_KEYED && AUTOBOOT_ENCRYPTION > + help > + This option adds the feature to only stop the autobooting, > + and therefore boot into the U-Boot prompt, when the input > + string / password matches a values that is hashed via > + one of support crypt options and saved in the environment. > + > config AUTOBOOT_STOP_STR_SHA256 > string "Stop autobooting via SHA256 encrypted password" > depends on AUTOBOOT_KEYED && AUTOBOOT_ENCRYPTION > diff --git a/common/autoboot.c b/common/autoboot.c > index 0bb08e7a4c..de60635d2a 100644 > --- a/common/autoboot.c > +++ b/common/autoboot.c > @@ -23,6 +23,7 @@ > #include <linux/delay.h> > #include <u-boot/sha256.h> > #include <bootcount.h> > +#include <crypt.h> > > DECLARE_GLOBAL_DATA_PTR; > > @@ -38,18 +39,80 @@ DECLARE_GLOBAL_DATA_PTR; > static int stored_bootdelay; > static int menukey; > > -#ifdef CONFIG_AUTOBOOT_ENCRYPTION > -#define AUTOBOOT_STOP_STR_SHA256 CONFIG_AUTOBOOT_STOP_STR_SHA256 > -#else > -#define AUTOBOOT_STOP_STR_SHA256 "" > +#if defined(CONFIG_AUTOBOOT_ENCRYPTION) > +#if defined(CONFIG_CRYPT_PW) && defined(CONFIG_AUTOBOOT_STOP_STR_CRYPT) > +#define AUTOBOOT_STOP_STR_ENC CONFIG_AUTOBOOT_STOP_STR_CRYPT > +#define HAS_STOP_STR_CRYPT 1
See other patch about splitting Kconfig > +#elif defined(CONFIG_AUTOBOOT_STOP_STR_SHA256) > +#define AUTOBOOT_STOP_STR_ENC CONFIG_AUTOBOOT_STOP_STR_SHA256 > +#endif > +#endif > +#if !defined(AUTOBOOT_STOP_STR_ENC) > +#define AUTOBOOT_STOP_STR_ENC "" > #endif > - > #ifdef CONFIG_USE_AUTOBOOT_MENUKEY > #define AUTOBOOT_MENUKEY CONFIG_USE_AUTOBOOT_MENUKEY > #else > #define AUTOBOOT_MENUKEY 0 > #endif > > +/** > + * passwd_abort_crypt() - check for a crypt-style hashed key sequence to > abort booting > + * > + * This checks for the user entering a password within a given time. > + * > + * The entered password is hashed via one of the crypt-style hash methods > + * and compared to the pre-defined value from either > + * the environment variable "bootstopkeycrypt" > + * or > + * the config value CONFIG_AUTOBOOT_STOP_STR_CRYPT > + * > + * @etime: Timeout value ticks (stop when get_ticks() reachs this) > + * @return 0 if autoboot should continue, 1 if it should stop > + */ > +static int passwd_abort_crypt(uint64_t etime) > +{ > + const char *crypt_env_str = env_get("bootstopkeycrypt"); > + char presskey[MAX_DELAY_STOP_STR]; > + u_int presskey_len = 0; uint > + int abort = 0; > + int err; > + > + if (IS_ENABLED(HAS_STOP_STR_CRYPT) && !crypt_env_str) > + crypt_env_str = AUTOBOOT_STOP_STR_ENC; > + > + if (!crypt_env_str) > + return 0; > + > + /* We expect the stop-string to be newline terminated. */ newline-terminated No need for the period > + do { > + if (tstc()) { > + /* Check for input string overflow */ > + if (presskey_len >= MAX_DELAY_STOP_STR) > + return 0; > + > + presskey[presskey_len] = getchar(); > + > + if ((presskey[presskey_len] == '\r') || > + (presskey[presskey_len] == '\n')) { > + presskey[presskey_len] = '\0'; > + err = crypt_compare(crypt_env_str, presskey, > + &abort); > + if (err) > + debug_bootkeys( > + "crypt_compare() failed with: > %s\n", > + errno_str(err)); > + /* you had one chance */ > + break; > + } else { > + presskey_len++; > + } > + } > + } while (get_ticks() <= etime); > + > + return abort; > +} > + > /* > * Use a "constant-length" time compare function for this > * hash compare: > @@ -89,7 +152,7 @@ static int passwd_abort_sha256(uint64_t etime) > int ret; > > if (sha_env_str == NULL) > - sha_env_str = AUTOBOOT_STOP_STR_SHA256; > + sha_env_str = AUTOBOOT_STOP_STR_ENC; I think you might need to rename that variable since it is not always a sha now. > > presskey = malloc_cache_aligned(MAX_DELAY_STOP_STR); > c = strstr(sha_env_str, ":"); > @@ -245,10 +308,14 @@ static int abortboot_key_sequence(int bootdelay) > printf(CONFIG_AUTOBOOT_PROMPT, bootdelay); > # endif > > - if (IS_ENABLED(CONFIG_AUTOBOOT_ENCRYPTION)) > - abort = passwd_abort_sha256(etime); > - else > + if (IS_ENABLED(CONFIG_AUTOBOOT_ENCRYPTION)) { > + if (IS_ENABLED(CONFIG_CRYPT_PW)) > + abort = passwd_abort_crypt(etime); > + else > + abort = passwd_abort_sha256(etime); > + } else { > abort = passwd_abort_key(etime); > + } > if (!abort) > debug_bootkeys("key timeout\n"); > > -- > 2.31.1 > Regards, Simon