All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] Enable ECDSA FIT verification for stm32mp
@ 2021-01-11 15:41 Alexandru Gagniuc
  2021-01-11 15:41 ` [PATCH 1/5] dm: crypto: Define UCLASS API for ECDSA signature verification Alexandru Gagniuc
                   ` (5 more replies)
  0 siblings, 6 replies; 17+ messages in thread
From: Alexandru Gagniuc @ 2021-01-11 15:41 UTC (permalink / raw)
  To: u-boot

This series is Part II of the ECDSA saga. It applies on top of [1]:
 * [PATCH v4 0/6] Add support for ECDSA image signing (with test)

I've designed the UCLASS_ECDSA such that it aligns with the ROM API
of the stm32mp. Instead of splitting the verification into
(1) curve operations and (2) modular exponentiation, I've
concatenated everything in a 'verify' step. It would be impossible to
split the steps and use the stm32mp ROM for verification.

Should more granular control be required, this API could be extended
at a later time. Until we have more hardware supporting ECDSA, this
is purely speculative.

The ROM API of the stm32mp is passed in 'r0' when the FSBL is called.
While we can save 'r0' in SPL, this series does not implement a
mechanism to pass this to u-boot. Thus the ROM API, and ECDSA
verification are only available for SPL. Although extending this to
u-boot by adding the ROM address to the FDT blob, implementing and
verifying this is beyond the scope of this series.

[1] https://lists.denx.de/pipermail/u-boot/2021-January/436935.html

Alexandru Gagniuc (5):
  dm: crypto: Define UCLASS API for ECDSA signature verification
  lib: ecdsa: Add skeleton to implement ecdsa verification in u-boot
  lib: ecdsa: Implement signature verification for crypto_algo API
  arm: stm32mp1: Implement ECDSA signature verification
  Kconfig: FIT_SIGNATURE should not select RSA_VERIFY

 arch/arm/mach-stm32mp/Kconfig        |   9 ++
 arch/arm/mach-stm32mp/Makefile       |   1 +
 arch/arm/mach-stm32mp/ecdsa_romapi.c | 106 ++++++++++++++++++++++
 common/Kconfig.boot                  |   8 +-
 include/crypto/ecdsa-uclass.h        |  39 ++++++++
 include/dm/uclass-id.h               |   1 +
 include/image.h                      |  10 +--
 include/u-boot/rsa.h                 |   2 +-
 lib/Kconfig                          |   1 +
 lib/Makefile                         |   1 +
 lib/ecdsa/Kconfig                    |  23 +++++
 lib/ecdsa/Makefile                   |   1 +
 lib/ecdsa/ecdsa-verify.c             | 128 +++++++++++++++++++++++++++
 13 files changed, 320 insertions(+), 10 deletions(-)
 create mode 100644 arch/arm/mach-stm32mp/ecdsa_romapi.c
 create mode 100644 include/crypto/ecdsa-uclass.h
 create mode 100644 lib/ecdsa/Kconfig
 create mode 100644 lib/ecdsa/Makefile
 create mode 100644 lib/ecdsa/ecdsa-verify.c

-- 
2.26.2

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 1/5] dm: crypto: Define UCLASS API for ECDSA signature verification
  2021-01-11 15:41 [PATCH 0/5] Enable ECDSA FIT verification for stm32mp Alexandru Gagniuc
@ 2021-01-11 15:41 ` Alexandru Gagniuc
  2021-01-13 16:10   ` Simon Glass
  2021-01-11 15:41 ` [PATCH 2/5] lib: ecdsa: Add skeleton to implement ecdsa verification in u-boot Alexandru Gagniuc
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 17+ messages in thread
From: Alexandru Gagniuc @ 2021-01-11 15:41 UTC (permalink / raw)
  To: u-boot

Define a UCLASS API for verifying ECDSA signatures. Unlike
UCLASS_MOD_EXP, which focuses strictly on modular exponentiation,
the ECDSA class focuses on verification. This is done so that it
better aligns with mach-specific implementations, such as stm32mp.

Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
 include/crypto/ecdsa-uclass.h | 39 +++++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h        |  1 +
 2 files changed, 40 insertions(+)
 create mode 100644 include/crypto/ecdsa-uclass.h

diff --git a/include/crypto/ecdsa-uclass.h b/include/crypto/ecdsa-uclass.h
new file mode 100644
index 0000000000..189843820a
--- /dev/null
+++ b/include/crypto/ecdsa-uclass.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2020, Alexandru Gagniuc <mr.nuke.me@gmail.com>
+ */
+
+#include <dm/device.h>
+
+/**
+ * struct ecdsa_public_key - ECDSA public key properties
+ *
+ * The struct has pointers to the (x, y) curve coordinates to an ECDSA public
+ * key, as well as the name of the ECDSA curve. The size of the key is inferred
+ * from the 'curve_name'
+ */
+struct ecdsa_public_key {
+	const char *curve_name;	/* Name of curve, e.g. "prime256v1" */
+	const void *x;		/* x coordinate of public key */
+	const void *y;		/* y coordinate of public key */
+	unsigned int size_bits;	/* key size in bits, derived from curve name */
+};
+
+struct ecdsa_ops {
+	/**
+	 * Verify signature of hash against given public key
+	 *
+	 * @dev:	ECDSA Device
+	 * @pubkey:	ECDSA public key
+	 * @hash:	Hash of binary image
+	 * @hash_len:	Length of hash in bytes
+	 * @signature:	Signature in a raw (R, S) point pair
+	 * @sig_len:	Length of signature in bytes
+	 *
+	 * This function verifies that the 'signature' of the given 'hash' was
+	 * signed by the private key corresponding to 'pubkey'.
+	 */
+	int (*verify)(struct udevice *dev, const struct ecdsa_public_key *pubkey,
+		      const void *hash, size_t hash_len,
+		      const void *signature, size_t sig_len);
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index e952a9967c..de4f5db086 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -45,6 +45,7 @@ enum uclass_id {
 	UCLASS_DISPLAY,		/* Display (e.g. DisplayPort, HDMI) */
 	UCLASS_DSI_HOST,	/* Display Serial Interface host */
 	UCLASS_DMA,		/* Direct Memory Access */
+	UCLASS_ECDSA,		/* Elliptic curve cryptographic device */
 	UCLASS_EFI,		/* EFI managed devices */
 	UCLASS_ETH,		/* Ethernet device */
 	UCLASS_ETH_PHY,		/* Ethernet PHY device */
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 2/5] lib: ecdsa: Add skeleton to implement ecdsa verification in u-boot
  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-11 15:41 ` Alexandru Gagniuc
  2021-02-09 15:11   ` Patrick DELAUNAY
  2021-01-11 15:41 ` [PATCH 3/5] lib: ecdsa: Implement signature verification for crypto_algo API Alexandru Gagniuc
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 17+ messages in thread
From: Alexandru Gagniuc @ 2021-01-11 15:41 UTC (permalink / raw)
  To: u-boot

