mirror of
https://git.proxmox.com/git/fwupd
synced 2025-07-27 11:09:28 +00:00
genesys: Check for validity of public-key
The scaler may return invalid version or public-key. This checks for the public-key by verifing if it starts with "N = " for both devices usbhub and scaler; however, the scaler version cannot be checked. Note: Replug the USB-C cable is fixes the issue.
This commit is contained in:
parent
e6f049625e
commit
7dca55a3fc
@ -6,6 +6,11 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
guint8 N[0x206];
|
||||||
|
guint8 E[0x00c];
|
||||||
|
} FuGenesysPublicKey;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
guint8 reg;
|
guint8 reg;
|
||||||
guint8 expected_val;
|
guint8 expected_val;
|
||||||
|
@ -62,7 +62,7 @@ typedef struct {
|
|||||||
struct _FuGenesysScalerDevice {
|
struct _FuGenesysScalerDevice {
|
||||||
FuDevice parent_instance;
|
FuDevice parent_instance;
|
||||||
guint8 level;
|
guint8 level;
|
||||||
guint8 public_key[0x212];
|
FuGenesysPublicKey public_key;
|
||||||
FuCfiDevice *cfi_device;
|
FuCfiDevice *cfi_device;
|
||||||
FuGenesysVendorCommand vc;
|
FuGenesysVendorCommand vc;
|
||||||
guint32 sector_size;
|
guint32 sector_size;
|
||||||
@ -1556,12 +1556,27 @@ fu_genesys_scaler_device_probe(FuDevice *device, GError **error)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!fu_genesys_scaler_device_get_public_key(self,
|
if (!fu_genesys_scaler_device_get_public_key(self,
|
||||||
self->public_key,
|
(guint8 *)&self->public_key,
|
||||||
sizeof(self->public_key),
|
sizeof(self->public_key),
|
||||||
error))
|
error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
guid =
|
if (memcmp(self->public_key.N, "N = ", 4) != 0 ||
|
||||||
fwupd_guid_hash_data(self->public_key, sizeof(self->public_key), FWUPD_GUID_FLAG_NONE);
|
memcmp(self->public_key.E, "E = ", 4) != 0) {
|
||||||
|
if (g_getenv("FWUPD_GENESYS_SCALER_VERBOSE") != NULL) {
|
||||||
|
fu_common_dump_raw(G_LOG_DOMAIN,
|
||||||
|
"PublicKey",
|
||||||
|
(const guint8 *)&self->public_key,
|
||||||
|
sizeof(self->public_key));
|
||||||
|
}
|
||||||
|
g_set_error_literal(error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_SIGNATURE_INVALID,
|
||||||
|
"invalid public-key");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
guid = fwupd_guid_hash_data((const guint8 *)&self->public_key,
|
||||||
|
sizeof(self->public_key),
|
||||||
|
FWUPD_GUID_FLAG_NONE);
|
||||||
|
|
||||||
if (!fu_genesys_scaler_device_get_version(self, buf, sizeof(buf), error))
|
if (!fu_genesys_scaler_device_get_version(self, buf, sizeof(buf), error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -1747,7 +1762,7 @@ fu_genesys_scaler_device_prepare_firmware(FuDevice *device,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (memcmp(&self->footer.data.public_key,
|
if (memcmp(&self->footer.data.public_key,
|
||||||
self->public_key,
|
&self->public_key,
|
||||||
sizeof(self->footer.data.public_key)) != 0) {
|
sizeof(self->footer.data.public_key)) != 0) {
|
||||||
g_set_error_literal(error,
|
g_set_error_literal(error,
|
||||||
FWUPD_ERROR,
|
FWUPD_ERROR,
|
||||||
@ -1854,7 +1869,7 @@ fu_genesys_scaler_device_to_string(FuDevice *device, guint idt, GString *str)
|
|||||||
if (fu_memcpy_safe((guint8 *)public_key_e,
|
if (fu_memcpy_safe((guint8 *)public_key_e,
|
||||||
sizeof(public_key_e),
|
sizeof(public_key_e),
|
||||||
0, /* dst */
|
0, /* dst */
|
||||||
self->public_key,
|
(const guint8 *)&self->public_key,
|
||||||
sizeof(self->public_key),
|
sizeof(self->public_key),
|
||||||
sizeof(self->public_key) - 2 - (sizeof(public_key_e) - 1), /* src */
|
sizeof(self->public_key) - 2 - (sizeof(public_key_e) - 1), /* src */
|
||||||
sizeof(public_key_e) - 1,
|
sizeof(public_key_e) - 1,
|
||||||
@ -1866,7 +1881,7 @@ fu_genesys_scaler_device_to_string(FuDevice *device, guint idt, GString *str)
|
|||||||
if (fu_memcpy_safe((guint8 *)public_key_n,
|
if (fu_memcpy_safe((guint8 *)public_key_n,
|
||||||
sizeof(public_key_n),
|
sizeof(public_key_n),
|
||||||
0, /* dst */
|
0, /* dst */
|
||||||
self->public_key,
|
(const guint8 *)&self->public_key,
|
||||||
sizeof(self->public_key),
|
sizeof(self->public_key),
|
||||||
4, /* src */
|
4, /* src */
|
||||||
sizeof(public_key_n) - 1,
|
sizeof(public_key_n) - 1,
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include <fwupdplugin.h>
|
#include <fwupdplugin.h>
|
||||||
|
|
||||||
|
#include "fu-genesys-common.h"
|
||||||
|
|
||||||
#define FU_TYPE_GENESYS_SCALER_FIRMWARE (fu_genesys_scaler_firmware_get_type())
|
#define FU_TYPE_GENESYS_SCALER_FIRMWARE (fu_genesys_scaler_firmware_get_type())
|
||||||
G_DECLARE_FINAL_TYPE(FuGenesysScalerFirmware,
|
G_DECLARE_FINAL_TYPE(FuGenesysScalerFirmware,
|
||||||
fu_genesys_scaler_firmware,
|
fu_genesys_scaler_firmware,
|
||||||
@ -134,10 +136,7 @@ typedef struct __attribute__((packed)) {
|
|||||||
typedef union __attribute__((packed)) {
|
typedef union __attribute__((packed)) {
|
||||||
guint8 raw[0x312];
|
guint8 raw[0x312];
|
||||||
struct {
|
struct {
|
||||||
struct {
|
FuGenesysPublicKey public_key;
|
||||||
guint8 N[0x206];
|
|
||||||
guint8 E[0x00c];
|
|
||||||
} __attribute__((packed)) public_key;
|
|
||||||
FuGenesysMtkRsaHeader header;
|
FuGenesysMtkRsaHeader header;
|
||||||
} data;
|
} data;
|
||||||
} FuGenesysMtkFooter;
|
} FuGenesysMtkFooter;
|
||||||
|
@ -171,7 +171,7 @@ struct _FuGenesysUsbhubDevice {
|
|||||||
gboolean read_first_bank;
|
gboolean read_first_bank;
|
||||||
gboolean write_recovery_bank;
|
gboolean write_recovery_bank;
|
||||||
|
|
||||||
guint8 public_key[0x212];
|
FuGenesysPublicKey public_key;
|
||||||
FuCfiDevice *cfi_device;
|
FuCfiDevice *cfi_device;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1096,7 +1096,7 @@ fu_genesys_usbhub_device_setup(FuDevice *device, GError **error)
|
|||||||
/* has public key */
|
/* has public key */
|
||||||
if (fu_device_has_private_flag(device, FU_GENESYS_USBHUB_FLAG_HAS_PUBLIC_KEY)) {
|
if (fu_device_has_private_flag(device, FU_GENESYS_USBHUB_FLAG_HAS_PUBLIC_KEY)) {
|
||||||
g_autofree gchar *guid = NULL;
|
g_autofree gchar *guid = NULL;
|
||||||
if (!fu_memcpy_safe(self->public_key,
|
if (!fu_memcpy_safe((guint8 *)&self->public_key,
|
||||||
sizeof(self->public_key),
|
sizeof(self->public_key),
|
||||||
0, /* dst */
|
0, /* dst */
|
||||||
g_bytes_get_data(blob, NULL),
|
g_bytes_get_data(blob, NULL),
|
||||||
@ -1105,7 +1105,15 @@ fu_genesys_usbhub_device_setup(FuDevice *device, GError **error)
|
|||||||
sizeof(self->public_key),
|
sizeof(self->public_key),
|
||||||
error))
|
error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
guid = fwupd_guid_hash_data(self->public_key,
|
if (memcmp(&self->public_key.N, "N = ", 4) != 0 &&
|
||||||
|
memcmp(&self->public_key.E, "E = ", 4) != 0) {
|
||||||
|
g_set_error_literal(error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_SIGNATURE_INVALID,
|
||||||
|
"invalid public-key");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
guid = fwupd_guid_hash_data((const guint8 *)&self->public_key,
|
||||||
sizeof(self->public_key),
|
sizeof(self->public_key),
|
||||||
FWUPD_GUID_FLAG_NONE);
|
FWUPD_GUID_FLAG_NONE);
|
||||||
fu_device_add_instance_strup(device, "PUBKEY", guid);
|
fu_device_add_instance_strup(device, "PUBKEY", guid);
|
||||||
@ -1202,9 +1210,9 @@ fu_genesys_usbhub_device_prepare_firmware(FuDevice *device,
|
|||||||
const guint8 *buf = g_bytes_get_data(fw, &bufsz);
|
const guint8 *buf = g_bytes_get_data(fw, &bufsz);
|
||||||
|
|
||||||
if (g_getenv("FWUPD_GENESYS_USBHUB_VERBOSE") != NULL)
|
if (g_getenv("FWUPD_GENESYS_USBHUB_VERBOSE") != NULL)
|
||||||
fu_common_dump_raw(G_LOG_DOMAIN, "Footer", buf, bufsz);
|
fu_common_dump_raw(G_LOG_DOMAIN, "PublicKey", buf, bufsz);
|
||||||
if (memcmp(buf + fu_firmware_get_size(firmware),
|
if (memcmp(buf + fu_firmware_get_size(firmware),
|
||||||
self->public_key,
|
&self->public_key,
|
||||||
sizeof(self->public_key)) != 0) {
|
sizeof(self->public_key)) != 0) {
|
||||||
g_set_error_literal(error,
|
g_set_error_literal(error,
|
||||||
FWUPD_ERROR,
|
FWUPD_ERROR,
|
||||||
|
Loading…
Reference in New Issue
Block a user