From patchwork Sun Jun 19 05:20:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 583003 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:7814:0:0:0:0 with SMTP id b20csp758107mav; Sat, 18 Jun 2022 22:19:59 -0700 (PDT) X-Google-Smtp-Source: AGRyM1t4KmRp+ON9WtbXFNLiYgqDPneGD7+UTnwU9avw+VxfwFgiyKVw9Jc4o68hDU1wxycL2Hdo X-Received: by 2002:a05:6402:350b:b0:42f:d079:647f with SMTP id b11-20020a056402350b00b0042fd079647fmr21135223edd.321.1655615998831; Sat, 18 Jun 2022 22:19:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1655615998; cv=none; d=google.com; s=arc-20160816; b=JDRXy+9yHkCIPqu5LNE/i+og1JRyy4yyFaFAjinkCoTje++eRJWb1o6GhvJ+C1XPGT OvXY1rDodw8b6GULiqtsuaaoNHN7AnoMYnDvt2ugP/N69KXkVxchnTFJ6hFY3zPBR44f Exks5+ue8VcmmA95OlaSceN4ev/RxWZx9zrEDlSwDmrtcUGpWAZsFH5joDP8lwwlIstY a9H9AbV5disN3NVAhYDTLk4mBaOfeGJoW01naE7ieou5h/ymi2WkAe5G9YBodbRecTxm 2mwY8BSjZkfme1XFR9mLqOPmsmyWI63w0aTqPLyLlxJchzI8hStqJy+McQHFAnd8RexH OqxA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=Y2mZs8XTetd7WZtB7os+qoxQ28UNXrCUE4UNgct3cM8=; b=sjYIBpYfHHNYB0io7Kyo04X5uFLGNoIxSyZQ+VGKwnaTuL8MSUspy/Clz2AjWCgODt d5W90Eud0o9gOebtBTGkYOM5h0xGvIZp4qVxVD+13yjHssoSv9c3e+xqXt7013YkW+MO leuCsyX1lPEEigx6Yul8JO0lgLav/QXEWBVsT4xalB2cQfpoxf2ZdPb6eUJL5+goGG/A 7gVnMzqGSa8FmUE0Vm3qo+iBgZgHngkYPX4pa3TQ7C8cF9ciLlp7DsCd8Q1j7VxzAUm5 COn/j+KRYfzo3g72p8xbDSz2gcT1HNBut83UDgKpPUCFYDy0WptkJ6vyWx3Xo34auR78 2C8w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="RaoMI/Po"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id nb19-20020a1709071c9300b006e82f2c77cfsi8132509ejc.199.2022.06.18.22.19.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Jun 2022 22:19:58 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="RaoMI/Po"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id D412D84400; Sun, 19 Jun 2022 07:19:43 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="RaoMI/Po"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id EB7EE843F4; Sun, 19 Jun 2022 07:19:40 +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=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x634.google.com (mail-pl1-x634.google.com [IPv6:2607:f8b0:4864:20::634]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 3BA2F843D8 for ; Sun, 19 Jun 2022 07:19:38 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=masahisa.kojima@linaro.org Received: by mail-pl1-x634.google.com with SMTP id o18so22287plg.2 for ; Sat, 18 Jun 2022 22:19:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Y2mZs8XTetd7WZtB7os+qoxQ28UNXrCUE4UNgct3cM8=; b=RaoMI/PoXZhXq+ttixCSyg6zMFF2S3uJdAP3c1aAtZryVQ4QzdPW2cALb/t+7XEWeg S1iKDH/zpMg1rJeQw3acRZ+t9fyLjLwbxIoFPTSwL3FCmTKmBRoTKjKBtQGffQBzl2Do +1bucpbzY092Waerst9d1mK7pJid5y4Et3ewAalHh2L7qtfb8mwYZTmJEfJ2AE8rtJ9y hY0Ddtr8m/wXljFC6+kOZV94Xx2ceFpxeVKaGcJabOu573+vty0wu9MxFSnUXchbk6BQ +uQOkMUM4AvoCSziaLiHAEVyR6DGz/IGkR2C0sJwDGMyBHcPTVl/zOyTZHE5nvUAw/yO qskw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Y2mZs8XTetd7WZtB7os+qoxQ28UNXrCUE4UNgct3cM8=; b=pzK2ddgDvXZ9pqLImxA7Bo0WwUyQq5UFXYBFAzhZS5U9jp0pyTRGhnLLqIMtIaX0hN Mg/aHEmMAJ1B8QA7lSK+eFUYI8U6Ixh1a6nlPWelTPddnbdVqsmN4+gHXcvVBuv5jths XvhY5rZjLPWkest+Q2e/Ywb4n0DLoaE8OYEZp1Nr+NJiXdRIlicMqc7KygOnjzjz0zRq t1KWj5h3+EP/Y6Mg9IqqRm9PhDAlsTm+U/Vu0khpWW3jYs77oILAI0zt5+aJkit1Auz/ 9nvTRjonOzO3/tI+9KqaEzYFrWrdrenu35Dh0pIRNjGty9LvMQI8jW008NMRrJgcLFIv jMPg== X-Gm-Message-State: AJIora9N2APndfZ1bqkkFb9TxOm0N9uMItHwpsiRvqlHejY+V4vLsWXr j1//eLQL2/e6R5Y9NvrHWguU72DtUBUqsQ== X-Received: by 2002:a17:902:dac7:b0:166:4ce4:7e32 with SMTP id q7-20020a170902dac700b001664ce47e32mr17606170plx.168.1655615976409; Sat, 18 Jun 2022 22:19:36 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id j3-20020a170903024300b001636c0b98a7sm6087243plh.226.2022.06.18.22.19.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Jun 2022 22:19:36 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis , Masahisa Kojima Subject: [RFC PATCH 3/3] eficonfig: add "Delete Key" menu entry Date: Sun, 19 Jun 2022 14:20:22 +0900 Message-Id: <20220619052022.2694-4-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220619052022.2694-1-masahisa.kojima@linaro.org> References: <20220619052022.2694-1-masahisa.kojima@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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.5 at phobos.denx.de X-Virus-Status: Clean This commit add the menu-driven interface to delete the signature database entry. EFI Signature Lists can contain the multiple signature entries, this menu can delete the indivisual entry. If the PK is enrolled and UEFI Secure Boot is in User Mode, user can not delete the existing signature lists since the signature lists must be signed by KEK or PK but signing information is not stored in the signature database. Signed-off-by: Masahisa Kojima --- cmd/eficonfig_sbkey.c | 218 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 217 insertions(+), 1 deletion(-) diff --git a/cmd/eficonfig_sbkey.c b/cmd/eficonfig_sbkey.c index 02ab8f8218..142bb4cef5 100644 --- a/cmd/eficonfig_sbkey.c +++ b/cmd/eficonfig_sbkey.c @@ -54,6 +54,29 @@ static const struct eficonfig_sigtype_to_str sigtype_to_str[] = { /* {EFI_CERT_SHA512_GUID, "SHA512", SIG_TYPE_HASH}, */ }; +static int eficonfig_console_yes_no(void) +{ + int esc = 0; + enum bootmenu_key key = KEY_NONE; + + while (1) { + bootmenu_loop(NULL, &key, &esc); + + switch (key) { + case KEY_SELECT: + return 1; + case KEY_QUIT: + return 0; + default: + break; + } + } + + /* never happens */ + debug("eficonfig: this should not happen"); + return 0; +} + static void eficonfig_console_wait_enter(void) { int esc = 0; @@ -72,7 +95,19 @@ static void eficonfig_console_wait_enter(void) /* never happens */ debug("eficonfig: this should not happen"); - return; +} + +static bool is_setupmode(void) +{ + efi_status_t ret; + u8 setup_mode; + efi_uintn_t size; + + size = sizeof(setup_mode); + ret = efi_get_variable_int(u"SetupMode", &efi_global_variable_guid, + NULL, &size, &setup_mode, NULL); + + return setup_mode == 1; } static bool is_secureboot_enabled(void) @@ -254,6 +289,103 @@ static efi_status_t eficonfig_process_sigdata_show(void *data) return EFI_SUCCESS; } +static efi_status_t eficonfig_process_sigdata_delete(void *data) +{ + int yes_no; + struct eficonfig_sig_data *sg = data; + + display_sigdata_header(sg, "Delete"); + display_sigdata_info(sg); + + printf("\n\n Press ENTER to delete, ESC/CTRL+C to quit"); + yes_no = eficonfig_console_yes_no(); + if (!yes_no) + return EFI_NOT_READY; + + return EFI_SUCCESS; +} + +static void delete_selected_signature_data(void *db, efi_uintn_t *db_size, + struct eficonfig_sig_data *target, + struct list_head *siglist_list) +{ + u8 *dest, *start; + struct list_head *pos, *n; + u32 remain; + u32 size = *db_size; + u8 *end = (u8 *)db + size; + struct eficonfig_sig_data *sg; + + list_for_each_safe(pos, n, siglist_list) { + sg = list_entry(pos, struct eficonfig_sig_data, list); + if (sg->esl == target->esl && sg->esd == target->esd) { + remain = sg->esl->signature_list_size - + (sizeof(struct efi_signature_list) - + sg->esl->signature_header_size) - + sg->esl->signature_size; + if (remain > 0) { + /* only delete the single signature data */ + sg->esl->signature_list_size -= sg->esl->signature_size; + size -= sg->esl->signature_size; + dest = (u8 *)sg->esd; + start = (u8 *)sg->esd + sg->esl->signature_size; + } else { + /* delete entire signature list */ + dest = (u8 *)sg->esl; + start = (u8 *)sg->esl + sg->esl->signature_list_size; + size -= sg->esl->signature_list_size; + } + memmove(dest, start, (end - start)); + } + } + + *db_size = size; +} + +static efi_status_t create_time_based_payload(void *db, void **new_db, efi_uintn_t *size) +{ + efi_status_t ret; + struct efi_time time; + efi_uintn_t total_size; + struct efi_variable_authentication_2 *auth; + + *new_db = NULL; + + /* + * SetVariable() call with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS + * attribute requires EFI_VARIABLE_AUTHENTICATED_2 descriptor, prepare it + * without certificate data in it. + */ + total_size = sizeof(struct efi_variable_authentication_2) + *size; + + auth = calloc(1, total_size); + if (!auth) + return EFI_OUT_OF_RESOURCES; + + ret = EFI_CALL((*efi_runtime_services.get_time)(&time, NULL)); + if (ret != EFI_SUCCESS) { + free(auth); + return EFI_OUT_OF_RESOURCES; + } + time.pad1 = 0; + time.nanosecond = 0; + time.timezone = 0; + time.daylight = 0; + time.pad2 = 0; + memcpy(&auth->time_stamp, &time, sizeof(time)); + auth->auth_info.hdr.dwLength = sizeof(struct win_certificate_uefi_guid); + auth->auth_info.hdr.wRevision = 0x0200; + auth->auth_info.hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID; + guidcpy(&auth->auth_info.cert_type, &efi_guid_cert_type_pkcs7); + if (db) + memcpy((u8 *)auth + sizeof(struct efi_variable_authentication_2), db, *size); + + *new_db = auth; + *size = total_size; + + return EFI_SUCCESS; +} + static efi_status_t prepare_signature_db_list(struct eficonfig_item **output, void *varname, void *db, efi_uintn_t db_size, eficonfig_entry_func func, @@ -378,6 +510,68 @@ out: return ret; } +static efi_status_t process_delete_key(void *varname) +{ + u32 attr, i, count = 0; + efi_status_t ret; + struct eficonfig_item *menu_item = NULL, *iter; + void *db = NULL, *new_db = NULL; + efi_uintn_t db_size; + struct list_head siglist_list; + struct eficonfig_sig_data *selected; + + db = efi_get_var(varname, efi_auth_var_get_guid(varname), &db_size); + if (!db) { + eficonfig_print_msg("There is no entry in the signature database."); + return EFI_NOT_FOUND; + } + + ret = prepare_signature_db_list(&menu_item, varname, db, db_size, + eficonfig_process_sigdata_delete, &selected, + &siglist_list, &count); + if (ret != EFI_SUCCESS) + goto out; + + ret = eficonfig_process_common(menu_item, count, " ** Delete Key **"); + + if (ret == EFI_SUCCESS) { + delete_selected_signature_data(db, &db_size, selected, &siglist_list); + + ret = create_time_based_payload(db, &new_db, &db_size); + if (ret != EFI_SUCCESS) + goto out; + + attr = EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS | + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS; + ret = efi_set_variable_int((u16 *)varname, efi_auth_var_get_guid((u16 *)varname), + attr, db_size, new_db, false); + if (ret != EFI_SUCCESS) { + eficonfig_print_msg("ERROR! Fail to delete signature database"); + goto out; + } + } + +out: + if (menu_item) { + iter = menu_item; + for (i = 0; i < count - 1; iter++, i++) { + free(iter->title); + free(iter->data); + } + } + + free(menu_item); + free(db); + free(new_db); + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret; + + return ret; +} + static efi_status_t eficonfig_process_show_signature_db(void *data) { efi_status_t ret; @@ -394,6 +588,27 @@ static efi_status_t eficonfig_process_show_signature_db(void *data) return ret; } +static efi_status_t eficonfig_process_delete_key(void *data) +{ + efi_status_t ret; + + if (!is_setupmode()) { + eficonfig_print_msg("Not in the SetupMode, can not delete."); + return EFI_SUCCESS; + } + + while (1) { + ret = process_delete_key(data); + if (ret != EFI_SUCCESS) + break; + } + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret; + + return ret; +} + static struct eficonfig_item key_config_pk_menu_items[] = { {"Enroll New Key", eficonfig_process_enroll_key}, {"Show Signature Database", eficonfig_process_show_signature_db}, @@ -403,6 +618,7 @@ static struct eficonfig_item key_config_pk_menu_items[] = { static struct eficonfig_item key_config_menu_items[] = { {"Enroll New Key", eficonfig_process_enroll_key}, {"Show Signature Database", eficonfig_process_show_signature_db}, + {"Delete Key", eficonfig_process_delete_key}, {"Quit", eficonfig_process_quit}, };