Prepare the source tree for accepting implementations of the ECDSA
algorithm. This patch deals with the boring aspects of Makefiles and
Kconfig files.

Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
 include/image.h          | 10 +++++-----
 include/u-boot/rsa.h     |  2 +-
 lib/Kconfig              |  1 +
 lib/Makefile             |  1 +
 lib/ecdsa/Kconfig        | 23 +++++++++++++++++++++++
 lib/ecdsa/Makefile       |  1 +
 lib/ecdsa/ecdsa-verify.c | 13 +++++++++++++
 7 files changed, 45 insertions(+), 6 deletions(-)
 create mode 100644 lib/ecdsa/Kconfig
 create mode 100644 lib/ecdsa/Makefile
 create mode 100644 lib/ecdsa/ecdsa-verify.c

diff --git a/include/image.h b/include/image.h
index 6628173dca..1d70ba0ece 100644
--- a/include/image.h
+++ b/include/image.h
@@ -1198,20 +1198,20 @@ int calculate_hash(const void *data, int data_len, const char *algo,
 #if defined(USE_HOSTCC)
 # if defined(CONFIG_FIT_SIGNATURE)
 #  define IMAGE_ENABLE_SIGN	1
-#  define IMAGE_ENABLE_VERIFY	1
+#  define IMAGE_ENABLE_VERIFY_RSA	1
 #  define IMAGE_ENABLE_VERIFY_ECDSA	1
 #  define FIT_IMAGE_ENABLE_VERIFY	1
 #  include <openssl/evp.h>
 # else
 #  define IMAGE_ENABLE_SIGN	0
-#  define IMAGE_ENABLE_VERIFY	0
+#  define IMAGE_ENABLE_VERIFY_RSA	0
 # define IMAGE_ENABLE_VERIFY_ECDSA	0
 #  define FIT_IMAGE_ENABLE_VERIFY	0
 # endif
 #else
 # define IMAGE_ENABLE_SIGN	0
-# define IMAGE_ENABLE_VERIFY		CONFIG_IS_ENABLED(RSA_VERIFY)
-# define IMAGE_ENABLE_VERIFY_ECDSA	0
+# define IMAGE_ENABLE_VERIFY_RSA	CONFIG_IS_ENABLED(RSA_VERIFY)
+# define IMAGE_ENABLE_VERIFY_ECDSA	CONFIG_IS_ENABLED(ECDSA_VERIFY)
 # define FIT_IMAGE_ENABLE_VERIFY	CONFIG_IS_ENABLED(FIT_SIGNATURE)
 #endif
 
@@ -1260,7 +1260,7 @@ struct image_region {
 	int size;
 };
 
-#if IMAGE_ENABLE_VERIFY
+#if FIT_IMAGE_ENABLE_VERIFY
 # include <u-boot/hash-checksum.h>
 #endif
 struct checksum_algo {
diff --git a/include/u-boot/rsa.h b/include/u-boot/rsa.h
index bed1c097c2..eb258fca4c 100644
--- a/include/u-boot/rsa.h
+++ b/include/u-boot/rsa.h
@@ -81,7 +81,7 @@ static inline int rsa_add_verify_data(struct image_sign_info *info,
 }
 #endif
 
-#if IMAGE_ENABLE_VERIFY
+#if IMAGE_ENABLE_VERIFY_RSA
 /**
  * rsa_verify_hash() - Verify a signature against a hash
  *
diff --git a/lib/Kconfig b/lib/Kconfig
index 7673d2e4e0..e2cb846fc0 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -292,6 +292,7 @@ config AES
 	  supported by the algorithm but only a 128-bit key is supported at
 	  present.
 
+source lib/ecdsa/Kconfig
 source lib/rsa/Kconfig
 source lib/crypto/Kconfig
 
diff --git a/lib/Makefile b/lib/Makefile
index cf64188ba5..ab86be2678 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -59,6 +59,7 @@ endif
 
 obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi/
 obj-$(CONFIG_$(SPL_)MD5) += md5.o
+obj-$(CONFIG_ECDSA) += ecdsa/
 obj-$(CONFIG_$(SPL_)RSA) += rsa/
 obj-$(CONFIG_FIT_SIGNATURE) += hash-checksum.o
 obj-$(CONFIG_SHA1) += sha1.o
diff --git a/lib/ecdsa/Kconfig b/lib/ecdsa/Kconfig
new file mode 100644
index 0000000000..1244d6b6ea
--- /dev/null
+++ b/lib/ecdsa/Kconfig
@@ -0,0 +1,23 @@
+config ECDSA
+	bool "Enable ECDSA support"
+	depends on DM
+	help
+	  This enables the ECDSA algorithm for FIT image verification in U-Boot.
+	  See doc/uImage.FIT/signature.txt for more details.
+	  The ECDSA algorithm is implemented using the driver model. So
+	  CONFIG_DM is required by this library.
+	  ECDSA is enabled for mkimage regardless of this  option.
+
+if ECDSA
+
+config ECDSA_VERIFY
+	bool "Enable ECDSA verification support in U-Boot."
+	help
+	  Allow ECDSA signatures to be recognized and verified in U-Boot.
+
+config SPL_ECDSA_VERIFY
+	bool "Enable ECDSA verification support in SPL"
+	help
+	  Allow ECDSA signatures to be recognized and verified in SPL.
+
+endif
diff --git a/lib/ecdsa/Makefile b/lib/ecdsa/Makefile
new file mode 100644
index 0000000000..771d6d3135
--- /dev/null
+++ b/lib/ecdsa/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_$(SPL_)ECDSA_VERIFY) += ecdsa-verify.o
diff --git a/lib/ecdsa/ecdsa-verify.c b/lib/ecdsa/ecdsa-verify.c
new file mode 100644
index 0000000000..d2e6a40f4a
--- /dev/null
+++ b/lib/ecdsa/ecdsa-verify.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020, Alexandru Gagniuc <mr.nuke.me@gmail.com>
+ */
+
+#include <u-boot/ecdsa.h>
+
+int ecdsa_verify(struct image_sign_info *info,
+		 const struct image_region region[], int region_count,
+		 uint8_t *sig, uint sig_len)
+{
+	return -EOPNOTSUPP;
+}
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 3/5] lib: ecdsa: Implement signature verification for crypto_algo API
  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-11 15:41 ` [PATCH 2/5] lib: ecdsa: Add skeleton to implement ecdsa verification in u-boot Alexandru Gagniuc
@ 2021-01-11 15:41 ` Alexandru Gagniuc
  2021-01-13 16:10   ` Simon Glass
  2021-02-09 15:56   ` Patrick DELAUNAY
  2021-01-11 15:41 ` [PATCH 4/5] arm: stm32mp1: Implement ECDSA signature verification Alexandru Gagniuc
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 17+ messages in thread
From: Alexandru Gagniuc @ 2021-01-11 15:41 UTC (permalink / raw)
  To: u-boot

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

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 4/5] arm: stm32mp1: Implement ECDSA signature verification
  2021-01-11 15:41 [PATCH 0/5] Enable ECDSA FIT verification for stm32mp Alexandru Gagniuc
                   ` (2 preceding siblings ...)
  2021-01-11 15:41 ` [PATCH 3/5] lib: ecdsa: Implement signature verification for crypto_algo API Alexandru Gagniuc
@ 2021-01-11 15:41 ` Alexandru Gagniuc
  2021-01-11 15:41 ` [PATCH 5/5] Kconfig: FIT_SIGNATURE should not select RSA_VERIFY Alexandru Gagniuc
  2021-02-09 15:08 ` [PATCH 0/5] Enable ECDSA FIT verification for stm32mp Patrick DELAUNAY
  5 siblings, 0 replies; 17+ messages in thread
From: Alexandru Gagniuc @ 2021-01-11 15:41 UTC (permalink / raw)
  To: u-boot

The STM32MP ROM provides several service. One of them is the ability
to verify ecdsa256 signatures. Hook the ROM API into the ECDSA uclass.

Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
 arch/arm/mach-stm32mp/Kconfig        |   9 +++
 arch/arm/mach-stm32mp/Makefile       |   1 +
 arch/arm/mach-stm32mp/ecdsa_romapi.c | 106 +++++++++++++++++++++++++++
 3 files changed, 116 insertions(+)
 create mode 100644 arch/arm/mach-stm32mp/ecdsa_romapi.c

diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig
index f538d7cb83..f1e00929fd 100644
--- a/arch/arm/mach-stm32mp/Kconfig
+++ b/arch/arm/mach-stm32mp/Kconfig
@@ -121,6 +121,15 @@ config STM32_ETZPC
 	help
 	  Say y to enable STM32 Extended TrustZone Protection
 
+config STM32_ECDSA_VERIFY
+	bool "STM32 ECDSA verification via the ROM API"
+	depends on SPL_ECDSA_VERIFY
+	default y
+	help
+	  Say y to enable the uclass driver for ECDSA verification using the
+	  ROM API provided on STM32MP.
+	  The ROM API is only available during SPL for now.
+
 config CMD_STM32PROG
 	bool "command stm32prog for STM32CudeProgrammer"
 	select DFU
diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile
index c8aa24d489..c03fedb486 100644
--- a/arch/arm/mach-stm32mp/Makefile
+++ b/arch/arm/mach-stm32mp/Makefile
@@ -10,6 +10,7 @@ obj-y += bsec.o
 
 ifdef CONFIG_SPL_BUILD
 obj-y += spl.o
+obj-$(CONFIG_STM32_ECDSA_VERIFY) += ecdsa_romapi.o
 else
 obj-$(CONFIG_CMD_STM32PROG) += cmd_stm32prog/
 obj-$(CONFIG_CMD_STM32KEY) += cmd_stm32key.o
diff --git a/arch/arm/mach-stm32mp/ecdsa_romapi.c b/arch/arm/mach-stm32mp/ecdsa_romapi.c
new file mode 100644
index 0000000000..7f71d7a341
--- /dev/null
+++ b/arch/arm/mach-stm32mp/ecdsa_romapi.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * STM32MP ECDSA verification via the ROM API
+ *
+ * Implements ECDSA signature verification via the STM32MP ROM.
+ */
+#include <asm/system.h>
+#include <dm/device.h>
+#include <linux/types.h>
+#include <u-boot/ecdsa.h>
+#include <crypto/ecdsa-uclass.h>
+#include <linux/libfdt.h>
+#include <dm/platdata.h>
+
+#define ROM_API_SUCCESS				0x77
+#define ROM_API_ECDSA_ALGO_PRIME_256V1		1
+#define ROM_API_ECDSA_ALGO_BRAINPOOL_256	2
+
+#define ROM_API_OFFSET_ECDSA_CHECK_KEY		0x5c
+#define ROM_API_OFFSET_ECDSA_VERIFY		0x60
+
+struct ecdsa_rom_api {
+	uint32_t (*ecdsa_check_key)(const void *pubkey_in, void *pubkey_out);
+	uint32_t (*ecdsa_verify_signature)(const void *hash, const void *pubkey,
+					   const void *signature,
+				    uint32_t ecc_algo);
+};
+
+/*
+ * Without forcing the ".data" section, this would get saved in ".bss". BSS
+ * will be cleared soon after, so it's not suitable.
+ */
+static uintptr_t rom_api_loc __section(".data");
+
+/*
+ * The ROM gives us the API location in r0 when starting. This is only available
+ * during SPL, as there isn't (yet) a mechanism to pass this on to u-boot.
+ */
+void save_boot_params(unsigned long r0, unsigned long r1, unsigned long r2,
+		      unsigned long r3)
+{
+	rom_api_loc = r0;
+	save_boot_params_ret();
+}
+
+static void stm32mp_rom_get_ecdsa_functions(struct ecdsa_rom_api *rom)
+{
+	uintptr_t verify_ptr = rom_api_loc + ROM_API_OFFSET_ECDSA_VERIFY;
+	uintptr_t check_key_ptr = rom_api_loc + ROM_API_OFFSET_ECDSA_CHECK_KEY;
+
+	rom->ecdsa_verify_signature = *(void **)verify_ptr;
+	rom->ecdsa_check_key = *(void **)check_key_ptr;
+}
+
+static int ecdsa_key_algo(const char *curve_name)
+{
+	if (!strcmp(curve_name, "prime256v1"))
+		return ROM_API_ECDSA_ALGO_PRIME_256V1;
+	else if (!strcmp(curve_name, "brainpool256"))
+		return ROM_API_ECDSA_ALGO_BRAINPOOL_256;
+	else
+		return -ENOPROTOOPT;
+}
+
+static int romapi_ecdsa_verify(struct udevice *dev,
+			       const struct ecdsa_public_key *pubkey,
+			       const void *hash, size_t hash_len,
+			       const void *signature, size_t sig_len)
+{
+	struct ecdsa_rom_api rom;
+	uint8_t raw_key[64];
+	uint32_t rom_ret;
+	int algo;
+
+	/* The ROM API can only handle 256-bit ECDSA keys. */
+	if (sig_len != 32 || hash_len != 32 || pubkey->size_bits != 256)
+		return -EINVAL;
+
+	algo = ecdsa_key_algo(pubkey->curve_name);
+	if (algo < 0)
+		return algo;
+
+	/* The ROM API wants the (X, Y) coordinates concatenated. */
+	memcpy(raw_key, pubkey->x, 32);
+	memcpy(raw_key + 32, pubkey->y, 32);
+
+	stm32mp_rom_get_ecdsa_functions(&rom);
+	rom_ret = rom.ecdsa_verify_signature(hash, raw_key, signature, algo);
+
+	return rom_ret == ROM_API_SUCCESS ? 0 : -EPERM;
+}
+
+static const struct ecdsa_ops rom_api_ops = {
+	.verify = romapi_ecdsa_verify,
+};
+
+U_BOOT_DRIVER(stm32mp_rom_api_ecdsa) = {
+	.name	= "stm32mp_rom_api_ecdsa",
+	.id	= UCLASS_ECDSA,
+	.ops	= &rom_api_ops,
+	.flags	= DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DEVICE(stm32mp_rom_api_ecdsa) = {
+	.name = "stm32mp_rom_api_ecdsa",
+};
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 5/5] Kconfig: FIT_SIGNATURE should not select RSA_VERIFY
  2021-01-11 15:41 [PATCH 0/5] Enable ECDSA FIT verification for stm32mp Alexandru Gagniuc
                   ` (3 preceding siblings ...)
  2021-01-11 15:41 ` [PATCH 4/5] arm: stm32mp1: Implement ECDSA signature verification Alexandru Gagniuc
@ 2021-01-11 15:41 ` 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
  5 siblings, 1 reply; 17+ messages in thread
From: Alexandru Gagniuc @ 2021-01-11 15:41 UTC (permalink / raw)
  To: u-boot

FIT signatures can now be implemented with ECDSA. The assumption that
all FIT images are signed with RSA is no longer valid. Thus, instead
of 'select'ing RSA, only 'imply' it. This doesn't change the defaults,
but allows one to explicitly disable RSA support.

Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
 common/Kconfig.boot | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/common/Kconfig.boot b/common/Kconfig.boot
index 3f6d9c1a25..280476698d 100644
--- a/common/Kconfig.boot
+++ b/common/Kconfig.boot
@@ -67,8 +67,8 @@ config FIT_SIGNATURE
 	bool "Enable signature verification of FIT uImages"
 	depends on DM
 	select HASH
-	select RSA
-	select RSA_VERIFY
+	imply RSA
+	imply RSA_VERIFY
 	select IMAGE_SIGN_INFO
 	help
 	  This option enables signature verification of FIT uImages,
@@ -159,8 +159,8 @@ config SPL_FIT_SIGNATURE
 	select SPL_FIT
 	select SPL_CRYPTO_SUPPORT
 	select SPL_HASH_SUPPORT
-	select SPL_RSA
-	select SPL_RSA_VERIFY
+	imply SPL_RSA
+	imply SPL_RSA_VERIFY
 	select SPL_IMAGE_SIGN_INFO
 
 config SPL_LOAD_FIT
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 3/5] lib: ecdsa: Implement signature verification for crypto_algo API
  2021-01-11 15:41 ` [PATCH 3/5] lib: ecdsa: Implement signature verification for crypto_algo API Alexandru Gagniuc
@ 2021-01-13 16:10   ` Simon Glass
  2021-02-09 15:56   ` Patrick DELAUNAY
  1 sibling, 0 replies; 17+ messages in thread
From: Simon Glass @ 2021-01-13 16:10 UTC (permalink / raw)
  To: u-boot

On Mon, 11 Jan 2021 at 08:41, Alexandru Gagniuc <mr.nuke.me@gmail.com> wrote:
>
> 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(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 1/5] dm: crypto: Define UCLASS API for ECDSA signature verification
  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.
  0 siblings, 1 reply; 17+ messages in thread
From: Simon Glass @ 2021-01-13 16:10 UTC (permalink / raw)
  To: u-boot

Hi Alexandru,

On Mon, 11 Jan 2021 at 08:41, Alexandru Gagniuc <mr.nuke.me@gmail.com> wrote:
>
> Define a UCLASS API for verifying ECDSA signatures. Unlike
> UCLASS_MOD_EXP, which focuses strictly on modular exponentiation,
> the ECDSA class focuses on verification. This is done so that it
> better aligns with mach-specific implementations, such as stm32mp.
>
> Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
> ---
>  include/crypto/ecdsa-uclass.h | 39 +++++++++++++++++++++++++++++++++++
>  include/dm/uclass-id.h        |  1 +
>  2 files changed, 40 insertions(+)
>  create mode 100644 include/crypto/ecdsa-uclass.h

This needs a test, as do all uclasses in U-Boot. If it isn't easy to
implement the algorithm then I suppose you could fake it by using an
easy algorithm like md5, but it does need a test.

Regards,
Simon

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 5/5] Kconfig: FIT_SIGNATURE should not select RSA_VERIFY
  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
  0 siblings, 0 replies; 17+ messages in thread
