From patchwork Tue Jan 25 14:46:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilias Apalodimas X-Patchwork-Id: 536488 Delivered-To: patch@linaro.org Received: by 2002:ac0:f7d2:0:0:0:0:0 with SMTP id i18csp3773656imr; Tue, 25 Jan 2022 06:46:39 -0800 (PST) X-Google-Smtp-Source: ABdhPJxEpW7963neZApMSAnUtDJZEp7BgOjyQws3M0xuKxm3hFYWuQJ5Lg/WONqZUImjgiZEFuef X-Received: by 2002:a05:6402:4383:: with SMTP id o3mr8392695edc.353.1643121998892; Tue, 25 Jan 2022 06:46:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1643121998; cv=none; d=google.com; s=arc-20160816; b=D/eRAOBLcUj8cM6ufcvC8XoYCykBAmewvsUoObSuubizCF72q/lxUtkfiQ/peY0HHZ 3uLJ0iFnN8RMaeYOR6E6wlNqgkOn8ZT5b0wnMmmK1Vw7hct/bz02hzD7sWDBrkf1zx6z 72+njQQXH5bsL81iBPCoLLRmB2w7cxiYKWPZxihimhgAxIivSz62IrZJmgKNi67FmHIW OYG2ObioKhaXZtnxOGnI6oKXEZLKZmFZxxtVMFmgX0rHE6K3WFUdEed76Ps2ivadBpFR 58l93j3rKcveF77IyxJU5myoLGZ8w7K6/5bqWAG4uPRwrwCu+Vjcc1b7vQII5IlsW012 ERgA== 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=UMhhtRo+gLK/41gYsDX/cisWHOVm7hOs4ueNRf/XtM4=; b=QGsYL69NrLo0lU4YFsfiUxjnirfphwePSYzfy2bepW4HiU3quWHyfG1/NhieOEjedF QcbgLgNiVj2nOTxUW6pFU2H5VKkYoqBIVbN+PFCfQrXWO9i6gRNnfa/Nz64Hnswl1JrO Qoje6PmpWsDocurRBxB2SzGl1vpkcVDd3MxOUOYNHj/0l622p4Yn3zyhFMoZHxfbR0U5 3Pvy4Qlch40DxZWwWrcrQwURlw7PWm0XSij80zCQY8GDoc7raeN7eJkMYkIp50+xwAjc doHcNPdvDUMw4/HJ/NsjOCKVQf/P6jbkoTQYVmnOPxZRvzTrlnbLr+A+l+KT3jfzTf7H sHow== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=zXzBExQ5; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 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. [85.214.62.61]) by mx.google.com with ESMTPS id fy1si11821319ejc.492.2022.01.25.06.46.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 Jan 2022 06:46:38 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=zXzBExQ5; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 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 AEC6B83035; Tue, 25 Jan 2022 15:46:36 +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="zXzBExQ5"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 64BC483106; Tue, 25 Jan 2022 15:46:35 +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-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) (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 83EA381432 for ; Tue, 25 Jan 2022 15:46:32 +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-ed1-x534.google.com with SMTP id j2so63374682edj.8 for ; Tue, 25 Jan 2022 06:46:32 -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=UMhhtRo+gLK/41gYsDX/cisWHOVm7hOs4ueNRf/XtM4=; b=zXzBExQ5lAfOQHuNVW7v5Mz+2BsGKwyZPZdpH5slTV1fjBhizTE5K7hwSNRmATT1Bf 886w//CSEMDYxzehGlK64BP4NSVOHws40AUsHCNjMr+Fkv8OvwFU5T03OW4b4KYak+Tq COkOCTYefbug2PRhDzkCaOkDHRu24psAjxOwUeEGGs0E/A8yaRVD/MthJ7MdEatYQDKw N3PSt+5wTOZpTMtxP7SzXvDK28/MRuyhmZdeO0XEhgCni/g8/p6RXwCCm+9JnOIlvJrj 77g+o71SUNkwaPZP0lw2EPPazHzgRFN9UhwbY989HDxbKo+o1LmQL1lwmSSOijX7Ycul ArEw== 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=UMhhtRo+gLK/41gYsDX/cisWHOVm7hOs4ueNRf/XtM4=; b=GqT5eayyLlyLtBPCbnJgXVbsjvNMeGMhrtpwfVDzVZJfulzURHlmkHlaB1K+FOO3ba WQAv/eoj6DSwCjgktmbmrNao7Nm8mkSFEjm2yOF45y/zsqJ9ajtLzDKpzG9pdlLKcUs8 Fuj3M0feJ6+f4tKfmHIw+JTF48vDepvqXOlOXLP2w5DbTvFbwHWL8GEmgn6botuoxsv/ qG3IEvjDRG4I1zTuaiqnwFzuZ20gNq0aTJFe9Hs3mxjTiPK950DP67PnINPpS/KPYr3C Bf5oqdf4Mc5pHcau8AlBZ4J5v2uCuwIH091UgQbiSBcE7XTxXtkCPhczPYgei0/GhYCK riwA== X-Gm-Message-State: AOAM530oML1mVVqPojhg1V9natlUWskaaJw/tEOzpuVdwdL9uFej0hXn V3/Pnla7UofFMz3HVNTXa4ilgQ== X-Received: by 2002:a17:907:60cd:: with SMTP id hv13mr1209527ejc.368.1643121992036; Tue, 25 Jan 2022 06:46:32 -0800 (PST) Received: from hades.. ([2a02:587:46a6:e776:230:64ff:fe3b:505d]) by smtp.gmail.com with ESMTPSA id b7sm5182979edv.58.2022.01.25.06.46.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 Jan 2022 06:46:31 -0800 (PST) From: Ilias Apalodimas To: xypron.glpk@gmx.de, takahiro.akashi@linaro.org Cc: Ilias Apalodimas , u-boot@lists.denx.de Subject: [PATCH 1/1] efi_loader: clean up uefi secure boot image verification logic Date: Tue, 25 Jan 2022 16:46:28 +0200 Message-Id: <20220125144629.712580-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 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. When checking for sha256 hashes, in db, we don't really care if the image is signed or not. The sequence for verifying the binary can be 1. Is the sha256 of the image in dbx, reject the image 2. Certification checking 2a. Is the image signed with a certificate that's found in db and not in dbx 2b. 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 3. Is the sha256 of the image in db So weed out the 'special' case, which is 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 SHA256 verification loop if a signature happens to be the present before the hash. It's worth noting that (2a) only works if the certificate is self signed, but that can be fixed in a following patch. Signed-off-by: Ilias Apalodimas --- changes since RFC: - added a comment indication sha256 approval is the last resort case - reworded the commit message, based on Takahiro's proposal lib/efi_loader/efi_image_loader.c | 89 +++++++------------------------ lib/efi_loader/efi_signature.c | 2 +- 2 files changed, 20 insertions(+), 71 deletions(-) diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index 255613eb72ba..90594acf9623 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -516,63 +516,17 @@ 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 the image certificate table + * * 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 +562,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 +571,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 +676,22 @@ 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: + /* + * This our last resort, the image is not found in dbx and is not + * authenticated by any certs in db. Try the image hash in db + */ + 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)) {