lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250620-usb_authentication-v1-3-0d92261a5779@ssi.gouv.fr>
Date: Fri, 20 Jun 2025 16:27:18 +0200
From: nicolas.bouchinet@....cyber.gouv.fr
To: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Cc: Alan Stern <stern@...land.harvard.edu>, 
 Kannappan R <r.kannappan@...el.com>, 
 Sabyrzhan Tasbolatov <snovitoll@...il.com>, 
 Krzysztof Kozlowski <krzysztof.kozlowski@...aro.org>, 
 Stefan Eichenberger <stefan.eichenberger@...adex.com>, 
 Thomas Gleixner <tglx@...utronix.de>, Pawel Laszczak <pawell@...ence.com>, 
 Ma Ke <make_ruc2021@....com>, Jeff Johnson <jeff.johnson@....qualcomm.com>, 
 Luc Bonnafoux <luc.bonnafoux@....gouv.fr>, 
 Luc Bonnafoux <luc.bonnafoux@....cyber.gouv.fr>, 
 Nicolas Bouchinet <nicolas.bouchinet@....gouv.fr>, 
 linux-kernel@...r.kernel.org, linux-usb@...r.kernel.org
Subject: [RFC PATCH 3/4] usb: core: Plug the usb authentication capability

From: Nicolas Bouchinet <nicolas.bouchinet@....gouv.fr>

Plugs the usb authentication implementation in the usb stack and more
particularly in the usb_parse_configuration function after the BOS has
been parsed and the usb authentication capacity has been controlled.

The authentication bulk is implemented by the usb_authenticate_device
function.

The authorization decision enforcement is done via the authorized field of
the usb_device and the associated authorization and deauthorization functions.
The usb_device also contains an authenticated field that could be used to track
the result of the authentication process and allow for more complex security
policy: the user could manually authorize a device that failed the
authentication or manually deauthorize a device that was previously
authenticated.

The usb_authenticate_device returns 0 or an error code. If 0 is
returned, the authorized and authenticated fields of the usb_device are
updated with the result of the authentication.

Co-developed-by: Luc Bonnafoux <luc.bonnafoux@....gouv.fr>
Signed-off-by: Luc Bonnafoux <luc.bonnafoux@....gouv.fr>
Signed-off-by: Nicolas Bouchinet <nicolas.bouchinet@....gouv.fr>
---
 drivers/usb/core/config.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++-
 drivers/usb/core/hub.c    |  6 ++++++
 drivers/usb/core/usb.c    |  5 +++++
 include/linux/usb.h       |  2 ++
 4 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 13bd4ec4ea5f7a6fef615b6f50b1acb3bbe44ba4..45ee8e93e263c41f1bf4271be4e69ccfcac3f650 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -14,6 +14,7 @@
 #include <asm/byteorder.h>
 #include "usb.h"
 
+#include "authent.h"
 
 #define USB_MAXALTSETTING		128	/* Hard limit */
 
@@ -824,7 +825,50 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx,
 		kref_init(&intfc->ref);
 	}
 
-	/* FIXME: parse the BOS descriptor */
+	/* If device USB version is above 2.0, get BOS descriptor */
+	/*
+	 * Requirement for bcdUSB >= 2.10 is defined in USB 3.2 ยง9.2.6.6
+	 * "Devices with a value of at least 0210H in the bcdUSB field of their
+	 * device descriptor shall support GetDescriptor (BOS Descriptor) requests."
+	 *
+	 * To discuss, BOS request could be also sent for bcdUSB >= 0x0201
+	 */
+	// Set a default value for authenticated at true in order not to block devices
+	// that do not support the authentication
+	dev->authenticated = 1;
+
+	if (le16_to_cpu(dev->descriptor.bcdUSB) >= 0x0201) {
+		pr_notice("bcdUSB >= 0x0201\n");
+		retval = usb_get_bos_descriptor(dev);
+		if (!retval) {
+			pr_notice("found BOS\n");
+#ifdef CONFIG_USB_AUTHENTICATION
+			if (dev->bos->authent_cap) {
+				/* If authentication cap is present, start device authent */
+				pr_notice("found Authent BOS\n");
+				retval = usb_authenticate_device(dev);
+				if (retval != 0) {
+					pr_err("failed to authenticate the device: %d\n",
+					       retval);
+				} else if (!dev->authenticated) {
+					pr_notice("device has been rejected\n");
+					// return early from the configuration process
+					return 0;
+				} else {
+					pr_notice("device has been authorized\n");
+				}
+			} else {
+				// USB authentication unsupported
+				// Apply security policy on failed devices
+				pr_notice("no authentication capability\n");
+			}
+#endif
+		} else {
+			// Older USB version, authentication not supported
+			// Apply security policy on failed devices
+			pr_notice("device does not have a BOS descriptor\n");
+		}
+	}
 
 	/* Skip over any Class Specific or Vendor Specific descriptors;
 	 * find the first interface descriptor */
@@ -1051,6 +1095,7 @@ int usb_get_bos_descriptor(struct usb_device *dev)
 	length = bos->bLength;
 	total_len = le16_to_cpu(bos->wTotalLength);
 	num = bos->bNumDeviceCaps;
+
 	kfree(bos);
 	if (total_len < length)
 		return -EINVAL;
@@ -1122,6 +1167,10 @@ int usb_get_bos_descriptor(struct usb_device *dev)
 			dev->bos->ptm_cap =
 				(struct usb_ptm_cap_descriptor *)buffer;
 			break;
+		case USB_AUTHENT_CAP_TYPE:
+			dev->bos->authent_cap =
+				(struct usb_authent_cap_descriptor *)buffer;
+			break;
 		default:
 			break;
 		}
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 0e1dd6ef60a719f59a22d86caeb20f86991b5b29..753e55155ea34a7739b5f530dad429534e60842d 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2640,6 +2640,12 @@ int usb_new_device(struct usb_device *udev)
 	udev->dev.devt = MKDEV(USB_DEVICE_MAJOR,
 			(((udev->bus->busnum-1) * 128) + (udev->devnum-1)));
 
+	// TODO: Check the device state, we want to avoid semi-initialized device to userspace.
+	if (!udev->authenticated) {
+		// If the device is not authenticated, abort the procedure
+		goto fail;
+	}
+
 	/* Tell the world! */
 	announce_device(udev);
 
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 0b4685aad2d50337f3cacb2198c95a68ae8eff86..76847c01d3493e2527992a3bb927422519d9a974 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -46,6 +46,7 @@
 #include <linux/dma-mapping.h>
 
 #include "hub.h"
+#include "authent_netlink.h"
 
 const char *usbcore_name = "usbcore";
 
@@ -1080,6 +1081,10 @@ static int __init usb_init(void)
 	usb_debugfs_init();
 
 	usb_acpi_register();
+
+	// TODO : check error case
+	usb_auth_init_netlink();
+
 	retval = bus_register(&usb_bus_type);
 	if (retval)
 		goto bus_register_failed;
diff --git a/include/linux/usb.h b/include/linux/usb.h
index b46738701f8dc46085f251379873b6a8a008d99d..e9037c8120b43556f8610f9acb3ad4129e847b98 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -431,6 +431,8 @@ struct usb_host_bos {
 	struct usb_ssp_cap_descriptor	*ssp_cap;
 	struct usb_ss_container_id_descriptor	*ss_id;
 	struct usb_ptm_cap_descriptor	*ptm_cap;
+	/* Authentication capability */
+	struct usb_authent_cap_descriptor *authent_cap;
 };
 
 int __usb_get_extra_descriptor(char *buffer, unsigned size,

-- 
2.50.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