
Hi Steffen,
On Mon, 26 Apr 2021 at 05:19, Steffen Jaeckel jaeckel-floss@eyet-services.de wrote:
Hook into the autoboot flow as an alternative to the existing mechanisms.
Signed-off-by: Steffen Jaeckel jaeckel-floss@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