genesys: usbhub: Identify HP usbhub using its public-key

The HP M2xfd monitors use GenesysLogic GL3523 USB Hub and provides their
own firmwares. Furthermore, HP uses the same VID/PID for other USB Hubs
products, with a different public-key; the HP M24fd and M27fd use
different public-key.

This appends the public-key to the instance-id string to make the
distinction between all the HP USB Hubs, and prevents to install a
firmware with the wrong public-key.
This commit is contained in:
Gaël PORTAY 2022-03-19 17:47:47 +01:00 committed by Richard Hughes
parent ad3cf1874a
commit be4e3fffdc
4 changed files with 56 additions and 1 deletions

View File

@ -25,6 +25,8 @@ This plugin supports the following protocol IDs:
These devices use the standard USB DeviceInstanceId values for the USB Hub, e.g.
* HP USB-C Controller: `USB\VID_03F0&PID_0610`
* HP M24fd USB-C Controller: `USB\VID_03F0&PID_0610&PUBKEY_B335BDCE-7073-5D0E-9BD3-9B69C1A6899F`
* HP M27fd USB-C Controller: `USB\VID_03F0&PID_0610&PUBKEY_847A3650-8648-586B-83C8-8B53714F37E3`
These devices also use custom GUID values for the Scaler, e.g.

View File

@ -1,4 +1,5 @@
/*
* Copyright (C) 2022 Gaël PORTAY <gael.portay@collabora.com>
* Copyright (C) 2021 Ricardo Cañuelo <ricardo.canuelo@collabora.com>
*
* SPDX-License-Identifier: LGPL-2.1+
@ -115,6 +116,7 @@ struct _FuGenesysUsbhubDevice {
gboolean read_first_bank;
gboolean write_recovery_bank;
guint8 public_key[0x212];
FuCfiDevice *cfi_device;
};
@ -693,6 +695,7 @@ fu_genesys_usbhub_device_setup(FuDevice *device, GError **error)
g_autoptr(GError) error_local = NULL;
g_autoptr(GBytes) blob = NULL;
g_autofree guint8 *buf = NULL;
g_autofree gchar *guid = NULL;
/* FuUsbDevice->setup */
if (!FU_DEVICE_CLASS(fu_genesys_usbhub_device_parent_class)->setup(device, error)) {
@ -926,6 +929,21 @@ fu_genesys_usbhub_device_setup(FuDevice *device, GError **error)
self->write_recovery_bank = address == self->fw_bank_addr[1];
}
/* get public key */
if (!fu_memcpy_safe(self->public_key,
sizeof(self->public_key),
0, /* dst */
g_bytes_get_data(blob, NULL),
g_bytes_get_size(blob),
self->fw_data_total_count, /* src */
sizeof(self->public_key),
error))
return FALSE;
guid =
fwupd_guid_hash_data(self->public_key, sizeof(self->public_key), FWUPD_GUID_FLAG_NONE);
fu_device_add_instance_strup(device, "PUBKEY", guid);
fu_device_build_instance_id(device, NULL, "USB", "VID", "PID", "PUBKEY", NULL);
/* have MStar scaler */
if (fu_device_has_private_flag(device, FU_GENESYS_USBHUB_FLAG_HAS_MSTAR_SCALER))
if (!fu_genesys_usbhub_device_mstar_scaler_setup(self, error))
@ -969,12 +987,31 @@ fu_genesys_usbhub_device_prepare_firmware(FuDevice *device,
FwupdInstallFlags flags,
GError **error)
{
FuGenesysUsbhubDevice *self = FU_GENESYS_USBHUB_DEVICE(device);
g_autoptr(FuFirmware) firmware = fu_genesys_usbhub_firmware_new();
/* parse firmware */
if (!fu_firmware_parse(firmware, fw, flags, error))
return NULL;
/* has public-key */
if (g_bytes_get_size(fw) >= fu_firmware_get_size(firmware) + sizeof(self->public_key)) {
gsize bufsz = 0;
const guint8 *buf = g_bytes_get_data(fw, &bufsz);
if (g_getenv("FWUPD_GENESYS_USBHUB_VERBOSE") != NULL)
fu_common_dump_raw(G_LOG_DOMAIN, "Footer", buf, bufsz);
if (memcmp(buf + fu_firmware_get_size(firmware),
self->public_key,
sizeof(self->public_key)) != 0) {
g_set_error_literal(error,
FWUPD_ERROR,
FWUPD_ERROR_SIGNATURE_INVALID,
"mismatch public-key");
return NULL;
}
}
/* check size */
if (g_bytes_get_size(fw) > fu_device_get_firmware_size_max(device)) {
g_set_error(error,

View File

@ -153,6 +153,7 @@ fu_genesys_usbhub_firmware_parse(FuFirmware *firmware,
} else {
code_size = 0x6000;
}
fu_firmware_set_size(firmware, code_size);
/* calculate checksum */
if ((flags & FWUPD_INSTALL_FLAG_IGNORE_CHECKSUM) == 0)

View File

@ -1,9 +1,24 @@
# M2xfd
# HP M2xfd
# usbhub
[USB\VID_03F0&PID_0610]
Plugin = genesys
Name = HP USB-C Controller
GenesysUsbhubSwitchRequest = 0xA1
GenesysUsbhubReadRequest = 0xA2
GenesysUsbhubWriteRequest = 0xA3
[USB\VID_03F0&PID_0610&PUBKEY_AB859399-95B8-5817-B521-9AD8CC7F5BD6]
Plugin = genesys
Name = HP M24fd USB-C Controller
Flags = has-mstar-scaler
GenesysUsbhubSwitchRequest = 0xA1
GenesysUsbhubReadRequest = 0xA2
GenesysUsbhubWriteRequest = 0xA3
[USB\VID_03F0&PID_0610&PUBKEY_6BE97D77-C2BA-5AA2-B7DF-B9B318BEC2B5]
Plugin = genesys
Name = HP M27fd USB-C Controller
Flags = has-mstar-scaler
GenesysUsbhubSwitchRequest = 0xA1
GenesysUsbhubReadRequest = 0xA2