1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-09-01 00:32:04 +02:00

autoboot.c: Add feature to stop autobooting via SHA256 encrypted password

This patch adds the feature to only stop the autobooting, and therefor
boot into the U-Boot prompt, when the input string / password matches
a values that is encypted via a SHA256 hash and saved in the environment.

This feature is enabled by defined these config options:
     CONFIG_AUTOBOOT_KEYED
     CONFIG_AUTOBOOT_STOP_STR_SHA256

Signed-off-by: Stefan Roese <sr@denx.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Stefan Roese
2015-05-18 14:08:24 +02:00
committed by Tom Rini
parent d126e01649
commit 8f0b1e24e2
4 changed files with 152 additions and 31 deletions

View File

@@ -12,6 +12,7 @@
#include <fdtdec.h>
#include <menu.h>
#include <post.h>
#include <u-boot/sha256.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -26,15 +27,81 @@ DECLARE_GLOBAL_DATA_PTR;
/* Stored value of bootdelay, used by autoboot_command() */
static int stored_bootdelay;
/***************************************************************************
* Watch for 'delay' seconds for autoboot stop or autoboot delay string.
* returns: 0 - no key string, allow autoboot 1 - got key string, abort
#if defined(CONFIG_AUTOBOOT_KEYED)
#if defined(CONFIG_AUTOBOOT_STOP_STR_SHA256)
/*
* Use a "constant-length" time compare function for this
* hash compare:
*
* https://crackstation.net/hashing-security.htm
*/
# if defined(CONFIG_AUTOBOOT_KEYED)
static int abortboot_keyed(int bootdelay)
static int slow_equals(u8 *a, u8 *b, int len)
{
int diff = 0;
int i;
for (i = 0; i < len; i++)
diff |= a[i] ^ b[i];
return diff == 0;
}
static int passwd_abort(uint64_t etime)
{
const char *sha_env_str = getenv("bootstopkeysha256");
u8 sha_env[SHA256_SUM_LEN];
u8 sha[SHA256_SUM_LEN];
char presskey[MAX_DELAY_STOP_STR];
const char *algo_name = "sha256";
u_int presskey_len = 0;
int abort = 0;
int size;
int ret;
if (sha_env_str == NULL)
sha_env_str = CONFIG_AUTOBOOT_STOP_STR_SHA256;
/*
* Generate the binary value from the environment hash value
* so that we can compare this value with the computed hash
* from the user input
*/
ret = hash_parse_string(algo_name, sha_env_str, sha_env);
if (ret) {
printf("Hash %s not supported!\n", algo_name);
return 0;
}
/*
* We don't know how long the stop-string is, so we need to
* generate the sha256 hash upon each input character and
* compare the value with the one saved in the environment
*/
do {
if (tstc()) {
/* Check for input string overflow */
if (presskey_len >= MAX_DELAY_STOP_STR)
return 0;
presskey[presskey_len++] = getc();
/* Calculate sha256 upon each new char */
hash_block(algo_name, (const void *)presskey,
presskey_len, sha, &size);
/* And check if sha matches saved value in env */
if (slow_equals(sha, sha_env, SHA256_SUM_LEN))
abort = 1;
}
} while (!abort && get_ticks() <= etime);
return abort;
}
#else
static int passwd_abort(uint64_t etime)
{
int abort = 0;
uint64_t etime = endtick(bootdelay);
struct {
char *str;
u_int len;
@@ -50,19 +117,6 @@ static int abortboot_keyed(int bootdelay)
u_int presskey_max = 0;
u_int i;
#ifndef CONFIG_ZERO_BOOTDELAY_CHECK
if (bootdelay == 0)
return 0;
#endif
# ifdef CONFIG_AUTOBOOT_PROMPT
/*
* CONFIG_AUTOBOOT_PROMPT includes the %d for all boards.
* To print the bootdelay value upon bootup.
*/
printf(CONFIG_AUTOBOOT_PROMPT, bootdelay);
# endif
# ifdef CONFIG_AUTOBOOT_DELAY_STR
if (delaykey[0].str == NULL)
delaykey[0].str = CONFIG_AUTOBOOT_DELAY_STR;
@@ -119,6 +173,33 @@ static int abortboot_keyed(int bootdelay)
}
} while (!abort && get_ticks() <= etime);
return abort;
}
#endif
/***************************************************************************
* Watch for 'delay' seconds for autoboot stop or autoboot delay string.
* returns: 0 - no key string, allow autoboot 1 - got key string, abort
*/
static int abortboot_keyed(int bootdelay)
{
int abort;
uint64_t etime = endtick(bootdelay);
#ifndef CONFIG_ZERO_BOOTDELAY_CHECK
if (bootdelay == 0)
return 0;
#endif
# ifdef CONFIG_AUTOBOOT_PROMPT
/*
* CONFIG_AUTOBOOT_PROMPT includes the %d for all boards.
* To print the bootdelay value upon bootup.
*/
printf(CONFIG_AUTOBOOT_PROMPT, bootdelay);
# endif
abort = passwd_abort(etime);
if (!abort)
debug_bootkeys("key timeout\n");