From: Simon Glass @ 2021-01-13 16:10 UTC (permalink / raw)
  To: u-boot

On Mon, 11 Jan 2021 at 08:41, Alexandru Gagniuc <mr.nuke.me@gmail.com> wrote:
>
> FIT signatures can now be implemented with ECDSA. The assumption that
> all FIT images are signed with RSA is no longer valid. Thus, instead
> of 'select'ing RSA, only 'imply' it. This doesn't change the defaults,
> but allows one to explicitly disable RSA support.
>
> Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
> ---
>  common/Kconfig.boot | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 1/5] dm: crypto: Define UCLASS API for ECDSA signature verification
  2021-01-13 16:10   ` Simon Glass
@ 2021-01-14 16:09     ` Alex G.
  2021-01-14 19:16       ` Simon Glass
  0 siblings, 1 reply; 17+ messages in thread
From: Alex G. @ 2021-01-14 16:09 UTC (permalink / raw)
  To: u-boot

On 1/13/21 10:10 AM, Simon Glass wrote:
> Hi Alexandru,
> 
> On Mon, 11 Jan 2021 at 08:41, Alexandru Gagniuc <mr.nuke.me@gmail.com> wrote:
>>
>> Define a UCLASS API for verifying ECDSA signatures. Unlike
>> UCLASS_MOD_EXP, which focuses strictly on modular exponentiation,
>> the ECDSA class focuses on verification. This is done so that it
>> better aligns with mach-specific implementations, such as stm32mp.
>>
>> Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
>> ---
>>   include/crypto/ecdsa-uclass.h | 39 +++++++++++++++++++++++++++++++++++
>>   include/dm/uclass-id.h        |  1 +
>>   2 files changed, 40 insertions(+)
>>   create mode 100644 include/crypto/ecdsa-uclass.h
> 
> This needs a test, as do all uclasses in U-Boot. If it isn't easy to
> implement the algorithm then I suppose you could fake it by using an
> easy algorithm like md5, but it does need a test.

I agree. I couldn't find a test for UCLASS_MOD_EXP (for guidance), so 
I'm not sure where to even start.

Alex

> Regards,
> Simon
> 

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 1/5] dm: crypto: Define UCLASS API for ECDSA signature verification
  2021-01-14 16:09     ` Alex G.
