mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v3 0/2] Allow generating MAC addresses from machine ID
@ 2023-11-22  9:47 Uwe Kleine-König
  2023-11-22  9:47 ` [PATCH v3 1/2] common: machine_id: support deriving app specific UUIDs Uwe Kleine-König
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Uwe Kleine-König @ 2023-11-22  9:47 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Ahmad Fatoum, Alexander Shiyan, Thorsten Scherer, Ahmad Fatoum, barebox

Hello,

On Tue, Nov 21, 2023 at 09:33:58AM +0100, Sascha Hauer wrote:
> This series neither applies to master nor to next, please resend

here is the rebased series. Applies to current next. There are no other
changes.

Best regards
Uwe

Ahmad Fatoum (2):
  common: machine_id: support deriving app specific UUIDs
  net: add generic MAC address derivation from machine ID

 common/machine_id.c  | 83 +++++++++++++++++++++++++++++++++++++++++++-
 include/linux/uuid.h |  8 +++++
 include/machine_id.h | 11 ++++++
 include/net.h        |  2 ++
 net/Kconfig          | 17 +++++++++
 net/eth.c            | 15 ++++++--
 net/net.c            | 49 ++++++++++++++++++++++++--
 7 files changed, 179 insertions(+), 6 deletions(-)

base-commit: 7c12dcdbe20ffc872af8b433c91263c6520cf669
-- 
2.42.0




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

* [PATCH v3 1/2] common: machine_id: support deriving app specific UUIDs
  2023-11-22  9:47 [PATCH v3 0/2] Allow generating MAC addresses from machine ID Uwe Kleine-König
@ 2023-11-22  9:47 ` Uwe Kleine-König
  2023-11-22  9:47 ` [PATCH v3 2/2] net: add generic MAC address derivation from machine ID Uwe Kleine-König
  2023-11-22 15:24 ` [PATCH v3 0/2] Allow generating MAC addresses " Sascha Hauer
  2 siblings, 0 replies; 4+ messages in thread
From: Uwe Kleine-König @ 2023-11-22  9:47 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Ahmad Fatoum, Ahmad Fatoum, Alexander Shiyan, Thorsten Scherer, barebox

From: Ahmad Fatoum <a.fatoum@pengutronix.de>

libsystemd provides a sd_id128_get_machine_app_specific() function that
allows deriving an application specific UUID without directly leaking
the machine ID.

Let's provide an equivalent for barebox that will be used in a following
commit to generate a stable MAC instead of randomizing it.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 common/machine_id.c  | 83 +++++++++++++++++++++++++++++++++++++++++++-
 include/linux/uuid.h |  8 +++++
 include/machine_id.h | 11 ++++++
 3 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/common/machine_id.c b/common/machine_id.c
index f0b148fb9b99..e670886d8538 100644
--- a/common/machine_id.c
+++ b/common/machine_id.c
@@ -13,6 +13,7 @@
 
 #define MACHINE_ID_LENGTH 32
 
+static bool __machine_id_initialized;
 static void *__machine_id_hashable;
 static size_t __machine_id_hashable_length;
 
@@ -22,13 +23,92 @@ const void *machine_id_get_hashable(size_t *len)
 	return __machine_id_hashable;
 }
 
+/**
+ * machine_id_set_hashable - Provide per-board unique data
+ * @hashable: Buffer
+ * @len: size of buffer
+ *
+ * The data supplied to the last call of this function prior to
+ * late_initcall will be hashed and stored into global.machine_id,
+ * which can be later used for fixup into the kernel command line
+ * or for deriving application specific unique IDs via
+ * machine_id_get_app_specific().
+ */
 void machine_id_set_hashable(const void *hashable, size_t len)
 {
-
 	__machine_id_hashable = xmemdup(hashable, len);
 	__machine_id_hashable_length = len;
 }
 
