From mboxrd@z Thu Jan 1 00:00:00 1970 Delivery-date: Mon, 22 Jul 2024 10:25:01 +0200 Received: from metis.whiteo.stw.pengutronix.de ([2a0a:edc0:2:b01:1d::104]) by lore.white.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1sVoLt-001kqF-0l for lore@lore.pengutronix.de; Mon, 22 Jul 2024 10:25:01 +0200 Received: from bombadil.infradead.org ([2607:7c80:54:3::133]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1sVoLr-0000F9-Dd for lore@pengutronix.de; Mon, 22 Jul 2024 10:25:01 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To: Cc:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=iXmC0GsBEtk/onalHJRcd2QCr5ZsNiaRbyQ7jURZzkA=; b=Fj4TJa+23wp3L2HYgZEbvgRUP5 Flxi4Bsez3iHHQ8YcKcLikEOc2dpI7mBjz+VvVEy48k2QgeamNiKNpVhCDr+X0dBdUHIoEgzJsnHx /ppc/UFP43qqHyvKFwOiyZ9LFVueAJtUomnV8NxGpKxfyL0eckuBMzbc6x6z+pwnlyZs1LnvxX8Iq Xi0beZY2UXWD+LTjmxhuEikZKr/V9NDWjeMABFc4qWKNvUTXpjIfymFUcfc9QPuGuhuN02U7I8/b8 YeSY+y6ypCva2/FXtnuLyVQRBTTCoxTNv00i+BfQCRCQ6T9NOqPdJIzxU1iUwA5bKxKEPgXsMtl95 JMPfB+iA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sVoLE-00000008rml-3Pqe; Mon, 22 Jul 2024 08:24:20 +0000 Received: from metis.whiteo.stw.pengutronix.de ([2a0a:edc0:2:b01:1d::104]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sVoL6-00000008rih-1jZ8 for barebox@lists.infradead.org; Mon, 22 Jul 2024 08:24:16 +0000 Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1sVoL2-0008H1-Rd; Mon, 22 Jul 2024 10:24:08 +0200 Received: from [2a0a:edc0:0:1101:1d::28] (helo=dude02.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sVoL2-001L9v-Dg; Mon, 22 Jul 2024 10:24:08 +0200 Received: from localhost ([::1] helo=dude02.red.stw.pengutronix.de) by dude02.red.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from ) id 1sVoL2-00629B-12; Mon, 22 Jul 2024 10:24:08 +0200 From: Sascha Hauer To: Barebox List Date: Mon, 22 Jul 2024 10:24:05 +0200 Message-Id: <20240722082405.926111-10-s.hauer@pengutronix.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240722082405.926111-1-s.hauer@pengutronix.de> References: <20240722082405.926111-1-s.hauer@pengutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240722_012412_640743_3FBA3509 X-CRM114-Status: GOOD ( 18.96 ) X-BeenThere: barebox@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "barebox" X-SA-Exim-Connect-IP: 2607:7c80:54:3::133 X-SA-Exim-Mail-From: barebox-bounces+lore=pengutronix.de@lists.infradead.org X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on metis.whiteo.stw.pengutronix.de X-Spam-Level: X-Spam-Status: No, score=-5.3 required=4.0 tests=AWL,BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,SPF_HELO_NONE,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.2 Subject: [PATCH 9/9] fit: Add ecdsa support X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on metis.whiteo.stw.pengutronix.de) This adds ECDSA signing support to the FIT image code. Previously we unconditionally called into rsa_verify() as this was the only option. Now with ECDSA support we first have to check the type of the signature, so we start evaluating the signature type in given in the FIT image and call rsa_verify() or ecdsa_verify() depending on it. Signed-off-by: Sascha Hauer --- common/image-fit.c | 112 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 94 insertions(+), 18 deletions(-) diff --git a/common/image-fit.c b/common/image-fit.c index 6002440e7e..599d969a38 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -253,13 +254,11 @@ static struct digest *fit_alloc_digest(struct device_node *sig_node, return digest; } -static int fit_check_rsa_signature(struct device_node *sig_node, - enum hash_algo algo, void *hash) +static int fit_check_rsa_signature(const void *signature, size_t sig_len, + enum hash_algo algo, void *hash, + const char *key_name) { const struct rsa_public_key *key; - const char *key_name = NULL; - int sig_len; - const char *sig_value; int ret; if (!IS_ENABLED(CONFIG_CRYPTO_RSA)) { @@ -267,17 +266,10 @@ static int fit_check_rsa_signature(struct device_node *sig_node, return -EOPNOTSUPP; } - sig_value = of_get_property(sig_node, "value", &sig_len); - if (!sig_value) { - pr_err("signature value not found in %pOF\n", sig_node); - return -EINVAL; - } - - of_property_read_string(sig_node, "key-name-hint", &key_name); if (key_name) { key = rsa_get_key(key_name); if (key) { - ret = rsa_verify(key, sig_value, sig_len, hash, algo); + ret = rsa_verify(key, signature, sig_len, hash, algo); if (!ret) goto ok; } @@ -287,20 +279,104 @@ static int fit_check_rsa_signature(struct device_node *sig_node, if (key_name && !strcmp(key->key_name_hint, key_name)) continue; - ret = rsa_verify(key, sig_value, sig_len, hash, algo); + ret = rsa_verify(key, signature, sig_len, hash, algo); if (!ret) goto ok; } - pr_err("image signature BAD\n"); + pr_err("image RSA signature BAD\n"); return -EBADMSG; ok: - pr_info("image signature OK\n"); + pr_info("image RSA signature OK\n"); return 0; } +static int fit_check_ecdsa_signature(const void *signature, size_t sig_len, + enum hash_algo algo, void *hash, + const char *key_name) +{ + const struct ecdsa_public_key *key; + int ret; + + if (!IS_ENABLED(CONFIG_CRYPTO_ECDSA)) { + pr_err("ECDSA support is disabled, Cannot verify image\n"); + return -EOPNOTSUPP; + } + + for_each_ecdsa_key(key) { + ret = ecdsa_verify(key, signature, sig_len, hash); + if (!ret) { + pr_info("image ECDSA signature OK\n"); + return 0; + } + } + + pr_err("image ECDSA signature BAD\n"); + + return -EBADMSG; +} + +struct crypto_algo { + const char *name; + int (*verify)(const void *signature, size_t sig_len, enum hash_algo algo, + void *hash, const char *key_name); +}; + +static struct crypto_algo crypto_algos[] = { + { + .name = "rsa2048", + .verify = fit_check_rsa_signature, + }, { + .name = "rsa3072", + .verify = fit_check_rsa_signature, + }, { + .name = "rsa4096", + .verify = fit_check_rsa_signature, + }, { + .name = "ecdsa256", + .verify = fit_check_ecdsa_signature, + }, +}; + +static int fit_check_signature(struct device_node *sig_node, + enum hash_algo algo, void *hash) +{ + int sig_len, i; + const char *sig_value; + const char *algo_name; + const char *key_name = NULL; + const char *str; + + sig_value = of_get_property(sig_node, "value", &sig_len); + if (!sig_value) { + pr_err("signature value not found in %pOF\n", sig_node); + return -EINVAL; + } + + of_property_read_string(sig_node, "key-name-hint", &key_name); + + if (of_property_read_string(sig_node, "algo", &algo_name)) { + pr_err("algo property not found\n"); + return -EINVAL; + } + + str = strchr(algo_name, ','); + if (!str) + return -EINVAL; + str++; + + for (i = 0; i < ARRAY_SIZE(crypto_algos); i++) { + struct crypto_algo *ca = &crypto_algos[i]; + + if (!strcmp(ca->name, str)) + return ca->verify(sig_value, sig_len, algo, hash, key_name); + } + + return -EINVAL; +} + /* * The consistency of the FTD structure was already checked by of_unflatten_dtb() */ @@ -346,7 +422,7 @@ static int fit_verify_signature(struct device_node *sig_node, const void *fit) hash = xzalloc(digest_length(digest)); digest_final(digest, hash); - ret = fit_check_rsa_signature(sig_node, algo, hash); + ret = fit_check_signature(sig_node, algo, hash); if (ret) goto out_free_hash; @@ -469,7 +545,7 @@ static int fit_image_verify_signature(struct fit_handle *handle, hash = xzalloc(digest_length(digest)); digest_final(digest, hash); - ret = fit_check_rsa_signature(sig_node, algo, hash); + ret = fit_check_signature(sig_node, algo, hash); free(hash); -- 2.39.2