@ 2021-01-14 19:16       ` Simon Glass
  0 siblings, 0 replies; 17+ messages in thread
From: Simon Glass @ 2021-01-14 19:16 UTC (permalink / raw)
  To: u-boot

Hi Alex,

On Thu, 14 Jan 2021 at 09:09, Alex G. <mr.nuke.me@gmail.com> wrote:
>
> On 1/13/21 10:10 AM, Simon Glass wrote:
> > Hi Alexandru,
> >
> > On Mon, 11 Jan 2021 at 08:41, Alexandru Gagniuc <mr.nuke.me@gmail.com> wrote:
> >>
> >> Define a UCLASS API for verifying ECDSA signatures. Unlike
> >> UCLASS_MOD_EXP, which focuses strictly on modular exponentiation,
> >> the ECDSA class focuses on verification. This is done so that it
> >> better aligns with mach-specific implementations, such as stm32mp.
> >>
> >> Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
> >> ---
> >>   include/crypto/ecdsa-uclass.h | 39 +++++++++++++++++++++++++++++++++++
> >>   include/dm/uclass-id.h        |  1 +
> >>   2 files changed, 40 insertions(+)
> >>   create mode 100644 include/crypto/ecdsa-uclass.h
> >
> > This needs a test, as do all uclasses in U-Boot. If it isn't easy to
> > implement the algorithm then I suppose you could fake it by using an
> > easy algorithm like md5, but it does need a test.
>
> I agree. I couldn't find a test for UCLASS_MOD_EXP (for guidance), so
> I'm not sure where to even start.

How about dm_test_rng_read()? That is pretty simple and does a few basic things.

Re UCLASS_MOD_EXP this is tested by the vboot tests. It should really
have a simple unit test too, though. This is an example of how to add
a software implementation of a hardware algorithm. See mod_exp_sw.c

Regards,
Simon

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 0/5] Enable ECDSA FIT verification for stm32mp
  2021-01-11 15:41 [PATCH 0/5] Enable ECDSA FIT verification for stm32mp Alexandru Gagniuc
                   ` (4 preceding siblings ...)
  2021-01-11 15:41 ` [PATCH 5/5] Kconfig: FIT_SIGNATURE should not select RSA_VERIFY Alexandru Gagniuc
@ 2021-02-09 15:08 ` Patrick DELAUNAY
  2021-02-09 21:28   ` Alex G.
  5 siblings, 1 reply; 17+ messages in thread
From: Patrick DELAUNAY @ 2021-02-09 15:08 UTC (permalink / raw)
  To: u-boot

Hi Alexandru,

On 1/11/21 4:41 PM, Alexandru Gagniuc wrote:
> This series is Part II of the ECDSA saga. It applies on top of [1]: *  > [PATCH v4 0/6] Add support for ECDSA image signing (with test) > > 
I've designed the UCLASS_ECDSA such that it aligns with the ROM API > of 
the stm32mp. Instead of splitting the verification into (1) curve > 
operations and (2) modular exponentiation, I've concatenated > 
everything in a 'verify' step. It would be impossible to split the > 
steps and use the stm32mp ROM for verification. > > Should more granular 
control be required, this API could be extended > at a later time. Until 
we have more hardware supporting ECDSA, this > is purely speculative. > 
 > The ROM API of the stm32mp is passed in 'r0' when the FSBL is > 
called. While we can save 'r0' in SPL, this series does not implement > 
a mechanism to pass this to u-boot. Thus the ROM API, and ECDSA > 
verification are only available for SPL. Although extending this to > 
u-boot by adding the ROM address to the FDT blob, implementing and > 
verifying this is beyond the scope of this series.

For information, today the STMicroelectronics expected that the boot 
sequence for secure boot

(with closed STM32MP1 devices) is the trusted boot chain.



TF-A (BL2) => OP-TEE or????? => U-Boot =>? OS

 ??????????????????????? TF-A (BL32)


BL2 is authenticated by ROM code, with EDCSA support.


I next OpenSTLinux release (and soon after in upstream) 
STMicroelectronics will add FIP support

for STM32MP15x; TF-A FIP allows to boot Kernel after TF-A BL2 if you 
want to skip U-Boot

TF-A (BL2) => FIP (OP-TEE + Kernel)


And the FIP allow authentication with certificate for 'secured boot' 
with a complete chain of trust.

https://trustedfirmware-a.readthedocs.io/en/latest/index.html


So the ECDSA support in SPL for STM32MP15x will be not actively 
supported by STMicroelectronics for product design.


> 

>  > [1] https://lists.denx.de/pipermail/u-boot/2021-January/436935.html > 
 > Alexandru Gagniuc (5): dm: crypto: Define UCLASS API for ECDSA > 
signature verification lib: ecdsa: Add skeleton to implement ecdsa > 
verification in u-boot lib: ecdsa: Implement signature verification > 
for crypto_algo API arm: stm32mp1: Implement ECDSA signature > 
verification Kconfig: FIT_SIGNATURE should not select RSA_VERIFY > > 
arch/arm/mach-stm32mp/Kconfig | 9 ++ > arch/arm/mach-stm32mp/Makefile | 
1 + > arch/arm/mach-stm32mp/ecdsa_romapi.c | 106 ++++++++++++++++++++++ 
 > common/Kconfig.boot | 8 +- > include/crypto/ecdsa-uclass.h | 39 
++++++++ > include/dm/uclass-id.h | 1 + include/image.h > | 10 +-- 
include/u-boot/rsa.h | 2 +- lib/Kconfig > | 1 + lib/Makefile | 1 + > 
lib/ecdsa/Kconfig | 23 +++++ lib/ecdsa/Makefile > | 1 + 
lib/ecdsa/ecdsa-verify.c | 128 > +++++++++++++++++++++++++++ 13 files 
changed, 320 insertions(+), 10 > deletions(-) create mode 100644 
arch/arm/mach-stm32mp/ecdsa_romapi.c > create mode 100644 
include/crypto/ecdsa-uclass.h create mode 100644 > lib/ecdsa/Kconfig 
create mode 100644 lib/ecdsa/Makefile create mode > 100644 
lib/ecdsa/ecdsa-verify.c >


Regards

Patrick

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 2/5] lib: ecdsa: Add skeleton to implement ecdsa verification in u-boot
  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.
  0 siblings, 1 reply; 17+ messages in thread
From: Patrick DELAUNAY @ 2021-02-09 15:11 UTC (permalink / raw)
  To: u-boot

Hi,

On 1/11/21 4:41 PM, Alexandru Gagniuc wrote:
> Prepare the source tree for accepting implementations of the ECDSA
> algorithm. This patch deals with the boring aspects of Makefiles and
> Kconfig files.
>
> Signed-off-by: Alexandru Gagniuc<mr.nuke.me@gmail.com>
> ---
>   include/image.h          | 10 +++++-----
>   include/u-boot/rsa.h     |  2 +-
>   lib/Kconfig              |  1 +
>   lib/Makefile             |  1 +
>   lib/ecdsa/Kconfig        | 23 +++++++++++++++++++++++
>   lib/ecdsa/Makefile       |  1 +
>   lib/ecdsa/ecdsa-verify.c | 13 +++++++++++++
>   7 files changed, 45 insertions(+), 6 deletions(-)
>   create mode 100644 lib/ecdsa/Kconfig
>   create mode 100644 lib/ecdsa/Makefile
>   create mode 100644 lib/ecdsa/ecdsa-verify.c
>
> diff --git a/include/image.h b/include/image.h
> index 6628173dca..1d70ba0ece 100644
> --- a/include/image.h
> +++ b/include/image.h
> @@ -1198,20 +1198,20 @@ int calculate_hash(const void *data, int data_len, const char *algo,
>   #if defined(USE_HOSTCC)
>   # if defined(CONFIG_FIT_SIGNATURE)
>   #  define IMAGE_ENABLE_SIGN	1
> -#  define IMAGE_ENABLE_VERIFY	1
> +#  define IMAGE_ENABLE_VERIFY_RSA	1
>   #  define IMAGE_ENABLE_VERIFY_ECDSA	1
>   #  define FIT_IMAGE_ENABLE_VERIFY	1
>   #  include <openssl/evp.h>
>   # else
>   #  define IMAGE_ENABLE_SIGN	0
> -#  define IMAGE_ENABLE_VERIFY	0
> +#  define IMAGE_ENABLE_VERIFY_RSA	0
>   # define IMAGE_ENABLE_VERIFY_ECDSA	0
>   #  define FIT_IMAGE_ENABLE_VERIFY	0
>   # endif
>   #else
>   # define IMAGE_ENABLE_SIGN	0
> -# define IMAGE_ENABLE_VERIFY		CONFIG_IS_ENABLED(RSA_VERIFY)
> -# define IMAGE_ENABLE_VERIFY_ECDSA	0
> +# define IMAGE_ENABLE_VERIFY_RSA	CONFIG_IS_ENABLED(RSA_VERIFY)
> +# define IMAGE_ENABLE_VERIFY_ECDSA	CONFIG_IS_ENABLED(ECDSA_VERIFY)

here you are using CONFIG_IS_ENABLED.

This macro imply to test CONFIG_ECDSA_VERIFY or CONFIG_SPL_ECDSA_VERIFY (for SPL build)

=> but CONFIG_SPL_ECDSA_VERIFY is missing, I think you need to add it, as RSA
  

>   # define FIT_IMAGE_ENABLE_VERIFY	CONFIG_IS_ENABLED(FIT_SIGNATURE)
>   #endif
>   
> @@ -1260,7 +1260,7 @@ struct image_region {
>   	int size;
>   };
>   
> -#if IMAGE_ENABLE_VERIFY
> +#if FIT_IMAGE_ENABLE_VERIFY
>   # include <u-boot/hash-checksum.h>
>   #endif
>   struct checksum_algo {
> diff --git a/include/u-boot/rsa.h b/include/u-boot/rsa.h
> index bed1c097c2..eb258fca4c 100644
> --- a/include/u-boot/rsa.h
> +++ b/include/u-boot/rsa.h
> @@ -81,7 +81,7 @@ static inline int rsa_add_verify_data(struct image_sign_info *info,
>   }
>   #endif
>   
> -#if IMAGE_ENABLE_VERIFY
> +#if IMAGE_ENABLE_VERIFY_RSA
>   /**
>    * rsa_verify_hash() - Verify a signature against a hash
>    *
> diff --git a/lib/Kconfig b/lib/Kconfig
> index 7673d2e4e0..e2cb846fc0 100644
> --- a/lib/Kconfig
> +++ b/lib/Kconfig
> @@ -292,6 +292,7 @@ config AES
>   	  supported by the algorithm but only a 128-bit key is supported at
>   	  present.
>   
> +source lib/ecdsa/Kconfig
>   source lib/rsa/Kconfig
>   source lib/crypto/Kconfig
>   
> diff --git a/lib/Makefile b/lib/Makefile
> index cf64188ba5..ab86be2678 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -59,6 +59,7 @@ endif
>   
>   obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi/
>   obj-$(CONFIG_$(SPL_)MD5) += md5.o
> +obj-$(CONFIG_ECDSA) += ecdsa/

obj-$(CONFIG_$(SPL_)ECDSA) += ecdsa/


>   obj-$(CONFIG_$(SPL_)RSA) += rsa/
>   obj-$(CONFIG_FIT_SIGNATURE) += hash-checksum.o
>   obj-$(CONFIG_SHA1) += sha1.o
> diff --git a/lib/ecdsa/Kconfig b/lib/ecdsa/Kconfig
> new file mode 100644
> index 0000000000..1244d6b6ea
> --- /dev/null
> +++ b/lib/ecdsa/Kconfig
> @@ -0,0 +1,23 @@
> +config ECDSA
> +	bool "Enable ECDSA support"
> +	depends on DM
> +	help
> +	  This enables the ECDSA algorithm for FIT image verification in U-Boot.
> +	  See doc/uImage.FIT/signature.txt for more details.
> +	  The ECDSA algorithm is implemented using the driver model. So
> +	  CONFIG_DM is required by this library.
> +	  ECDSA is enabled for mkimage regardless of this  option.
> +
> +if ECDSA
> +

Add CONFIG_SPL_ECDSA to select independently support in SPL et/or in U-Boot

as it is done for RSA

+ config SPL_ECDSA
+	bool "Use ECDSA library within in SPL"

  

> +config ECDSA_VERIFY
> +	bool "Enable ECDSA verification support in U-Boot."


+ select SPL_ECDSA


> +	help
> +	  Allow ECDSA signatures to be recognized and verified in U-Boot.
> +
> +config SPL_ECDSA_VERIFY
> +	bool "Enable ECDSA verification support in SPL"
> +	help
> +	  Allow ECDSA signatures to be recognized and verified in SPL.
> +
> +endif
> diff --git a/lib/ecdsa/Makefile b/lib/ecdsa/Makefile
> new file mode 100644
> index 0000000000..771d6d3135
> --- /dev/null
> +++ b/lib/ecdsa/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_$(SPL_)ECDSA_VERIFY) += ecdsa-verify.o
> diff --git a/lib/ecdsa/ecdsa-verify.c b/lib/ecdsa/ecdsa-verify.c
> new file mode 100644
> index 0000000000..d2e6a40f4a
> --- /dev/null
> +++ b/lib/ecdsa/ecdsa-verify.c
> @@ -0,0 +1,13 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2020, Alexandru Gagniuc<mr.nuke.me@gmail.com>
> + */
> +
> +#include <u-boot/ecdsa.h>
> +
> +int ecdsa_verify(struct image_sign_info *info,
> +		 const struct image_region region[], int region_count,
> +		 uint8_t *sig, uint sig_len)
> +{
> +	return -EOPNOTSUPP;
> +}


Regards,

Patrick

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 3/5] lib: ecdsa: Implement signature verification for crypto_algo API
  2021-01-11 15:41 ` [PATCH 3/5] lib: ecdsa: Implement signature verification for crypto_algo API Alexandru Gagniuc
  2021-01-13 16:10   ` Simon Glass
@ 2021-02-09 15:56   ` Patrick DELAUNAY
  2021-02-09 22:58     ` Alex G.
  1 sibling, 1 reply; 17+ messages in thread
From: Patrick DELAUNAY @ 2021-02-09 15:56 UTC (permalink / raw)
  To: u-boot

Hi,

On 1/11/21 4:41 PM, Alexandru Gagniuc wrote:
> 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>
>    */
>   

http://www.denx.de/wiki/U-Boot/CodingStyle #Include files

#include <crypto/ecdsa-uclass.h>

it is normally the first in alphabetic order of directory

> +#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;
> +}
> +


To prepare the future can you parse a array of supported curves with 
associated ID

used as parameter of ECDSA parameter = enum ECDSA_CURVES

for example: char * name, int size, enum ECDSA_CURVES

const [] = {
{"prime256v1", 256, ECDSA_PRIME256V1 },

}


> +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);


Need to indicate the used curve here as parameter of the verify opts ?


> +	}
> +
> +	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)


issue raised by chekpatch I think

if (!ret)


> +			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",
> +};


Regards

Patrick

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 0/5] Enable ECDSA FIT verification for stm32mp
  2021-02-09 15:08 ` [PATCH 0/5] Enable ECDSA FIT verification for stm32mp Patrick DELAUNAY