+/**
+ * machine_id_get_app_specific - Generates an application-specific UUID
+ * @result: UUID output of the function
+ * @...: pairs of (const void *, size_t) arguments of data to factor
+ * into the UUID followed by a NULL sentinel value.
+ *
+ * Combines the machine ID with the application specific varargs data
+ * to arrive at an application-specific and board-specific UUID that is
+ * stable and unique.
+ *
+ * The function returns 0 if a UUID was successfully written into @result
+ * and a negative error code otherwise.
+ */
+int machine_id_get_app_specific(uuid_t *result, ...)
+{
+	static u8 hmac[SHA256_DIGEST_SIZE];
+	const void *data;
+	size_t size;
+	va_list args;
+	struct digest *d;
+	int ret;
+
+	if (!__machine_id_initialized)
+		return -ENODATA;
+
+	d = digest_alloc("hmac(sha256)");
+	if (!d)
+		return -ENOSYS;
+
+	ret = digest_set_key(d, __machine_id_hashable, __machine_id_hashable_length);
+	if (ret)
+		goto out;
+
+	ret = digest_init(d);
+	if (ret)
+		goto out;
+
+	ret = -ENODATA;
+
+	va_start(args, result);
+
+	while ((data = va_arg(args, const void *))) {
+		size = va_arg(args, size_t);
+
+		ret = digest_update(d, data, size);
+		if (ret)
+			break;
+	}
+
+	va_end(args);
+
+	if (ret)
+		goto out;
+
+	ret = digest_final(d, hmac);
+	if (ret)
+		goto out;
+
+	/* Take only the first half. */
+	memcpy(result, hmac, min(sizeof(hmac), sizeof(*result)));
+
+	uuid_make_v4(result);
+
+out:
+	digest_free(d);
+
+	return ret;
+}
+
 static int machine_id_set_globalvar(void)
 {
 	struct digest *digest = NULL;
@@ -66,6 +146,7 @@ static int machine_id_set_globalvar(void)
 	env_machine_id = basprintf("%.*s", MACHINE_ID_LENGTH, hex_machine_id);
 	globalvar_add_simple("machine_id", env_machine_id);
 	free(env_machine_id);
+	__machine_id_initialized = true;
 
 out:
 	digest_free(digest);
diff --git a/include/linux/uuid.h b/include/linux/uuid.h
index 6b1a3efa1e0b..1e4ffb343452 100644
--- a/include/linux/uuid.h
+++ b/include/linux/uuid.h
@@ -107,6 +107,14 @@ extern const u8 uuid_index[16];
 int guid_parse(const char *uuid, guid_t *u);
 int uuid_parse(const char *uuid, uuid_t *u);
 
+static inline void uuid_make_v4(uuid_t *u) {
+	/* Set UUID version to 4 --- truly random generation */
+	u->b[6] = (u->b[6] & 0x0F) | 0x40;
+
+	/* Set the UUID variant to DCE */
+	u->b[8] = (u->b[8] & 0x3F) | 0x80;
+}
+
 /* MEI UUID type, don't use anywhere else */
 #include <uapi/linux/uuid.h>
 
diff --git a/include/machine_id.h b/include/machine_id.h
index 9699e7f2072b..29600483ddc5 100644
--- a/include/machine_id.h
+++ b/include/machine_id.h
@@ -3,11 +3,15 @@
 #ifndef __MACHINE_ID_H__
 #define __MACHINE_ID_H__
 
+#include <linux/types.h>
+#include <linux/uuid.h>
+
 #if IS_ENABLED(CONFIG_MACHINE_ID)
 
 const void *machine_id_get_hashable(size_t *len);
 
 void machine_id_set_hashable(const void *hashable, size_t len);
+int machine_id_get_app_specific(uuid_t *result, ...) __attribute__((__sentinel__));
 
 #else
 
@@ -20,6 +24,13 @@ static inline void machine_id_set_hashable(const void *hashable, size_t len)
 {
 }
 
+static inline int machine_id_get_app_specific(uuid_t *result, ...)
+	__attribute__((__sentinel__));
+static inline int machine_id_get_app_specific(uuid_t *result, ...)
+{
+	return -ENOSYS;
+}
+
 #endif /* CONFIG_MACHINE_ID */
 
 #endif  /* __MACHINE_ID_H__ */
-- 
2.42.0




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

* [PATCH v3 2/2] net: add generic MAC address derivation from machine ID
  2023-11-22  9:47 [PATCH v3 0/2] Allow generating MAC addresses from machine ID Uwe Kleine-König
  2023-11-22  9:47 ` [PATCH v3 1/2] common: machine_id: support deriving app specific UUIDs Uwe Kleine-König
@ 2023-11-22  9:47 ` Uwe Kleine-König
  2023-11-22 15:24 ` [PATCH v3 0/2] Allow generating MAC addresses " Sascha Hauer
  2 siblings, 0 replies; 4+ messages in thread
From: Uwe Kleine-König @ 2023-11-22  9:47 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Ahmad Fatoum, Alexander Shiyan, Thorsten Scherer, Ahmad Fatoum, barebox

From: Ahmad Fatoum <ahmad@a3f.at>

Especially during development, devices often lack a MAC address. While a
MAC address can be easily added to the environment:

  nv dev.eth0.ethaddr="aa:bb:cc:dd:ee:ff"

It's easily lost when flashing complete new images, e.g. from CI.
Make the development experience neater by deriving a stable MAC address
if possible.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 include/net.h |  2 ++
 net/Kconfig   | 17 +++++++++++++++++
 net/eth.c     | 15 ++++++++++++---
 net/net.c     | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 78 insertions(+), 5 deletions(-)

diff --git a/include/net.h b/include/net.h
index a0ef8bee0404..de43c29f74ac 100644
--- a/include/net.h
+++ b/include/net.h
@@ -418,6 +418,8 @@ static inline int is_broadcast_ether_addr(const u8 *addr)
 #define ETH_ALEN	6	/* Octets in an Ethernet address */
 #define ETH_HLEN	14	/* Total octets in header.*/
 
+int generate_ether_addr(u8 *addr, int ethid);
+
 /**
  * random_ether_addr - Generate software assigned random Ethernet address
  * @addr: Pointer to a six-byte array containing the Ethernet address
diff --git a/net/Kconfig b/net/Kconfig
index 59f14c23cba2..07e623670e22 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -6,6 +6,23 @@ menuconfig NET
 
 if NET
 
+config NET_ETHADDR_FROM_MACHINE_ID
+	bool
+	prompt "generate stable Ethernet address"
+	depends on MACHINE_ID && HAVE_DIGEST_SHA256 && HAVE_DIGEST_HMAC
+	help
+	  By default, barebox will generate random Ethernet addresses for
+	  interfaces that had no explicit Ethernet address set via
+	  either board code or NVMEM properties in device tree.
+
+	  Say y here, to randomize Ethernet addresses only if no machine ID
+	  is available. Should barebox have a machine ID, it will be used
+	  alongside the hostname to generate MAC addresses that are unlikely
+	  to change between subsequent runs of barebox.
+
+	  This is not recommended for use in production as it may leak
+	  information about the machine ID.
+
 config NET_NFS
 	bool
 	prompt "nfs support"
diff --git a/net/eth.c b/net/eth.c
index ccac5e2a6488..d1474ec57df3 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -10,6 +10,7 @@
 #include <dhcp.h>
 #include <net.h>
 #include <dma.h>
+#include <machine_id.h>
 #include <of.h>
 #include <of_net.h>
 #include <linux/phy.h>
@@ -554,10 +555,11 @@ void eth_open_all(void)
 	}
 }
 
-static int of_populate_ethaddr(void)
+static int populate_ethaddr(void)
 {
 	char str[sizeof("xx:xx:xx:xx:xx:xx")];
 	struct eth_device *edev;
+	bool generated = false;
 	int ret;
 
 	list_for_each_entry(edev, &netdev_list, list) {
@@ -566,14 +568,21 @@ static int of_populate_ethaddr(void)
 
 		ret = of_get_mac_addr_nvmem(edev->parent->of_node,
 					    edev->ethaddr);
+		if (IS_ENABLED(CONFIG_NET_ETHADDR_FROM_MACHINE_ID) && ret) {
+			ret = generate_ether_addr(edev->ethaddr, edev->dev.id);
+			generated = true;
+		}
 		if (ret)
 			continue;
 
 		ethaddr_to_string(edev->ethaddr, str);
-		dev_info(&edev->dev, "Got preset MAC address from device tree: %s\n", str);
+		if (generated)
+			dev_notice(&edev->dev, "Generated MAC address from unique id: %s\n", str);
+		else
+			dev_info(&edev->dev, "Got preset MAC address from NVMEM: %s\n", str);
 		eth_set_ethaddr(edev, edev->ethaddr);
 	}
 
 	return 0;
 }
-postenvironment_initcall(of_populate_ethaddr);
+postenvironment_initcall(populate_ethaddr);
diff --git a/net/net.c b/net/net.c
index bf2117ff7ec2..e38179491d7a 100644
--- a/net/net.c
+++ b/net/net.c
@@ -25,6 +25,7 @@
 #include <init.h>
 #include <globalvar.h>
 #include <magicvar.h>
+#include <machine_id.h>
 #include <linux/ctype.h>
 #include <linux/err.h>
 
@@ -365,6 +366,43 @@ IPaddr_t net_get_gateway(void)
 
 static LIST_HEAD(connection_list);
 
+/**
+ * generate_ether_addr - Generates stable software assigned Ethernet address
+ * @addr: Pointer to a six-byte array to contain the Ethernet address
+ * @ethid: index of the Ethernet interface
+ *
+ * Derives an Ethernet address (MAC) from the machine ID, that's stable
+ * per board that is not multicast and has the local assigned bit set.
+ *
+ * Return 0 if an address could be generated or a negative error code otherwise.
+ */
+int generate_ether_addr(u8 *ethaddr, int ethid)
+{
+	const char *hostname;
+	uuid_t id;
+	int ret;
+
+	if (!IS_ENABLED(CONFIG_NET_ETHADDR_FROM_MACHINE_ID))
+		return -ENOSYS;
+
+	hostname = barebox_get_hostname();
+	if (!hostname)
+		return -EINVAL;
+
+	ret = machine_id_get_app_specific(&id, ARRAY_AND_SIZE("barebox-macaddr:"),
+					  hostname, strlen(hostname), NULL);
+	if (ret)
+		return ret;
+
+	memcpy(ethaddr, &id.b, ETH_ALEN);
+	eth_addr_add(ethaddr, ethid);
+
+	ethaddr[0] &= 0xfe;	/* clear multicast bit */
+	ethaddr[0] |= 0x02;	/* set local assignment bit (IEEE802) */
+
+	return 0;
+}
+
 static struct net_connection *net_new(struct eth_device *edev, IPaddr_t dest,
 				      rx_handler_f *handler, void *ctx)
 {
@@ -381,9 +419,16 @@ static struct net_connection *net_new(struct eth_device *edev, IPaddr_t dest,
 
 	if (!is_valid_ether_addr(edev->ethaddr)) {
 		char str[sizeof("xx:xx:xx:xx:xx:xx")];
-		random_ether_addr(edev->ethaddr);
+
+		ret = generate_ether_addr(edev->ethaddr, edev->dev.id);
+		if (ret)
+			random_ether_addr(edev->ethaddr);
+
 		ethaddr_to_string(edev->ethaddr, str);
-		dev_warn(&edev->dev, "No MAC address set. Using random address %s\n", str);
+
+		dev_warn(&edev->dev, "No MAC address set. Using %s %s\n",
+			 ret == 1 ? "address computed from unique ID" : "random address",
+			 str);
 		eth_set_ethaddr(edev, edev->ethaddr);
 	}
 
-- 
2.42.0




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

* Re: [PATCH v3 0/2] Allow generating MAC addresses from machine ID
  2023-11-22  9:47 [PATCH v3 0/2] Allow generating MAC addresses from machine ID Uwe Kleine-König
  2023-11-22  9:47 ` [PATCH v3 1/2] common: machine_id: support deriving app specific UUIDs Uwe Kleine-König
  2023-11-22  9:47 ` [PATCH v3 2/2] net: add generic MAC address derivation from machine ID Uwe Kleine-König
@ 2023-11-22 15:24 ` Sascha Hauer
  2 siblings, 0 replies; 4+ messages in thread
From: Sascha Hauer @ 2023-11-22 15:24 UTC (permalink / raw)
  To: Uwe Kleine-König
  Cc: Ahmad Fatoum, Alexander Shiyan, Thorsten Scherer, Ahmad Fatoum, barebox

On Wed, Nov 22, 2023 at 10:47:48AM +0100, Uwe Kleine-König wrote:
> Hello,
> 
> On Tue, Nov 21, 2023 at 09:33:58AM +0100, Sascha Hauer wrote:
> > This series neither applies to master nor to next, please resend
> 
> here is the rebased series. Applies to current next. There are no other
> changes.
> 
> Best regards
> Uwe
> 
> Ahmad Fatoum (2):
>   common: machine_id: support deriving app specific UUIDs
>   net: add generic MAC address derivation from machine ID

Applied, thanks

Sascha

> 
>  common/machine_id.c  | 83 +++++++++++++++++++++++++++++++++++++++++++-
>  include/linux/uuid.h |  8 +++++
>  include/machine_id.h | 11 ++++++
>  include/net.h        |  2 ++
>  net/Kconfig          | 17 +++++++++
>  net/eth.c            | 15 ++++++--
>  net/net.c            | 49 ++++++++++++++++++++++++--
>  7 files changed, 179 insertions(+), 6 deletions(-)
> 
> base-commit: 7c12dcdbe20ffc872af8b433c91263c6520cf669
> -- 
> 2.42.0
> 
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



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

end of thread, other threads:[~2023-11-22 15:25 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-22  9:47 [PATCH v3 0/2] Allow generating MAC addresses from machine ID Uwe Kleine-König
2023-11-22  9:47 ` [PATCH v3 1/2] common: machine_id: support deriving app specific UUIDs Uwe Kleine-König
2023-11-22  9:47 ` [PATCH v3 2/2] net: add generic MAC address derivation from machine ID Uwe Kleine-König
2023-11-22 15:24 ` [PATCH v3 0/2] Allow generating MAC addresses " Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox