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

This series is Part II of the ECDSA saga. It applies on top of [1]:
 * [PATCH v6 00/11] Add support for ECDSA image signing

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 possible, 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.

Changes since v1:
  - Add test to make sure the UCLASS is enabled
  - Fix check against wrong sig_len in ecdsa_romapi.c
  - s/U_BOOT_DEVICE/U_BOOT_DRVINFO/
  - Use "if(!ret)" instead of "if (ret == 0)"
  - Use uclass_first_device_err() instead of uclass_first_device()
  - Make sure #includes are correctly alphabetized

Alexandru Gagniuc (6):
  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
  test: dm: Add test for ECDSA UCLASS support

 arch/arm/mach-stm32mp/Kconfig        |  10 ++-
 arch/arm/mach-stm32mp/Makefile       |   1 +
 arch/arm/mach-stm32mp/ecdsa_romapi.c | 106 ++++++++++++++++++++++
 common/Kconfig.boot                  |   8 +-
 configs/sandbox_defconfig            |   2 +
 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 +++++++++++++++++++++++++++
 test/dm/Makefile                     |   1 +
 test/dm/ecdsa.c                      |  38 ++++++++
 16 files changed, 361 insertions(+), 11 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
 create mode 100644 test/dm/ecdsa.c

-- 
2.26.2

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

* [PATCH v2 1/6] dm: crypto: Define UCLASS API for ECDSA signature verification
  2021-03-16  0:24 [PATCH v2 0/6] Enable ECDSA FIT verification for stm32mp Alexandru Gagniuc
@ 2021-03-16  0:24 ` Alexandru Gagniuc
  2021-03-29  7:43   ` Simon Glass
  2021-03-16  0:24 ` [PATCH v2 2/6] lib: ecdsa: Add skeleton to implement ecdsa verification in u-boot Alexandru Gagniuc
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 19+ messages in thread
From: Alexandru Gagniuc @ 2021-03-16  0:24 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 d75de368c5..f335f4e5a4 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -47,6 +47,7 @@ enum uclass_id {
 	UCLASS_DSI_HOST,	/* Display Serial Interface host */
 	UCLASS_DMA,		/* Direct Memory Access */
 	UCLASS_DSA,		/* Distributed (Ethernet) Switch Architecture */
+	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] 19+ messages in thread

* [PATCH v2 2/6] lib: ecdsa: Add skeleton to implement ecdsa verification in u-boot
  2021-03-16  0:24 [PATCH v2 0/6] Enable ECDSA FIT verification for stm32mp Alexandru Gagniuc
  2021-03-16  0:24 ` [PATCH v2 1/6] dm: crypto: Define UCLASS API for ECDSA signature verification Alexandru Gagniuc
@ 2021-03-16  0:24 ` Alexandru Gagniuc
  2021-03-29  7:43   ` Simon Glass
  2021-03-16  0:24 ` [PATCH v2 3/6] lib: ecdsa: Implement signature verification for crypto_algo API Alexandru Gagniuc
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 19+ messages in thread
From: Alexandru Gagniuc @ 2021-03-16  0:24 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 b5bcf08e61..800d981f03 100644
--- a/include/image.h
+++ b/include/image.h
@@ -1219,20 +1219,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
 
@@ -1288,7 +1288,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 7288340614..48895e4e4f 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -295,6 +295,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 1d4b7d3aad..de55914f52 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] 19+ messages in thread

* [PATCH v2 3/6] lib: ecdsa: Implement signature verification for crypto_algo API
  2021-03-16  0:24 [PATCH v2 0/6] Enable ECDSA FIT verification for stm32mp Alexandru Gagniuc
  2021-03-16  0:24 ` [PATCH v2 1/6] dm: crypto: Define UCLASS API for ECDSA signature verification Alexandru Gagniuc
  2021-03-16  0:24 ` [PATCH v2 2/6] lib: ecdsa: Add skeleton to implement ecdsa verification in u-boot Alexandru Gagniuc
@ 2021-03-16  0:24 ` Alexandru Gagniuc
  2021-03-16  0:24 ` [PATCH v2 4/6] arm: stm32mp1: Implement ECDSA signature verification Alexandru Gagniuc
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 19+ messages in thread
From: Alexandru Gagniuc @ 2021-03-16  0:24 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>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
 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..3e55b14497 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 <crypto/ecdsa-uclass.h>
+#include <dm/uclass.h>
 #include <u-boot/ecdsa.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)
+			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_err(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] 19+ messages in thread

* [PATCH v2 4/6] arm: stm32mp1: Implement ECDSA signature verification
  2021-03-16  0:24 [PATCH v2 0/6] Enable ECDSA FIT verification for stm32mp Alexandru Gagniuc
                   ` (2 preceding siblings ...)
  2021-03-16  0:24 ` [PATCH v2 3/6] lib: ecdsa: Implement signature verification for crypto_algo API Alexandru Gagniuc
@ 2021-03-16  0:24 ` Alexandru Gagniuc
  2021-03-16  0:24 ` [PATCH v2 5/6] Kconfig: FIT_SIGNATURE should not select RSA_VERIFY Alexandru Gagniuc
  2021-03-16  0:24 ` [PATCH v2 6/6] test: dm: Add test for ECDSA UCLASS support Alexandru Gagniuc
  5 siblings, 0 replies; 19+ messages in thread
From: Alexandru Gagniuc @ 2021-03-16  0:24 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        |  10 ++-
 arch/arm/mach-stm32mp/Makefile       |   1 +
 arch/arm/mach-stm32mp/ecdsa_romapi.c | 106 +++++++++++++++++++++++++++
 3 files changed, 116 insertions(+), 1 deletion(-)
 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 079d66a80c..fa58cffd1d 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_STM32KEY
 	bool "command stm32key to fuse public key hash"
 	default y
@@ -160,7 +169,6 @@ config DEBUG_UART_CLOCK
 	default 64000000
 endif
 
-source "arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig"
 source "board/st/stm32mp1/Kconfig"
 source "board/dhelectronics/dh_stm32mp1/Kconfig"
 
diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile
index aa39867080..0942092d8e 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-y += 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..ca32925a12
--- /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 != 64 || 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_DRVINFO(stm32mp_rom_api_ecdsa) = {
+	.name = "stm32mp_rom_api_ecdsa",
+};
-- 
2.26.2

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

* [PATCH v2 5/6] Kconfig: FIT_SIGNATURE should not select RSA_VERIFY
  2021-03-16  0:24 [PATCH v2 0/6] Enable ECDSA FIT verification for stm32mp Alexandru Gagniuc
                   ` (3 preceding siblings ...)
  2021-03-16  0:24 ` [PATCH v2 4/6] arm: stm32mp1: Implement ECDSA signature verification Alexandru Gagniuc
@ 2021-03-16  0:24 ` Alexandru Gagniuc
  2021-03-16  0:24 ` [PATCH v2 6/6] test: dm: Add test for ECDSA UCLASS support Alexandru Gagniuc
  5 siblings, 0 replies; 19+ messages in thread
From: Alexandru Gagniuc @ 2021-03-16  0:24 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>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
 common/Kconfig.boot | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/common/Kconfig.boot b/common/Kconfig.boot
index 9c335f4f8c..788c287da2 100644
--- a/common/Kconfig.boot
+++ b/common/Kconfig.boot
@@ -76,8 +76,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
 	select FIT_FULL_CHECK
 	help
@@ -186,8 +186,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
 	select SPL_FIT_FULL_CHECK
 
-- 
2.26.2

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

* [PATCH v2 6/6] test: dm: Add test for ECDSA UCLASS support
  2021-03-16  0:24 [PATCH v2 0/6] Enable ECDSA FIT verification for stm32mp Alexandru Gagniuc
                   ` (4 preceding siblings ...)
  2021-03-16  0:24 ` [PATCH v2 5/6] Kconfig: FIT_SIGNATURE should not select RSA_VERIFY Alexandru Gagniuc
@ 2021-03-16  0:24 ` Alexandru Gagniuc
  2021-03-29  7:43   ` Simon Glass
  5 siblings, 1 reply; 19+ messages in thread
From: Alexandru Gagniuc @ 2021-03-16  0:24 UTC (permalink / raw)
  To: u-boot

This test verifies that ECDSA_UCLASS is implemented, and that
ecdsa_verify() works as expected. The definition of "expected" is
"does not find a device, and returns -ENODEV".

The lack of a hardware-independent ECDSA implementation prevents us
from having one in the sandbox, for now.

Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
 configs/sandbox_defconfig |  2 ++
 test/dm/Makefile          |  1 +
 test/dm/ecdsa.c           | 38 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 41 insertions(+)
 create mode 100644 test/dm/ecdsa.c

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 5bc90d09a8..bb73cab18d 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -283,3 +283,5 @@ CONFIG_TEST_FDTDEC=y
 CONFIG_UNIT_TEST=y
 CONFIG_UT_TIME=y
 CONFIG_UT_DM=y
+CONFIG_ECDSA=y
+CONFIG_ECDSA_VERIFY=y
diff --git a/test/dm/Makefile b/test/dm/Makefile
index fd1455109d..7d1870f941 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_CLK) += clk.o clk_ccf.o
 obj-$(CONFIG_CROS_EC) += cros_ec.o
 obj-$(CONFIG_DEVRES) += devres.o
 obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi_host.o
+obj-$(CONFIG_ECDSA_VERIFY) += ecdsa.o
 obj-$(CONFIG_DM_ETH) += eth.o
 obj-$(CONFIG_FIRMWARE) += firmware.o
 obj-$(CONFIG_DM_GPIO) += gpio.o
diff --git a/test/dm/ecdsa.c b/test/dm/ecdsa.c
new file mode 100644
index 0000000000..23d57dd47f
--- /dev/null
+++ b/test/dm/ecdsa.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <crypto/ecdsa-uclass.h>
+#include <dm.h>
+#include <dm/test.h>
+#include <test/ut.h>
+#include <u-boot/ecdsa.h>
+
+/*
+ * Basic test of the ECDSA uclass and ecdsa_verify()
+ *
+ * ECDSA implementations in u-boot are hardware-dependent. Until we have a
+ * software implementation that can be compiled into the sandbox, all we can
+ * test is the uclass support.
+ *
+ * The uclass_get() test is redundant since ecdsa_verify() would also fail. We
+ * run both functions in order to isolate the cause more clearly. i.e. is
+ * ecdsa_verify() failing because the UCLASS is absent/broken?
+ */
+static int dm_test_ecdsa_verify(struct unit_test_state *uts)
+{
+	const struct ecdsa_ops *ops;
+	struct uclass *ucp;
+
+	const struct checksum_algo algo = {
+		.checksum_len = 256,
+	};
+
+	struct image_sign_info info = {
+		.checksum = &algo,
+	};
+
+	ut_assertok(uclass_get(UCLASS_ECDSA, &ucp));
+	ut_assertnonnull(ucp);
+	ut_assert(ecdsa_verify(&info, NULL, 0, NULL, 0) == -ENODEV);
+	return 0;
+}
+DM_TEST(dm_test_ecdsa_verify, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
-- 
2.26.2

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

* [PATCH v2 2/6] lib: ecdsa: Add skeleton to implement ecdsa verification in u-boot
  2021-03-16  0:24 ` [PATCH v2 2/6] lib: ecdsa: Add skeleton to implement ecdsa verification in u-boot Alexandru Gagniuc
@ 2021-03-29  7:43   ` Simon Glass
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2021-03-29  7:43 UTC (permalink / raw)
  To: u-boot

Hi Alexandru,

On Tue, 16 Mar 2021 at 13:24, Alexandru Gagniuc <mr.nuke.me@gmail.com> 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 b5bcf08e61..800d981f03 100644
> --- a/include/image.h
> +++ b/include/image.h
> @@ -1219,20 +1219,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
>
> @@ -1288,7 +1288,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 7288340614..48895e4e4f 100644
> --- a/lib/Kconfig
> +++ b/lib/Kconfig
> @@ -295,6 +295,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 1d4b7d3aad..de55914f52 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.

drop extra space before option

Can you write out ECDSA in full once, briefly mention what it is and
perhaps a link to more info?

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

Regards,Simon

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

* [PATCH v2 6/6] test: dm: Add test for ECDSA UCLASS support
  2021-03-16  0:24 ` [PATCH v2 6/6] test: dm: Add test for ECDSA UCLASS support Alexandru Gagniuc
@ 2021-03-29  7:43   ` Simon Glass
  2021-03-29 18:42     ` Alex G.
  0 siblings, 1 reply; 19+ messages in thread
From: Simon Glass @ 2021-03-29  7:43 UTC (permalink / raw)
  To: u-boot

Hi Alexandru,

On Tue, 16 Mar 2021 at 13:24, Alexandru Gagniuc <mr.nuke.me@gmail.com> wrote:
>
> This test verifies that ECDSA_UCLASS is implemented, and that
> ecdsa_verify() works as expected. The definition of "expected" is
> "does not find a device, and returns -ENODEV".
>
> The lack of a hardware-independent ECDSA implementation prevents us
> from having one in the sandbox, for now.

Yes we do need a software impl at some point. Any update on that?

>
> Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
> ---
>  configs/sandbox_defconfig |  2 ++
>  test/dm/Makefile          |  1 +
>  test/dm/ecdsa.c           | 38 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 41 insertions(+)
>  create mode 100644 test/dm/ecdsa.c
>

Regards,
Simon

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

* [PATCH v2 1/6] dm: crypto: Define UCLASS API for ECDSA signature verification
  2021-03-16  0:24 ` [PATCH v2 1/6] dm: crypto: Define UCLASS API for ECDSA signature verification Alexandru Gagniuc
@ 2021-03-29  7:43   ` Simon Glass
  2021-03-29 23:03     ` Alex G.
  0 siblings, 1 reply; 19+ messages in thread
From: Simon Glass @ 2021-03-29  7:43 UTC (permalink / raw)
  To: u-boot

Hi Alexandru,

On Tue, 16 Mar 2021 at 13:24, 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
>
> 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

What is the format of this? I think a better API would be to have a struct here.

> +        * @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 d75de368c5..f335f4e5a4 100644
> --- a/include/dm/uclass-id.h
> +++ b/include/dm/uclass-id.h
> @@ -47,6 +47,7 @@ enum uclass_id {
>         UCLASS_DSI_HOST,        /* Display Serial Interface host */
>         UCLASS_DMA,             /* Direct Memory Access */
>         UCLASS_DSA,             /* Distributed (Ethernet) Switch Architecture */
> +       UCLASS_ECDSA,           /* Elliptic curve cryptographic device */
>         UCLASS_EFI,             /* EFI managed devices */
>         UCLASS_ETH,             /* Ethernet device */
>         UCLASS_ETH_PHY,         /* Ethernet PHY device */
> --
> 2.26.2
>

Regards,
Simon

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

* [PATCH v2 6/6] test: dm: Add test for ECDSA UCLASS support
  2021-03-29  7:43   ` Simon Glass
@ 2021-03-29 18:42     ` Alex G.
  2021-03-30 18:27       ` [EXTERNAL] " Tim Romanski
  0 siblings, 1 reply; 19+ messages in thread
From: Alex G. @ 2021-03-29 18:42 UTC (permalink / raw)
  To: u-boot

+ Tim

On 3/29/21 2:43 AM, Simon Glass wrote:
> Hi Alexandru,
> 
> On Tue, 16 Mar 2021 at 13:24, Alexandru Gagniuc <mr.nuke.me@gmail.com> wrote:
>>
>> This test verifies that ECDSA_UCLASS is implemented, and that
>> ecdsa_verify() works as expected. The definition of "expected" is
>> "does not find a device, and returns -ENODEV".
>>
>> The lack of a hardware-independent ECDSA implementation prevents us
>> from having one in the sandbox, for now.
> 
> Yes we do need a software impl at some point. Any update on that?

I don't have any updates from Tim that you don't. I assume he's still 
silently hacking at it.

Alex

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

* [PATCH v2 1/6] dm: crypto: Define UCLASS API for ECDSA signature verification
  2021-03-29  7:43   ` Simon Glass
@ 2021-03-29 23:03     ` Alex G.
  0 siblings, 0 replies; 19+ messages in thread
From: Alex G. @ 2021-03-29 23:03 UTC (permalink / raw)
  To: u-boot



On 3/29/21 2:43 AM, Simon Glass wrote:
> Hi Alexandru,
> 
> On Tue, 16 Mar 2021 at 13:24, 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
>>
>> 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
> 
> What is the format of this? I think a better API would be to have a struct here.

It's the raw format, which is the R, and S points. It's the same format 
used by pycryptodomex, and inside the FIT. see ecdsa_sig_encode_raw() in 
the other series ("v6: Add support for ECDSA image signing")
I don't know if it's a good idea to split up the R,S points since the 
verify step(both pycryptodomex and stm32) uses this concatenated format. 
Then the implementation would have to memcpy R and S to a buffer.

Alex

>> +        * @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 d75de368c5..f335f4e5a4 100644
>> --- a/include/dm/uclass-id.h
>> +++ b/include/dm/uclass-id.h
>> @@ -47,6 +47,7 @@ enum uclass_id {
>>          UCLASS_DSI_HOST,        /* Display Serial Interface host */
>>          UCLASS_DMA,             /* Direct Memory Access */
>>          UCLASS_DSA,             /* Distributed (Ethernet) Switch Architecture */
>> +       UCLASS_ECDSA,           /* Elliptic curve cryptographic device */
>>          UCLASS_EFI,             /* EFI managed devices */
>>          UCLASS_ETH,             /* Ethernet device */
>>          UCLASS_ETH_PHY,         /* Ethernet PHY device */
>> --
>> 2.26.2
>>
> 
> Regards,
> Simon
> 

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

* [EXTERNAL] Re: [PATCH v2 6/6] test: dm: Add test for ECDSA UCLASS support
  2021-03-29 18:42     ` Alex G.
@ 2021-03-30 18:27       ` Tim Romanski
  2021-04-07 17:29         ` Tim Romanski
  0 siblings, 1 reply; 19+ messages in thread
From: Tim Romanski @ 2021-03-30 18:27 UTC (permalink / raw)
  To: u-boot

On 3/30/21 2:17PM, Alexandru Gagniuc <mr.nuke.me@gmail.com> wrote:
> I don't have any updates from Tim that you don't. I assume he's still silently hacking at it.

Yep, I'm working on a software implementation of ECDSA. Currently have the OpenSSL implementation for the nistp256 curve isolated, debugging a test program that verifies a signature on data that was randomly generated, then will need to clean up unnecessary code and fit it into U-Boot.

CC'd my @linux.microsoft.com email, I prefer to use that one from now on.

All the best,
Tim

-----Original Message-----
From: Alex G. <mr.nuke.me@gmail.com> 
Sent: March 29, 2021 2:43 PM
To: Simon Glass <sjg@chromium.org>
Cc: U-Boot Mailing List <u-boot@lists.denx.de>; Tom Rini <trini@konsulko.com>; Tim Romanski <t-tromanski@microsoft.com>
Subject: [EXTERNAL] Re: [PATCH v2 6/6] test: dm: Add test for ECDSA UCLASS support

+ Tim

On 3/29/21 2:43 AM, Simon Glass wrote:
> Hi Alexandru,
> 
> On Tue, 16 Mar 2021 at 13:24, Alexandru Gagniuc <mr.nuke.me@gmail.com> wrote:
>>
>> This test verifies that ECDSA_UCLASS is implemented, and that
>> ecdsa_verify() works as expected. The definition of "expected" is 
>> "does not find a device, and returns -ENODEV".
>>
>> The lack of a hardware-independent ECDSA implementation prevents us 
>> from having one in the sandbox, for now.
> 
> Yes we do need a software impl at some point. Any update on that?

I don't have any updates from Tim that you don't. I assume he's still silently hacking at it.

Alex

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

* [EXTERNAL] Re: [PATCH v2 6/6] test: dm: Add test for ECDSA UCLASS support
  2021-03-30 18:27       ` [EXTERNAL] " Tim Romanski
@ 2021-04-07 17:29         ` Tim Romanski
  2021-04-07 20:03           ` Alex G.
  0 siblings, 1 reply; 19+ messages in thread
From: Tim Romanski @ 2021-04-07 17:29 UTC (permalink / raw)
  To: u-boot

Update on current progress on U-Boot ECDSA verification: I've isolated 
the OpenSSL code required to verify a signature signed with the 
nistp256v1 curve, and I've written a small test program to show that the 
code works without any external dependencies [1]. Currently fitting the 
code into Alex's fork of U-Boot.

Question for Alex, I see your repo has a few branches related to ECDSA 
(patch-ecdsa-v[1-5], patch-mkimage-keyfile-v{1,2}). You sent me a link 
to 'patch-ecdsa-v1' in a previous email, is that the one that's being 
upstreamed? Should I be working off a different branch or is that one ok?

Tim

[1] https://github.com/timr11/openssl-ecdsa-verify

On 2021-03-30 2:27 p.m., Tim Romanski wrote:
> On 3/30/21 2:17PM, Alexandru Gagniuc <mr.nuke.me@gmail.com> wrote:
>> I don't have any updates from Tim that you don't. I assume he's still silently hacking at it.
> Yep, I'm working on a software implementation of ECDSA. Currently have the OpenSSL implementation for the nistp256 curve isolated, debugging a test program that verifies a signature on data that was randomly generated, then will need to clean up unnecessary code and fit it into U-Boot.
>
> CC'd my @linux.microsoft.com email, I prefer to use that one from now on.
>
> All the best,
> Tim
>
> -----Original Message-----
> From: Alex G. <mr.nuke.me@gmail.com>
> Sent: March 29, 2021 2:43 PM
> To: Simon Glass <sjg@chromium.org>
> Cc: U-Boot Mailing List <u-boot@lists.denx.de>; Tom Rini <trini@konsulko.com>; Tim Romanski <t-tromanski@microsoft.com>
> Subject: [EXTERNAL] Re: [PATCH v2 6/6] test: dm: Add test for ECDSA UCLASS support
>
> + Tim
>
> On 3/29/21 2:43 AM, Simon Glass wrote:
>> Hi Alexandru,
>>
>> On Tue, 16 Mar 2021 at 13:24, Alexandru Gagniuc <mr.nuke.me@gmail.com> wrote:
>>> This test verifies that ECDSA_UCLASS is implemented, and that
>>> ecdsa_verify() works as expected. The definition of "expected" is
>>> "does not find a device, and returns -ENODEV".
>>>
>>> The lack of a hardware-independent ECDSA implementation prevents us
>>> from having one in the sandbox, for now.
>> Yes we do need a software impl at some point. Any update on that?
> I don't have any updates from Tim that you don't. I assume he's still silently hacking at it.
>
> Alex

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

* [EXTERNAL] Re: [PATCH v2 6/6] test: dm: Add test for ECDSA UCLASS support
  2021-04-07 17:29         ` Tim Romanski
@ 2021-04-07 20:03           ` Alex G.
  2021-04-08 16:56             ` Tim Romanski
  0 siblings, 1 reply; 19+ messages in thread
From: Alex G. @ 2021-04-07 20:03 UTC (permalink / raw)
  To: u-boot

On 4/7/21 12:29 PM, Tim Romanski wrote:

> Question for Alex, I see your repo has a few branches related to ECDSA 
> (patch-ecdsa-v[1-5], patch-mkimage-keyfile-v{1,2}). You sent me a link 
> to 'patch-ecdsa-v1' in a previous email, is that the one that's being 
> upstreamed? Should I be working off a different branch or is that one ok?

I'm up to v6 on the patch submission. The differences are not that big, 
but I recommend sticking to the latest.

Alex

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

* [EXTERNAL] Re: [PATCH v2 6/6] test: dm: Add test for ECDSA UCLASS support
  2021-04-07 20:03           ` Alex G.
@ 2021-04-08 16:56             ` Tim Romanski
  2021-04-08 17:05               ` Alex G.
  2021-04-23 17:03               ` Tim Romanski
  0 siblings, 2 replies; 19+ messages in thread
From: Tim Romanski @ 2021-04-08 16:56 UTC (permalink / raw)
  To: u-boot

Ok, will do. I'm writing the verification code, I noticed you're passing 
the public key into the fdt using fdt_add_bignum, which converts the x 
and y values into big endian integer arrays. Do you have a method to 
read these values from the fdt and convert them back into bignums, or is 
that TODO? I can get that done if it's not yet implemented.

All the best,

Tim

On 2021-04-07 4:03 p.m., Alex G. wrote:
> On 4/7/21 12:29 PM, Tim Romanski wrote:
>
>> Question for Alex, I see your repo has a few branches related to 
>> ECDSA (patch-ecdsa-v[1-5], patch-mkimage-keyfile-v{1,2}). You sent me 
>> a link to 'patch-ecdsa-v1' in a previous email, is that the one 
>> that's being upstreamed? Should I be working off a different branch 
>> or is that one ok?
>
> I'm up to v6 on the patch submission. The differences are not that 
> big, but I recommend sticking to the latest.
>
> Alex

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

* [EXTERNAL] Re: [PATCH v2 6/6] test: dm: Add test for ECDSA UCLASS support
  2021-04-08 16:56             ` Tim Romanski
@ 2021-04-08 17:05               ` Alex G.
  2021-04-23 17:03               ` Tim Romanski
  1 sibling, 0 replies; 19+ messages in thread
From: Alex G. @ 2021-04-08 17:05 UTC (permalink / raw)
  To: u-boot

On 4/8/21 11:56 AM, Tim Romanski wrote:
> Ok, will do. I'm writing the verification code, I noticed you're passing 
> the public key into the fdt using fdt_add_bignum, which converts the x 
> and y values into big endian integer arrays. Do you have a method to 
> read these values from the fdt and convert them back into bignums, or is 
> that TODO? I can get that done if it's not yet implemented.

Because u-boot proper doesn't use openssl, there hasn't been a need to 
convert data into types such as BIGNUM* at runtime. You could check 
BN_bin2bn() for inspiration.

Alex

> All the best,
> 
> Tim
> 
> On 2021-04-07 4:03 p.m., Alex G. wrote:
>> On 4/7/21 12:29 PM, Tim Romanski wrote:
>>
>>> Question for Alex, I see your repo has a few branches related to 
>>> ECDSA (patch-ecdsa-v[1-5], patch-mkimage-keyfile-v{1,2}). You sent me 
>>> a link to 'patch-ecdsa-v1' in a previous email, is that the one 
>>> that's being upstreamed? Should I be working off a different branch 
>>> or is that one ok?
>>
>> I'm up to v6 on the patch submission. The differences are not that 
>> big, but I recommend sticking to the latest.
>>
>> Alex

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

* [EXTERNAL] Re: [PATCH v2 6/6] test: dm: Add test for ECDSA UCLASS support
  2021-04-08 16:56             ` Tim Romanski
  2021-04-08 17:05               ` Alex G.
@ 2021-04-23 17:03               ` Tim Romanski
  2021-04-24 13:30                 ` Tom Rini
  1 sibling, 1 reply; 19+ messages in thread
From: Tim Romanski @ 2021-04-23 17:03 UTC (permalink / raw)
  To: u-boot

Update on ECDSA verification progress, I've forked Alex's repo and have 
included my changes in the 'ecdsa-vrf-1' branch [1]. This includes the 
isolated OpenSSL code for verification, and I split up the 
lib/ecdsa/ecdsa-libcrypto.c file into lib/ecdsa/ecdsa-sign.c and 
lib/ecdsa/ecdsa-verify.c. I've also included unit tests under 
test/py/tests/test_vboot_ecdsa.py, which test ECDSA with the sha1 and 
sha256 digest algos. There are some outstanding changes to be made 
before it's ready for review, mainly cleaning up the OpenSSL code as it 
has redundant code still included though it works without any additional 
dependencies, and better integration with U-Boot's build system. 
Currently I've added a new Kconfig setting to turn on ECDSA 
signing/verification called "CONFIG_FIT_SIGNATURE_ECDSA" in 
common/Kconfig.boot which sets config options "CONFIG_ECDSA" and 
"CONFIG_ECDSA_VERIFY". This is done mainly to replicate how the RSA 
config was setup, though creating "CONFIG_FIT_SIGNATURE_ECDSA" separate 
from "CONFIG_FIT_SIGNATURE" feels messy, there's probably a better approach.

Today is also my last day at my internship. Deskin, a team member of 
mine at Microsoft who was keeping an eye on the project, will be the 
main point of contact from here (deskinm at linux.microsoft.com) though I 
can also be reached at timromanski at gmail.com (CC'd) and will be 
responsive if there are any questions.

All the best,

Tim

[1] timr11/u-boot: u-boot + elliptic curve verification (github.com) 
<https://github.com/timr11/u-boot>

On 2021-04-08 12:56 p.m., Tim Romanski wrote:
> Ok, will do. I'm writing the verification code, I noticed you're 
> passing the public key into the fdt using fdt_add_bignum, which 
> converts the x and y values into big endian integer arrays. Do you 
> have a method to read these values from the fdt and convert them back 
> into bignums, or is that TODO? I can get that done if it's not yet 
> implemented.
>
> All the best,
>
> Tim
>
> On 2021-04-07 4:03 p.m., Alex G. wrote:
>> On 4/7/21 12:29 PM, Tim Romanski wrote:
>>
>>> Question for Alex, I see your repo has a few branches related to 
>>> ECDSA (patch-ecdsa-v[1-5], patch-mkimage-keyfile-v{1,2}). You sent 
>>> me a link to 'patch-ecdsa-v1' in a previous email, is that the one 
>>> that's being upstreamed? Should I be working off a different branch 
>>> or is that one ok?
>>
>> I'm up to v6 on the patch submission. The differences are not that 
>> big, but I recommend sticking to the latest.
>>
>> Alex

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

* [EXTERNAL] Re: [PATCH v2 6/6] test: dm: Add test for ECDSA UCLASS support
  2021-04-23 17:03               ` Tim Romanski
@ 2021-04-24 13:30                 ` Tom Rini
  0 siblings, 0 replies; 19+ messages in thread
From: Tom Rini @ 2021-04-24 13:30 UTC (permalink / raw)
  To: u-boot

On Fri, Apr 23, 2021 at 01:03:25PM -0400, Tim Romanski wrote:

> Update on ECDSA verification progress, I've forked Alex's repo and have
> included my changes in the 'ecdsa-vrf-1' branch [1]. This includes the
> isolated OpenSSL code for verification, and I split up the
> lib/ecdsa/ecdsa-libcrypto.c file into lib/ecdsa/ecdsa-sign.c and
> lib/ecdsa/ecdsa-verify.c. I've also included unit tests under
> test/py/tests/test_vboot_ecdsa.py, which test ECDSA with the sha1 and sha256
> digest algos. There are some outstanding changes to be made before it's
> ready for review, mainly cleaning up the OpenSSL code as it has redundant
> code still included though it works without any additional dependencies, and
> better integration with U-Boot's build system. Currently I've added a new
> Kconfig setting to turn on ECDSA signing/verification called
> "CONFIG_FIT_SIGNATURE_ECDSA" in common/Kconfig.boot which sets config
> options "CONFIG_ECDSA" and "CONFIG_ECDSA_VERIFY". This is done mainly to
> replicate how the RSA config was setup, though creating
> "CONFIG_FIT_SIGNATURE_ECDSA" separate from "CONFIG_FIT_SIGNATURE" feels
> messy, there's probably a better approach.
> 
> Today is also my last day at my internship. Deskin, a team member of mine at
> Microsoft who was keeping an eye on the project, will be the main point of
> contact from here (deskinm at linux.microsoft.com) though I can also be reached
> at timromanski at gmail.com (CC'd) and will be responsive if there are any
> questions.
> 
> All the best,

Thanks for all your effort on this!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210424/7033f20e/attachment.sig>

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

end of thread, other threads:[~2021-04-24 13:30 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-16  0:24 [PATCH v2 0/6] Enable ECDSA FIT verification for stm32mp Alexandru Gagniuc
2021-03-16  0:24 ` [PATCH v2 1/6] dm: crypto: Define UCLASS API for ECDSA signature verification Alexandru Gagniuc
2021-03-29  7:43   ` Simon Glass
2021-03-29 23:03     ` Alex G.
2021-03-16  0:24 ` [PATCH v2 2/6] lib: ecdsa: Add skeleton to implement ecdsa verification in u-boot Alexandru Gagniuc
2021-03-29  7:43   ` Simon Glass
2021-03-16  0:24 ` [PATCH v2 3/6] lib: ecdsa: Implement signature verification for crypto_algo API Alexandru Gagniuc
2021-03-16  0:24 ` [PATCH v2 4/6] arm: stm32mp1: Implement ECDSA signature verification Alexandru Gagniuc
2021-03-16  0:24 ` [PATCH v2 5/6] Kconfig: FIT_SIGNATURE should not select RSA_VERIFY Alexandru Gagniuc
2021-03-16  0:24 ` [PATCH v2 6/6] test: dm: Add test for ECDSA UCLASS support Alexandru Gagniuc
2021-03-29  7:43   ` Simon Glass
2021-03-29 18:42     ` Alex G.
2021-03-30 18:27       ` [EXTERNAL] " Tim Romanski
2021-04-07 17:29         ` Tim Romanski
2021-04-07 20:03           ` Alex G.
2021-04-08 16:56             ` Tim Romanski
2021-04-08 17:05               ` Alex G.
2021-04-23 17:03               ` Tim Romanski
2021-04-24 13:30                 ` Tom Rini

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.