@ 2021-02-09 21:28   ` Alex G.
  0 siblings, 0 replies; 17+ messages in thread
From: Alex G. @ 2021-02-09 21:28 UTC (permalink / raw)
  To: u-boot

Hi Patrick,

On 2/9/21 9:08 AM, Patrick DELAUNAY wrote:
[snip]
> For information, today the STMicroelectronics expected that the boot 
> sequence for secure boot
> 
> (with closed STM32MP1 devices) is the trusted boot chain.
> 
> 
> 
> TF-A (BL2) => OP-TEE or????? => U-Boot =>? OS
> 
>  ??????????????????????? TF-A (BL32)
> 
> 
> BL2 is authenticated by ROM code, with EDCSA support.
> 
> 
> I next OpenSTLinux release (and soon after in upstream) 
> STMicroelectronics will add FIP support
> 
> for STM32MP15x; TF-A FIP allows to boot Kernel after TF-A BL2 if you 
> want to skip U-Boot
> 
> TF-A (BL2) => FIP (OP-TEE + Kernel)
> 
> 
> And the FIP allow authentication with certificate for 'secured boot' 
> with a complete chain of trust.
> 
> https://trustedfirmware-a.readthedocs.io/en/latest/index.html
> 
> 
> So the ECDSA support in SPL for STM32MP15x will be not actively 
> supported by STMicroelectronics for product design.


The boot flow I'm working on will use an authenticated BL2 as well:

   ROM -> SPL(BL2) -> FIT(OP-TEE -> Linux)

I'm using this to boot to a 3D application very fast (a couple of 
seconds max). It's really cool. I even wrote a utility for signing SPL 
images for the ROM code to check [1].

I had looked at FIP images briefly a few months back. I didn't see any 
advantage over the FIT format. I also wanted to have as little code as 
possible, so avoiding TF-A made sense. There were also some major issues 
with syncing the clock tree between linux and TF-A. TF-A was a beautiful 
disaster. Maybe that changed, but given I have a working proof of 
concept, I doubt I'll be re-engineering the boot flow.

I realize there won't be any STM support for SPL. openstlinux seems to 
have moved away from SPL. I've gotten a lot of enthusiastic support from 
u-boot members, as a number of people seem to really like this chip 
(meself included).

Alex


[1] https://github.com/mrnuke/stm32mp-keygen

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 2/5] lib: ecdsa: Add skeleton to implement ecdsa verification in u-boot
  2021-02-09 15:11   ` Patrick DELAUNAY
