From patchwork Mon Jun 21 20:23:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steffen Jaeckel X-Patchwork-Id: 1495303 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4G81Gw1z4Xz9sTD for ; Tue, 22 Jun 2021 06:24:56 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 0A630829EF; Mon, 21 Jun 2021 22:24:42 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=eyet-services.de Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 76EAF82BDC; Mon, 21 Jun 2021 22:24:37 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_MSPIKE_H2, SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from common.oak.relay.mailchannels.net (common.oak.relay.mailchannels.net [23.83.215.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id A6B09829F0 for ; Mon, 21 Jun 2021 22:24:30 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=eyet-services.de Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=jaeckel-floss@eyet-services.de X-Sender-Id: instrampxe0y3a|x-authuser|jaeckel@eyet-services.de Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id F3CC712284E; Mon, 21 Jun 2021 20:24:27 +0000 (UTC) Received: from cpanel-004-fra.hostingww.com (100-96-133-115.trex.outbound.svc.cluster.local [100.96.133.115]) (Authenticated sender: instrampxe0y3a) by relay.mailchannels.net (Postfix) with ESMTPA id 308F3122B96; Mon, 21 Jun 2021 20:24:25 +0000 (UTC) X-Sender-Id: instrampxe0y3a|x-authuser|jaeckel@eyet-services.de Received: from cpanel-004-fra.hostingww.com (ec2-18-198-100-52.eu-central-1.compute.amazonaws.com [18.198.100.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384) by 100.96.133.115 (trex/6.3.3); Mon, 21 Jun 2021 20:24:27 +0000 X-MC-Relay: Bad X-MailChannels-SenderId: instrampxe0y3a|x-authuser|jaeckel@eyet-services.de X-MailChannels-Auth-Id: instrampxe0y3a X-White-Well-Made: 5777cadf37317810_1624307067736_684795681 X-MC-Loop-Signature: 1624307067735:562976477 X-MC-Ingress-Time: 1624307067735 Received: from hsi-kbw-46-223-101-50.hsi.kabel-badenwuerttemberg.de ([46.223.101.50]:39002 helo=draupnir.jaeckel.lan) by cpanel-004-fra.hostingww.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1lvQSx-00066a-B4; Mon, 21 Jun 2021 20:24:23 +0000 From: Steffen Jaeckel To: u-boot@lists.denx.de Cc: Steffen Jaeckel , Simon Glass , Alexandru Gagniuc , Bin Meng , Heiko Schocher , Heinrich Schuchardt , Joel Peshkin , Klaus Heinrich Kiwi , Masahisa Kojima , Siew Chin Lim , "Yuezhang.Mo@sony.com" Subject: [PATCH v3 3/8] common: integrate crypt-based passwords Date: Mon, 21 Jun 2021 22:23:46 +0200 Message-Id: <20210621202352.1250303-4-jaeckel-floss@eyet-services.de> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210621202352.1250303-1-jaeckel-floss@eyet-services.de> References: <20210621202352.1250303-1-jaeckel-floss@eyet-services.de> MIME-Version: 1.0 X-OutGoing-Spam-Status: No, score=-1.0 X-AuthUser: jaeckel@eyet-services.de X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean Hook into the autoboot flow as an alternative to the existing mechanisms. Signed-off-by: Steffen Jaeckel Reviewed-by: Simon Glass --- (no changes since v1) common/Kconfig.boot | 38 ++++++++++++++++++--- common/autoboot.c | 80 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 104 insertions(+), 14 deletions(-) diff --git a/common/Kconfig.boot b/common/Kconfig.boot index 89a3161f1f..410d117cdd 100644 --- a/common/Kconfig.boot +++ b/common/Kconfig.boot @@ -811,10 +811,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. @@ -852,9 +859,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 0bb08e7a4c..d52f88dd54 100644 --- a/common/autoboot.c +++ b/common/autoboot.c @@ -23,6 +23,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -38,18 +39,75 @@ 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_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; + 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 +147,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 +303,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");