aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorSteffen Jaeckel2021-07-08 15:57:35 +0200
committerTom Rini2021-07-23 13:36:20 -0400
commit1a4a778666842f22752c3af93f5cd8b94948cb9e (patch)
treec1d882cb476ed09b7a25c52a3426af1c6d796633 /common
parent29bbe71ccfef3440b4881259c6f8e39b6e7924c6 (diff)
common: integrate crypt-based passwords
Hook into the autoboot flow as an alternative to the existing mechanisms. Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de> Reviewed-by: Simon Glass <sjg@chromium.org> Reviewed-by: Heiko Schocher <hs@denx.de>
Diffstat (limited to 'common')
-rw-r--r--common/Kconfig.boot38
-rw-r--r--common/autoboot.c81
2 files changed, 105 insertions, 14 deletions
diff --git a/common/Kconfig.boot b/common/Kconfig.boot
index b4dc49e0195..fe60ad0171c 100644
--- a/common/Kconfig.boot
+++ b/common/Kconfig.boot
@@ -812,10 +812,17 @@ 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 from lib 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,9 +860,30 @@ config AUTOBOOT_KEYED_CTRLC
Setting this variable provides an escape sequence from the
limited "password" strings.
+config AUTOBOOT_STOP_STR_ENABLE
+ bool "Enable fixed string to stop autobooting"
+ depends on AUTOBOOT_KEYED && AUTOBOOT_ENCRYPTION
+ help
+ This option enables the feature to add a fixed stop
+ string that is defined at compile time.
+ In every case it will be tried to load the stop
+ string from the environment.
+ In case this is enabled and there is no stop string
+ in the environment, this will be used as default value.
+
+config AUTOBOOT_STOP_STR_CRYPT
+ string "Stop autobooting via crypt-hashed password"
+ depends on AUTOBOOT_STOP_STR_ENABLE && CRYPT_PW
+ 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 the supported crypt-style password hashing options
+ and saved in the environment variable "bootstopkeycrypt".
+
config AUTOBOOT_STOP_STR_SHA256
string "Stop autobooting via SHA256 encrypted password"
- depends on AUTOBOOT_KEYED && AUTOBOOT_ENCRYPTION
+ depends on AUTOBOOT_STOP_STR_ENABLE
help
This option adds the feature to only stop the autobooting,
and therefore boot into the U-Boot prompt, when the input
diff --git a/common/autoboot.c b/common/autoboot.c
index b42148c7291..107fb1533dd 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,10 +39,11 @@ 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_STOP_STR_CRYPT)
+#define CONFIG_AUTOBOOT_STOP_STR_CRYPT ""
+#endif
+#if !defined(CONFIG_AUTOBOOT_STOP_STR_SHA256)
+#define CONFIG_AUTOBOOT_STOP_STR_SHA256 ""
#endif
#ifdef CONFIG_AUTOBOOT_USE_MENUKEY
@@ -50,6 +52,63 @@ static int menukey;
#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;
+ int abort = 0;
+ int err;
+
+ if (IS_ENABLED(CONFIG_AUTOBOOT_STOP_STR_ENABLE) && !crypt_env_str)
+ crypt_env_str = CONFIG_AUTOBOOT_STOP_STR_CRYPT;
+
+ if (!crypt_env_str)
+ return 0;
+
+ /* We expect the stop-string to be newline-terminated */
+ do {
+ if (tstc()) {
+ /* Check for input string overflow */
+ if (presskey_len >= sizeof(presskey))
+ 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 +148,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 = CONFIG_AUTOBOOT_STOP_STR_SHA256;
presskey = malloc_cache_aligned(MAX_DELAY_STOP_STR);
c = strstr(sha_env_str, ":");
@@ -245,10 +304,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");
@@ -394,4 +457,4 @@ void autoboot_command(const char *s)
if (s)
run_command_list(s, -1, 0);
}
-}
+} \ No newline at end of file