@ 2021-02-09 22:37     ` Alex G.
  0 siblings, 0 replies; 17+ messages in thread
From: Alex G. @ 2021-02-09 22:37 UTC (permalink / raw)
  To: u-boot

Hi Patrick,

On 2/9/21 9:11 AM, Patrick DELAUNAY wrote:
> Hi,
> 
> On 1/11/21 4:41 PM, Alexandru Gagniuc wrote:
>> Prepare the source tree for accepting implementations of the ECDSA
>> algorithm. This patch deals with the boring aspects of Makefiles and
>> Kconfig files.
>>
>> Signed-off-by: Alexandru Gagniuc<mr.nuke.me@gmail.com>
>> ---
>> ? include/image.h????????? | 10 +++++-----
>> ? include/u-boot/rsa.h???? |? 2 +-
>> ? lib/Kconfig????????????? |? 1 +
>> ? lib/Makefile???????????? |? 1 +
>> ? lib/ecdsa/Kconfig??????? | 23 +++++++++++++++++++++++
>> ? lib/ecdsa/Makefile?????? |? 1 +
>> ? lib/ecdsa/ecdsa-verify.c | 13 +++++++++++++
>> ? 7 files changed, 45 insertions(+), 6 deletions(-)
>> ? create mode 100644 lib/ecdsa/Kconfig
>> ? create mode 100644 lib/ecdsa/Makefile
>> ? create mode 100644 lib/ecdsa/ecdsa-verify.c
>>
>> diff --git a/include/image.h b/include/image.h
>> index 6628173dca..1d70ba0ece 100644
>> --- a/include/image.h
>> +++ b/include/image.h
>> @@ -1198,20 +1198,20 @@ int calculate_hash(const void *data, int 
>> data_len, const char *algo,
>> ? #if defined(USE_HOSTCC)
>> ? # if defined(CONFIG_FIT_SIGNATURE)
>> ? #? define IMAGE_ENABLE_SIGN??? 1
>> -#? define IMAGE_ENABLE_VERIFY??? 1
>> +#? define IMAGE_ENABLE_VERIFY_RSA??? 1
>> ? #? define IMAGE_ENABLE_VERIFY_ECDSA??? 1
>> ? #? define FIT_IMAGE_ENABLE_VERIFY??? 1
>> ? #? include <openssl/evp.h>
>> ? # else
>> ? #? define IMAGE_ENABLE_SIGN??? 0
>> -#? define IMAGE_ENABLE_VERIFY??? 0
>> +#? define IMAGE_ENABLE_VERIFY_RSA??? 0
>> ? # define IMAGE_ENABLE_VERIFY_ECDSA??? 0
>> ? #? define FIT_IMAGE_ENABLE_VERIFY??? 0
>> ? # endif
>> ? #else
>> ? # define IMAGE_ENABLE_SIGN??? 0
>> -# define IMAGE_ENABLE_VERIFY??????? CONFIG_IS_ENABLED(RSA_VERIFY)
>> -# define IMAGE_ENABLE_VERIFY_ECDSA??? 0
>> +# define IMAGE_ENABLE_VERIFY_RSA??? CONFIG_IS_ENABLED(RSA_VERIFY)
>> +# define IMAGE_ENABLE_VERIFY_ECDSA??? CONFIG_IS_ENABLED(ECDSA_VERIFY)
> 
> here you are using CONFIG_IS_ENABLED.
> 
> This macro imply to test CONFIG_ECDSA_VERIFY or CONFIG_SPL_ECDSA_VERIFY 
> (for SPL build)
> 
> => but CONFIG_SPL_ECDSA_VERIFY is missing, I think you need to add it, 
> as RSA

This patch adds both "config ECDSA_VERIFY" and "config SPL_ECDSA_VERIFY"
see @lib/ecdsa/Kconfig. I believe this achieves what you need.

[snip]
>> diff --git a/lib/Makefile b/lib/Makefile
>> index cf64188ba5..ab86be2678 100644
>> --- a/lib/Makefile
>> +++ b/lib/Makefile
>> @@ -59,6 +59,7 @@ endif
>> ? obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi/
>> ? obj-$(CONFIG_$(SPL_)MD5) += md5.o
>> +obj-$(CONFIG_ECDSA) += ecdsa/
> 
> obj-$(CONFIG_$(SPL_)ECDSA) += ecdsa/

The intent here is to use CONFIG_ECDSA to denote ECDSA support. 
CONFIG_ECDSA_VERIFY and CONFIG_SPL_ECDSA_VERIFY are used to enable the 
code in u-boot and SPL respectively. Only verification is supported on 
the target, so these are the only switches that enable or disable code.

> 
>> ? obj-$(CONFIG_$(SPL_)RSA) += rsa/
>> ? obj-$(CONFIG_FIT_SIGNATURE) += hash-checksum.o
>> ? obj-$(CONFIG_SHA1) += sha1.o
>> diff --git a/lib/ecdsa/Kconfig b/lib/ecdsa/Kconfig
>> new file mode 100644
>> index 0000000000..1244d6b6ea
>> --- /dev/null
>> +++ b/lib/ecdsa/Kconfig
>> @@ -0,0 +1,23 @@
>> +config ECDSA
>> +??? bool "Enable ECDSA support"
>> +??? depends on DM
>> +??? help
>> +????? This enables the ECDSA algorithm for FIT image verification in 
>> U-Boot.
>> +????? See doc/uImage.FIT/signature.txt for more details.
>> +????? The ECDSA algorithm is implemented using the driver model. So
>> +????? CONFIG_DM is required by this library.
>> +????? ECDSA is enabled for mkimage regardless of this? option.
>> +
>> +if ECDSA
>> +
> 
> Add CONFIG_SPL_ECDSA to select independently support in SPL et/or in U-Boot
> as it is done for RSA
> 
> + config SPL_ECDSA
> +??? bool "Use ECDSA library within in SPL"
> 
I though about an SPL_ECDSA kconfig. As mentioned above, we have 
independent switches to enable the code for u-boot/SPL. We can enable 
ECDSA support in u-boot, SPL, neither or both. What would this switch add?

> 
>> +config ECDSA_VERIFY
>> +??? bool "Enable ECDSA verification support in U-Boot."
> 
> 
> + select SPL_ECDSA
> 
> 
>> +??? help
>> +????? Allow ECDSA signatures to be recognized and verified in U-Boot.
>> +
>> +config SPL_ECDSA_VERIFY
>> +??? bool "Enable ECDSA verification support in SPL"
>> +??? help
>> +????? Allow ECDSA signatures to be recognized and verified in SPL.

This is the switch for SPL (@mentioned earlier).


Alex

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 3/5] lib: ecdsa: Implement signature verification for crypto_algo API
  2021-02-09 15:56   ` Patrick DELAUNAY
