From: Alexandru Gagniuc <mr.nuke.me@gmail.com>
To: u-boot@lists.denx.de
Subject: [PATCH 3/5] lib: ecdsa: Implement signature verification for crypto_algo API
Date: Mon, 11 Jan 2021 09:41:35 -0600 [thread overview]
Message-ID: <20210111154137.621732-4-mr.nuke.me@gmail.com> (raw)
In-Reply-To: <20210111154137.621732-1-mr.nuke.me@gmail.com>
Implement the crypto_algo .verify() function for ecdsa256. Because
it backends on UCLASS_ECDSA, this change is focused on parsing the
keys from devicetree and passing this information to the specific
UCLASS driver.
Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
lib/ecdsa/ecdsa-verify.c | 117 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 116 insertions(+), 1 deletion(-)
diff --git a/lib/ecdsa/ecdsa-verify.c b/lib/ecdsa/ecdsa-verify.c
index d2e6a40f4a..d84f6eb093 100644
--- a/lib/ecdsa/ecdsa-verify.c
+++ b/lib/ecdsa/ecdsa-verify.c
@@ -1,13 +1,128 @@
// SPDX-License-Identifier: GPL-2.0+
/*
+ * ECDSA signature verification for u-boot
+ *
+ * This implements the firmware-side wrapper for ECDSA verification. It bridges
+ * the struct crypto_algo API to the ECDSA uclass implementations.
+ *
* Copyright (c) 2020, Alexandru Gagniuc <mr.nuke.me@gmail.com>
*/
+#include <dm/uclass.h>
#include <u-boot/ecdsa.h>
+#include <crypto/ecdsa-uclass.h>
+
+/*
+ * Derive size of an ECDSA key from the curve name
+ *
+ * While it's possible to extract the key size by using string manipulation,
+ * use a list of known curves for the time being.
+ */
+static int ecdsa_key_size(const char *curve_name)
+{
+ if (!strcmp(curve_name, "prime256v1"))
+ return 256;
+ else
+ return 0;
+}
+
+static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)
+{
+ int x_len, y_len;
+
+ key->curve_name = fdt_getprop(fdt, node, "ecdsa,curve", NULL);
+ key->size_bits = ecdsa_key_size(key->curve_name);
+ if (key->size_bits == 0) {
+ debug("Unknown ECDSA curve '%s'", key->curve_name);
+ return -EINVAL;
+ }
+
+ key->x = fdt_getprop(fdt, node, "ecdsa,x-point", &x_len);
+ key->y = fdt_getprop(fdt, node, "ecdsa,y-point", &y_len);
+
+ if (!key->x || !key->y)
+ return -EINVAL;
+
+ if (x_len != (key->size_bits / 8) || y_len != (key->size_bits / 8)) {
+ printf("%s: node=%d, curve@%p x@%p+%i y@%p+%i\n", __func__,
+ node, key->curve_name, key->x, x_len, key->y, y_len);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int ecdsa_verify_hash(struct udevice *dev,
+ const struct image_sign_info *info,
+ const void *hash, const void *sig, uint sig_len)
+{
+ const struct ecdsa_ops *ops = device_get_ops(dev);
+ const struct checksum_algo *algo = info->checksum;
+ struct ecdsa_public_key key;
+ int sig_node, key_node, ret;
+
+ if (!ops || !ops->verify)
+ return -ENODEV;
+
+ if (info->required_keynode > 0) {
+ ret = fdt_get_key(&key, info->fdt_blob, info->required_keynode);
+ if (ret < 0)
+ return ret;
+
+ return ops->verify(dev, &key, hash, algo->checksum_len,
+ sig, sig_len);
+ }
+
+ sig_node = fdt_subnode_offset(info->fdt_blob, 0, FIT_SIG_NODENAME);
+ if (sig_node < 0)
+ return -ENOENT;
+
+ /* Try all possible keys under the "/signature" node */
+ fdt_for_each_subnode(key_node, info->fdt_blob, sig_node) {
+ ret = fdt_get_key(&key, info->fdt_blob, key_node);
+ if (ret < 0)
+ continue;
+
+ ret = ops->verify(dev, &key, hash, algo->checksum_len,
+ sig, sig_len);
+
+ /* On success, don't worry about remaining keys */
+ if (ret == 0)
+ return 0;
+ }
+
+ return -EPERM;
+}
int ecdsa_verify(struct image_sign_info *info,
const struct image_region region[], int region_count,
uint8_t *sig, uint sig_len)
{
- return -EOPNOTSUPP;
+ const struct checksum_algo *algo = info->checksum;
+ uint8_t hash[algo->checksum_len];
+ struct udevice *dev;
+ int ret;
+
+ ret = uclass_first_device(UCLASS_ECDSA, &dev);
+ if (ret) {
+ debug("ECDSA: Could not find ECDSA implementation: %d\n", ret);
+ return ret;
+ }
+
+ ret = algo->calculate(algo->name, region, region_count, hash);
+ if (ret < 0)
+ return -EINVAL;
+
+ return ecdsa_verify_hash(dev, info, hash, sig, sig_len);
}
+
+/*
+ * uclass definition for ECDSA API
+ *
+ * We don't implement any wrappers around ecdsa_ops->verify() because it's
+ * trivial to call ops->verify().
+ */
+UCLASS_DRIVER(ecdsa) = {
+ .id = UCLASS_ECDSA,
+ .name = "ecdsa_verifier",
+};
--
2.26.2
next prev parent reply other threads:[~2021-01-11 15:41 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-11 15:41 [PATCH 0/5] Enable ECDSA FIT verification for stm32mp Alexandru Gagniuc
2021-01-11 15:41 ` [PATCH 1/5] dm: crypto: Define UCLASS API for ECDSA signature verification Alexandru Gagniuc
2021-01-13 16:10 ` Simon Glass
2021-01-14 16:09 ` Alex G.
2021-01-14 19:16 ` Simon Glass
2021-01-11 15:41 ` [PATCH 2/5] lib: ecdsa: Add skeleton to implement ecdsa verification in u-boot Alexandru Gagniuc
2021-02-09 15:11 ` Patrick DELAUNAY
2021-02-09 22:37 ` Alex G.
2021-01-11 15:41 ` Alexandru Gagniuc [this message]
2021-01-13 16:10 ` [PATCH 3/5] lib: ecdsa: Implement signature verification for crypto_algo API Simon Glass
2021-02-09 15:56 ` Patrick DELAUNAY
2021-02-09 22:58 ` Alex G.
2021-01-11 15:41 ` [PATCH 4/5] arm: stm32mp1: Implement ECDSA signature verification Alexandru Gagniuc
2021-01-11 15:41 ` [PATCH 5/5] Kconfig: FIT_SIGNATURE should not select RSA_VERIFY Alexandru Gagniuc
2021-01-13 16:10 ` Simon Glass
2021-02-09 15:08 ` [PATCH 0/5] Enable ECDSA FIT verification for stm32mp Patrick DELAUNAY
2021-02-09 21:28 ` Alex G.
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210111154137.621732-4-mr.nuke.me@gmail.com \
--to=mr.nuke.me@gmail.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.