From patchwork Mon Jan 24 15:36:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilias Apalodimas X-Patchwork-Id: 534515 Delivered-To: patch@linaro.org Received: by 2002:ac0:f7d2:0:0:0:0:0 with SMTP id i18csp2940142imr; Mon, 24 Jan 2022 07:36:29 -0800 (PST) X-Google-Smtp-Source: ABdhPJyW08eR68Sdowuw6Al6DY2as+syZIhGpjGmGZjAsKCZf2ptsFqcqCTLhExCvqPwTaE8mtXC X-Received: by 2002:a50:9f26:: with SMTP id b35mr12868039edf.364.1643038589560; Mon, 24 Jan 2022 07:36:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1643038589; cv=none; d=google.com; s=arc-20160816; b=JG+xfRvpQxQV8YtbguRcc8I9eEO4Wj7wKmQq6wE4iE1qsY+zB3ytlA0b/IXEjdfamk IxZYRmefPmXi1HTwXThaMKdZN4zIkrJUQoZJLStYBEG4r5oIyg/ATb/DbEip1gDppol9 Mpnxr3NTwQRq7hYxC7yU58/r4SHkqdikiTHL33fT9kbErOyzK9MqRmSpLRMU3xps25OU kbWfesM/MkGwqjqNuCw0YIE6NkKM3orTlp7G2Jd6T73+Snum2bJYhEaxTTEx7F/0HOoY F3x/xQ+g5fpmXx/zK8jOBO0X0BoIzxHAeL4vqEZAHJ9LRQOOgKVQ+U1vlfpj/gBnkVPE qIkA== 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:content-transfer-encoding :mime-version:message-id:date:subject:cc:to:from:dkim-signature; bh=YIMDbBh7DN7xHxYqyIKbtle3BRYziUSW523SzSLK9cs=; b=BnxllidxEzUPxzw/Rn4Y2AoHpalHSIlcfdpE6fwvyAyvAc98Tps4ubDvQgExidUSP4 TvHGv8FgPYOxLWAs50cI0DqwE3nuuf4HhK7SFroO8cITBY0/wpEv2rNUWGi0T5rweXXV sLVacMJ2qRgdPdyjRTZFgyx/x9F4bGSyA+mRztRwXY1LnAhlhb2oatpbPsWwbKfEz8FR mROU6OZyk+OR027hgoCU48EIRVUpv+xFKUC2g4wD2BAq3phaCNGxVVkMIphQvrUWdZnV tMPbT/v91CR9ZBRwkNNzM9LKFfUBieiuz5pO/TOfWlz1cN76j2X4EpKv6op1XCfTwcWI Jk3w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=r7EL8RIV; 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 l4si10203799ejo.195.2022.01.24.07.36.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Jan 2022 07:36:29 -0800 (PST) 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=r7EL8RIV; 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 A07B882148; Mon, 24 Jan 2022 16:36:28 +0100 (CET) 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="r7EL8RIV"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id D56D38303B; Mon, 24 Jan 2022 16:36:26 +0100 (CET) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-ej1-x629.google.com (mail-ej1-x629.google.com [IPv6:2a00:1450:4864:20::629]) (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 37C5581428 for ; Mon, 24 Jan 2022 16:36:24 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ilias.apalodimas@linaro.org Received: by mail-ej1-x629.google.com with SMTP id k25so22321433ejp.5 for ; Mon, 24 Jan 2022 07:36:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=YIMDbBh7DN7xHxYqyIKbtle3BRYziUSW523SzSLK9cs=; b=r7EL8RIVEsfO9qB+WhDaxYoicTiGolEQXrzby9UXn64I664MXu9CdLDutTYzqv3S1N Et0PNmxDnhWrq+3Lt7FxIoAlt3wd6fKbUez2ZTmkRokPs3CVZZOROD6pl35S+zOSUK3a 8/WQk2eJVTDYt/lPmUiiz6H8IvHDlvYnD3m9sp3F48MxXA3MSLGXNI/t7KTWjjm5WNTT PveV7fRs0j040zV11WzxtvJ/yasamYpZGsPJOckOzBvVFWFdZYbeGsKYXpRRv+tlnEYu tTpBu5U4YgBtOf6y4c9T8lQdop1Glhto8urIhgN6sGIvTj3L3JxVHN9IEzzmzBQ03R0F oD6g== 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:mime-version :content-transfer-encoding; bh=YIMDbBh7DN7xHxYqyIKbtle3BRYziUSW523SzSLK9cs=; b=MSx30L8X6vrIX5Ib9PRVwK4g3at4UJ58Ywn8VORtdHc7P68Xfvm0YmJlaWRv+//hVw bhqy3Mi9e82Y/5l4sKb034E5QJpOg5pjzXLubBw87DbyMxbycZZ5M+DbPQOJF6Lvl5mp LUr7pXGGohgmb5zcww3fXd+I27pp4dU6Q5gSj9/lkQI8ECiW/jEi3zNqAThDWXl+0L36 9Fya8jE9Kv/zfzVlkxaV1HKAQNw5PuN27pXgGc6AY7RUu/IzwhhyBtx4k6YeuWjxTHjH NmAwQC/US1mMfvg75aH2m7/PQ2GpwqONEoBdqaKMEvyVDYhoUEs6r3yZrCzacfY3VuQc +2qw== X-Gm-Message-State: AOAM53135cYFxadcPfHLkk3uqCLcV1kbRzwjC0PMee215fxxwO1Mq4q/ W2j41d6SjNVoDdST9ds/0nhgQGD+wOphCVKh X-Received: by 2002:a17:907:1c11:: with SMTP id nc17mr2387876ejc.308.1643038583717; Mon, 24 Jan 2022 07:36:23 -0800 (PST) Received: from hades.. ([2a02:587:46a6:e776:230:64ff:fe3b:505d]) by smtp.gmail.com with ESMTPSA id u6sm5045572ejn.181.2022.01.24.07.36.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Jan 2022 07:36:23 -0800 (PST) From: Ilias Apalodimas To: xypron.glpk@gmx.de, takahiro.akashi@linaro.org Cc: Ilias Apalodimas , u-boot@lists.denx.de Subject: [RFC PATCH] efi_loader: clean up uefi secure boot image verification logic Date: Mon, 24 Jan 2022 17:36:20 +0200 Message-Id: <20220124153621.662350-1-ilias.apalodimas@linaro.org> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 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 From: Ilias Apalodimas We currently distinguish between signed and non signed PE/COFF executables while trying to authenticate signatures and/or sha256 hashes in db and dbx. That code duplication can be avoided. On sha256 hashes we don't really care if the image is signed or not. The logic can be implemented in 1. Is the sha256 of the image in dbx 2. Is the image signed with a certificate that's found in db and not in dbx 3. The image carries a cert which is signed by a cert in db (and not in dbx, and the image can be verified against the former) 4. Is the sha256 of the image in db So weed out the 'special' case handling unsigned images. While at it move the checking of a hash outside the certificate verification loop which isn't really needed and check for the hash only once. Also allow a mix of signatures and hashes in db instead of explicitly breaking out the sha verification loop if a signature happens to be added first. It's worth noting that (2) only works if the certificate is self signed, but that canb be fixed in a following patch. Signed-off-by: Ilias Apalodimas --- lib/efi_loader/efi_image_loader.c | 84 ++++++------------------------- lib/efi_loader/efi_signature.c | 2 +- 2 files changed, 15 insertions(+), 71 deletions(-) diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index 255613eb72ba..53d54ca42f5c 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -516,63 +516,16 @@ err: } #ifdef CONFIG_EFI_SECURE_BOOT -/** - * efi_image_unsigned_authenticate() - authenticate unsigned image with - * SHA256 hash - * @regs: List of regions to be verified - * - * If an image is not signed, it doesn't have a signature. In this case, - * its message digest is calculated and it will be compared with one of - * hash values stored in signature databases. - * - * Return: true if authenticated, false if not - */ -static bool efi_image_unsigned_authenticate(struct efi_image_regions *regs) -{ - struct efi_signature_store *db = NULL, *dbx = NULL; - bool ret = false; - - dbx = efi_sigstore_parse_sigdb(L"dbx"); - if (!dbx) { - EFI_PRINT("Getting signature database(dbx) failed\n"); - goto out; - } - - db = efi_sigstore_parse_sigdb(L"db"); - if (!db) { - EFI_PRINT("Getting signature database(db) failed\n"); - goto out; - } - - /* try black-list first */ - if (efi_signature_lookup_digest(regs, dbx)) { - EFI_PRINT("Image is not signed and its digest found in \"dbx\"\n"); - goto out; - } - - /* try white-list */ - if (efi_signature_lookup_digest(regs, db)) - ret = true; - else - EFI_PRINT("Image is not signed and its digest not found in \"db\" or \"dbx\"\n"); - -out: - efi_sigstore_free(db); - efi_sigstore_free(dbx); - - return ret; -} - /** * efi_image_authenticate() - verify a signature of signed image * @efi: Pointer to image * @efi_size: Size of @efi * - * A signed image should have its signature stored in a table of its PE header. + * An image should have its signature stored in a table of its PE header. * So if an image is signed and only if if its signature is verified using - * signature databases, an image is authenticated. - * If an image is not signed, its validity is checked by using - * efi_image_unsigned_authenticated(). + * signature databases or if it's sha256 is found in db an image is + * authenticated. + * * TODO: * When AuditMode==0, if the image's signature is not found in * the authorized database, or is found in the forbidden database, @@ -608,14 +561,7 @@ static bool efi_image_authenticate(void *efi, size_t efi_size) if (!efi_image_parse(new_efi, efi_size, ®s, &wincerts, &wincerts_len)) { EFI_PRINT("Parsing PE executable image failed\n"); - goto err; - } - - if (!wincerts) { - /* The image is not signed */ - ret = efi_image_unsigned_authenticate(regs); - - goto err; + goto out; } /* @@ -624,18 +570,18 @@ static bool efi_image_authenticate(void *efi, size_t efi_size) db = efi_sigstore_parse_sigdb(L"db"); if (!db) { EFI_PRINT("Getting signature database(db) failed\n"); - goto err; + goto out; } dbx = efi_sigstore_parse_sigdb(L"dbx"); if (!dbx) { EFI_PRINT("Getting signature database(dbx) failed\n"); - goto err; + goto out; } if (efi_signature_lookup_digest(regs, dbx)) { EFI_PRINT("Image's digest was found in \"dbx\"\n"); - goto err; + goto out; } /* @@ -729,20 +675,18 @@ static bool efi_image_authenticate(void *efi, size_t efi_size) /* try white-list */ if (efi_signature_verify(regs, msg, db, dbx)) { ret = true; - break; + goto out; } EFI_PRINT("Signature was not verified by \"db\"\n"); - if (efi_signature_lookup_digest(regs, db)) { - ret = true; - break; - } - - EFI_PRINT("Image's digest was not found in \"db\" or \"dbx\"\n"); } -err: + if (efi_signature_lookup_digest(regs, db)) + ret = true; + else + EFI_PRINT("Image's digest was not found in \"db\" or \"dbx\"\n"); +out: efi_sigstore_free(db); efi_sigstore_free(dbx); pkcs7_free_message(msg); diff --git a/lib/efi_loader/efi_signature.c b/lib/efi_loader/efi_signature.c index 3243e2c60de0..8fa82f8cea4c 100644 --- a/lib/efi_loader/efi_signature.c +++ b/lib/efi_loader/efi_signature.c @@ -176,7 +176,7 @@ bool efi_signature_lookup_digest(struct efi_image_regions *regs, if (guidcmp(&siglist->sig_type, &efi_guid_sha256)) { EFI_PRINT("Digest algorithm is not supported: %pUs\n", &siglist->sig_type); - break; + continue; } if (!efi_hash_regions(regs->reg, regs->num, &hash, &size)) {