@ 2021-02-09 22:58     ` Alex G.
  0 siblings, 0 replies; 17+ messages in thread
From: Alex G. @ 2021-02-09 22:58 UTC (permalink / raw)
  To: u-boot


On 2/9/21 9:56 AM, Patrick DELAUNAY wrote:
> Hi,

[snip]

>> 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>
>> ?? */
> 
> http://www.denx.de/wiki/U-Boot/CodingStyle #Include files
> 
> #include <crypto/ecdsa-uclass.h>
> 
> it is normally the first in alphabetic order of directory

Thank your for catching that. I will have it fixed in the next iteration 
of this series.

>> +#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;
>> +}
>> +
> 
> 
> To prepare the future can you parse a array of supported curves with 
> associated ID
> 
> used as parameter of ECDSA parameter = enum ECDSA_CURVES
> 
> for example: char * name, int size, enum ECDSA_CURVES
> 
> const [] = {
> {"prime256v1", 256, ECDSA_PRIME256V1 },
> 
> }

That is possible. If I were to have a longer list of curve names, I 
change things to extract the key length from the name itself. So instead 
of running strncmp() of N keyname strings, I would extract the digits 
from 'curve_name'.

I chose not to do that here because I want this patch to be didactic. 
That is, I'm trying to achieve the goal clearly, with the lowest number 
of lines of code.

[snip]

>> +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);
> 
> 
> Need to indicate the used curve here as parameter of the verify opts ?

The curve name is part of the key (struct ecdsa_public_key).


[snip]
>> +??????? ret = ops->verify(dev, &key, hash, algo->checksum_len,
>> +????????????????? sig, sig_len);
>> +
>> +??????? /* On success, don't worry about remaining keys */
>> +??????? if (ret == 0)
> 
> 
> issue raised by chekpatch I think
> 
> if (!ret)

Oh! I'll get this fixed. Thanks!

Alex

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2021-02-09 22:58 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 3/5] lib: ecdsa: Implement signature verification for crypto_algo API Alexandru Gagniuc
2021-01-13 16:10   ` 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.

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.