synaptics-rmi: add feature to verify signature (#5406)

This commit is contained in:
Vincent Huang 2023-01-17 17:33:49 +08:00 committed by GitHub
parent 4057edb24b
commit a01b57b17d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 279 additions and 37 deletions

View File

@ -60,6 +60,7 @@ typedef struct {
guint32 build_id; guint32 build_id;
guint8 bootloader_id[2]; guint8 bootloader_id[2];
guint8 status_addr; guint8 status_addr;
gboolean has_pubkey;
} FuSynapticsRmiFlash; } FuSynapticsRmiFlash;
#define RMI_F34_HAS_NEW_REG_MAP (1 << 0) #define RMI_F34_HAS_NEW_REG_MAP (1 << 0)
@ -69,11 +70,13 @@ typedef struct {
#define RMI_F34_BLOCK_DATA_V1_OFFSET 1 #define RMI_F34_BLOCK_DATA_V1_OFFSET 1
#define RMI_F34_ENABLE_WAIT_MS 300 /* ms */ #define RMI_F34_ENABLE_WAIT_MS 300 /* ms */
#define RMI_F34_IDLE_WAIT_MS 20 /* ms */ #define RMI_F34_IDLE_WAIT_MS 500 /* ms */
#define RMI_DEVICE_PAGE_SELECT_REGISTER 0xff #define RMI_DEVICE_PAGE_SELECT_REGISTER 0xff
#define RMI_DEVICE_BUS_SELECT_REGISTER 0xfe #define RMI_DEVICE_BUS_SELECT_REGISTER 0xfe
#define RMI_KEY_SIZE_2K 0x100
typedef enum { typedef enum {
RMI_DEVICE_WAIT_FOR_IDLE_FLAG_NONE = 0, RMI_DEVICE_WAIT_FOR_IDLE_FLAG_NONE = 0,
RMI_DEVICE_WAIT_FOR_IDLE_FLAG_REFRESH_F34 = (1 << 0), RMI_DEVICE_WAIT_FOR_IDLE_FLAG_REFRESH_F34 = (1 << 0),

View File

@ -32,17 +32,17 @@ G_DEFINE_TYPE(FuSynapticsRmiHidDevice, fu_synaptics_rmi_hid_device, FU_TYPE_SYNA
#define RMI_DEVICE_DEFAULT_TIMEOUT 2000 #define RMI_DEVICE_DEFAULT_TIMEOUT 2000
#define HID_RMI4_REPORT_ID 0 #define HID_RMI4_REPORT_ID 0
#define HID_RMI4_READ_INPUT_COUNT 1 #define HID_RMI4_READ_INPUT_COUNT 1
#define HID_RMI4_READ_INPUT_DATA 2 #define HID_RMI4_READ_INPUT_DATA 2
#define HID_RMI4_READ_OUTPUT_ADDR 2 #define HID_RMI4_READ_OUTPUT_ADDR 2
#define HID_RMI4_READ_OUTPUT_COUNT 4 #define HID_RMI4_READ_OUTPUT_COUNT 4
#define HID_RMI4_WRITE_OUTPUT_COUNT 1 #define HID_RMI4_WRITE_OUTPUT_COUNT 1
#define HID_RMI4_WRITE_OUTPUT_ADDR 2 #define HID_RMI4_WRITE_OUTPUT_ADDR 2
#define HID_RMI4_WRITE_OUTPUT_DATA 4 #define HID_RMI4_WRITE_OUTPUT_DATA 4
#define HID_RMI4_FEATURE_MODE 1 #define HID_RMI4_FEATURE_MODE 1
#define HID_RMI4_ATTN_INTERRUPT_SOURCES 1 #define HID_RMI4_ATTN_INTERRUPT_SOURCES 1
#define HID_RMI4_ATTN_DATA 2 #define HID_RMI4_ATTN_DATA 2
/* /*
* This bit disables whatever sleep mode may be selected by the sleep_mode * This bit disables whatever sleep mode may be selected by the sleep_mode
@ -559,10 +559,9 @@ static void
fu_synaptics_rmi_hid_device_set_progress(FuDevice *self, FuProgress *progress) fu_synaptics_rmi_hid_device_set_progress(FuDevice *self, FuProgress *progress)
{ {
fu_progress_set_id(progress, G_STRLOC); fu_progress_set_id(progress, G_STRLOC);
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED); fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 3, "detach");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2, "detach"); fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 88, "write");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94, "write"); fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 7, "attach");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2, "attach");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2, "reload"); fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2, "reload");
} }

View File

@ -39,6 +39,7 @@ typedef enum {
RMI_PARTITION_ID_DISPLAY_CONFIG, RMI_PARTITION_ID_DISPLAY_CONFIG,
RMI_PARTITION_ID_EXTERNAL_TOUCH_AFE_CONFIG, RMI_PARTITION_ID_EXTERNAL_TOUCH_AFE_CONFIG,
RMI_PARTITION_ID_UTILITY_PARAMETER, RMI_PARTITION_ID_UTILITY_PARAMETER,
RMI_PARTITION_ID_PUBKEY,
RMI_PARTITION_ID_FIXED_LOCATION_DATA = 0x0E, RMI_PARTITION_ID_FIXED_LOCATION_DATA = 0x0E,
} RmiPartitionId; } RmiPartitionId;
@ -71,6 +72,8 @@ rmi_firmware_partition_id_to_string(RmiPartitionId partition_id)
return "external-touch-afe-config"; return "external-touch-afe-config";
if (partition_id == RMI_PARTITION_ID_UTILITY_PARAMETER) if (partition_id == RMI_PARTITION_ID_UTILITY_PARAMETER)
return "utility-parameter"; return "utility-parameter";
if (partition_id == RMI_PARTITION_ID_PUBKEY)
return "pubkey";
if (partition_id == RMI_PARTITION_ID_FIXED_LOCATION_DATA) if (partition_id == RMI_PARTITION_ID_FIXED_LOCATION_DATA)
return "fixed-location-data"; return "fixed-location-data";
return NULL; return NULL;
@ -120,6 +123,53 @@ fu_synaptics_rmi_v7_device_detach(FuDevice *device, FuProgress *progress, GError
return TRUE; return TRUE;
} }
static gboolean
fu_synaptics_rmi_v7_device_erase_partition(FuSynapticsRmiDevice *self,
guint8 partition_id,
GError **error)
{
FuSynapticsRmiFunction *f34;
FuSynapticsRmiFlash *flash = fu_synaptics_rmi_device_get_flash(self);
g_autoptr(GByteArray) erase_cmd = g_byte_array_new();
/* f34 */
f34 = fu_synaptics_rmi_device_get_function(self, 0x34, error);
if (f34 == NULL)
return FALSE;
fu_byte_array_append_uint8(erase_cmd, partition_id);
fu_byte_array_append_uint32(erase_cmd, 0x0, G_LITTLE_ENDIAN);
fu_byte_array_append_uint8(erase_cmd, RMI_FLASH_CMD_ERASE);
fu_byte_array_append_uint8(erase_cmd, flash->bootloader_id[0]);
fu_byte_array_append_uint8(erase_cmd, flash->bootloader_id[1]);
g_usleep(1000 * 1000);
if (!fu_synaptics_rmi_device_write(self,
f34->data_base + 1,
erase_cmd,
FU_SYNAPTICS_RMI_DEVICE_FLAG_NONE,
error)) {
g_prefix_error(error, "failed to unlock erasing: ");
return FALSE;
}
g_usleep(1000 * 100);
/* wait for ATTN */
if (!fu_synaptics_rmi_device_wait_for_idle(self,
RMI_F34_ERASE_WAIT_MS,
RMI_DEVICE_WAIT_FOR_IDLE_FLAG_NONE,
error)) {
g_prefix_error(error, "failed to wait for idle: ");
return FALSE;
}
if (!fu_synaptics_rmi_device_poll_wait(self, error)) {
g_prefix_error(error, "failed to get flash success: ");
return FALSE;
}
return TRUE;
}
static gboolean static gboolean
fu_synaptics_rmi_v7_device_erase_all(FuSynapticsRmiDevice *self, GError **error) fu_synaptics_rmi_v7_device_erase_all(FuSynapticsRmiDevice *self, GError **error)
{ {
@ -134,7 +184,7 @@ fu_synaptics_rmi_v7_device_erase_all(FuSynapticsRmiDevice *self, GError **error)
fu_byte_array_append_uint8(erase_cmd, RMI_PARTITION_ID_CORE_CODE); fu_byte_array_append_uint8(erase_cmd, RMI_PARTITION_ID_CORE_CODE);
fu_byte_array_append_uint32(erase_cmd, 0x0, G_LITTLE_ENDIAN); fu_byte_array_append_uint32(erase_cmd, 0x0, G_LITTLE_ENDIAN);
if (flash->bootloader_id[1] == 8) { if (flash->bootloader_id[1] >= 8) {
/* For bootloader v8 */ /* For bootloader v8 */
fu_byte_array_append_uint8(erase_cmd, RMI_FLASH_CMD_ERASE_AP); fu_byte_array_append_uint8(erase_cmd, RMI_FLASH_CMD_ERASE_AP);
} else { } else {
@ -145,7 +195,7 @@ fu_synaptics_rmi_v7_device_erase_all(FuSynapticsRmiDevice *self, GError **error)
fu_byte_array_append_uint8(erase_cmd, flash->bootloader_id[1]); fu_byte_array_append_uint8(erase_cmd, flash->bootloader_id[1]);
/* for BL8 device, we need hold 1 seconds after querying F34 status to /* for BL8 device, we need hold 1 seconds after querying F34 status to
* avoid not get attention by following giving erase command */ * avoid not get attention by following giving erase command */
if (flash->bootloader_id[1] == 8) if (flash->bootloader_id[1] >= 8)
g_usleep(1000 * 1000); g_usleep(1000 * 1000);
if (!fu_synaptics_rmi_device_write(self, if (!fu_synaptics_rmi_device_write(self,
f34->data_base + 1, f34->data_base + 1,
@ -156,7 +206,7 @@ fu_synaptics_rmi_v7_device_erase_all(FuSynapticsRmiDevice *self, GError **error)
return FALSE; return FALSE;
} }
g_usleep(1000 * 100); g_usleep(1000 * 100);
if (flash->bootloader_id[1] == 8) { if (flash->bootloader_id[1] >= 8) {
/* wait for ATTN */ /* wait for ATTN */
if (!fu_synaptics_rmi_device_wait_for_idle(self, if (!fu_synaptics_rmi_device_wait_for_idle(self,
RMI_F34_ERASE_WAIT_MS, RMI_F34_ERASE_WAIT_MS,
@ -422,6 +472,133 @@ fu_synaptics_rmi_v7_device_write_partition(FuSynapticsRmiDevice *self,
return TRUE; return TRUE;
} }
GBytes *
fu_synaptics_rmi_v7_device_get_pubkey(FuSynapticsRmiDevice *self, GError **error)
{
FuSynapticsRmiFlash *flash = fu_synaptics_rmi_device_get_flash(self);
FuSynapticsRmiFunction *f34;
const gsize key_size = RMI_KEY_SIZE_2K;
g_autoptr(GByteArray) req_addr_zero = g_byte_array_new();
g_autoptr(GByteArray) req_cmd = g_byte_array_new();
g_autoptr(GByteArray) req_partition_id = g_byte_array_new();
g_autoptr(GByteArray) req_transfer_length = g_byte_array_new();
g_autoptr(GByteArray) res = NULL;
g_autoptr(GByteArray) pubkey = g_byte_array_new();
/* f34 */
f34 = fu_synaptics_rmi_device_get_function(self, 0x34, error);
if (f34 == NULL)
return NULL;
/* set partition id for bootloader 7 */
fu_byte_array_append_uint8(req_partition_id, RMI_PARTITION_ID_PUBKEY);
if (!fu_synaptics_rmi_device_write(self,
f34->data_base + 0x1,
req_partition_id,
FU_SYNAPTICS_RMI_DEVICE_FLAG_NONE,
error)) {
g_prefix_error(error, "failed to write flash partition id: ");
return NULL;
}
fu_byte_array_append_uint16(req_addr_zero, 0x0, G_LITTLE_ENDIAN);
if (!fu_synaptics_rmi_device_write(self,
f34->data_base + 0x2,
req_addr_zero,
FU_SYNAPTICS_RMI_DEVICE_FLAG_NONE,
error)) {
g_prefix_error(error, "failed to write flash config address: ");
return NULL;
}
/* set transfer length */
fu_byte_array_append_uint16(req_transfer_length,
key_size / flash->block_size,
G_LITTLE_ENDIAN);
if (!fu_synaptics_rmi_device_write(self,
f34->data_base + 0x3,
req_transfer_length,
FU_SYNAPTICS_RMI_DEVICE_FLAG_NONE,
error)) {
g_prefix_error(error, "failed to set transfer length: ");
return NULL;
}
/* set command to read */
fu_byte_array_append_uint8(req_cmd, RMI_FLASH_CMD_READ);
if (!fu_synaptics_rmi_device_write(self,
f34->data_base + 0x4,
req_cmd,
FU_SYNAPTICS_RMI_DEVICE_FLAG_NONE,
error)) {
g_prefix_error(error, "failed to write command to read: ");
return NULL;
}
if (!fu_synaptics_rmi_device_poll_wait(self, error)) {
g_prefix_error(error, "failed to wait: ");
return NULL;
}
/* read back entire buffer in blocks */
res = fu_synaptics_rmi_device_read(self, f34->data_base + 0x5, (guint32)key_size, error);
if (res == NULL) {
g_prefix_error(error, "failed to read: ");
return NULL;
}
for (guint i = 0; i < res->len; i++)
fu_byte_array_append_uint8(pubkey, res->data[res->len - i - 1]);
/* success */
return g_byte_array_free_to_bytes(g_steal_pointer(&pubkey));
}
gboolean
fu_synaptics_rmi_v7_device_secure_check(FuSynapticsRmiDevice *self,
FuFirmware *firmware,
GError **error)
{
FuSynapticsRmiFlash *flash = fu_synaptics_rmi_device_get_flash(self);
g_autoptr(GBytes) pubkey = NULL;
g_autoptr(GPtrArray) imgs = NULL;
if (flash->bootloader_id[1] >= 10 || flash->has_pubkey == FALSE)
return TRUE;
pubkey = fu_synaptics_rmi_v7_device_get_pubkey(self, error);
if (pubkey == NULL) {
g_prefix_error(error, "get pubkey failed: ");
return FALSE;
}
imgs = fu_firmware_get_images(firmware);
for (guint i = 0; i < imgs->len; i++) {
FuFirmware *img = g_ptr_array_index(imgs, i);
const gchar *id = fu_firmware_get_id(img);
g_autoptr(GBytes) byte_payload = NULL;
g_autoptr(GBytes) byte_signature = NULL;
g_autofree gchar *id_signature = NULL;
if (g_str_has_suffix(id, "-signature"))
continue;
id_signature = g_strdup_printf("%s-signature", id);
byte_signature = fu_firmware_get_image_by_id_bytes(firmware, id_signature, NULL);
if (byte_signature == NULL)
continue;
byte_payload = fu_firmware_get_bytes(img, error);
if (byte_payload == NULL)
return FALSE;
if (!fu_synaptics_verify_sha256_signature(byte_payload,
pubkey,
byte_signature,
error)) {
g_prefix_error(error, "%s secure check failed: ", id);
return FALSE;
}
g_debug("%s signature verified successfully", id);
}
return TRUE;
}
gboolean gboolean
fu_synaptics_rmi_v7_device_write_firmware(FuDevice *device, fu_synaptics_rmi_v7_device_write_firmware(FuDevice *device,
FuFirmware *firmware, FuFirmware *firmware,
@ -441,15 +618,46 @@ fu_synaptics_rmi_v7_device_write_firmware(FuDevice *device,
/* progress */ /* progress */
fu_progress_set_id(progress, G_STRLOC); fu_progress_set_id(progress, G_STRLOC);
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED); if (flash->bootloader_id[1] > 8) {
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0, "disable-sleep"); fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0, "disable-sleep");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 2, "fixed-location-data"); fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_READ, 0, "verify-signature");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 3, NULL); fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 1, "fixed-location-data");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 0, "flash-config"); fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 8, "flash-config");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 89, "core-code"); fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 9, NULL);
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 2, "core-config"); fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 81, "core-code");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 2, "external-touch-afe-config"); fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 1, "core-config");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 2, "display-config"); fu_progress_add_step(progress,
FWUPD_STATUS_DEVICE_WRITE,
0,
"external-touch-afe-config");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 0, "display-config");
} else if (flash->bootloader_id[1] == 8) {
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0, "disable-sleep");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_READ, 0, "verify-signature");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 0, "fixed-location-data");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 16, NULL);
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 0, "flash-config");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 81, "core-code");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 1, "core-config");
fu_progress_add_step(progress,
FWUPD_STATUS_DEVICE_WRITE,
0,
"external-touch-afe-config");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 0, "display-config");
} else {
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0, "disable-sleep");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_READ, 2, "verify-signature");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 2, "fixed-location-data");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 3, NULL);
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 89, "core-code");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 2, "core-config");
fu_progress_add_step(progress,
FWUPD_STATUS_DEVICE_WRITE,
2,
"external-touch-afe-config");
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 2, "display-config");
}
/* we should be in bootloader mode now, but check anyway */ /* we should be in bootloader mode now, but check anyway */
if (!fu_device_has_flag(device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER)) { if (!fu_device_has_flag(device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER)) {
@ -472,7 +680,7 @@ fu_synaptics_rmi_v7_device_write_firmware(FuDevice *device,
bytes_cfg = fu_firmware_get_image_by_id_bytes(firmware, "config", error); bytes_cfg = fu_firmware_get_image_by_id_bytes(firmware, "config", error);
if (bytes_cfg == NULL) if (bytes_cfg == NULL)
return FALSE; return FALSE;
if (flash->bootloader_id[1] == 8) { if (flash->bootloader_id[1] >= 8) {
bytes_flashcfg = fu_firmware_get_image_by_id_bytes(firmware, "flash-config", error); bytes_flashcfg = fu_firmware_get_image_by_id_bytes(firmware, "flash-config", error);
if (bytes_flashcfg == NULL) if (bytes_flashcfg == NULL)
return FALSE; return FALSE;
@ -486,6 +694,11 @@ fu_synaptics_rmi_v7_device_write_firmware(FuDevice *device,
return FALSE; return FALSE;
fu_progress_step_done(progress); fu_progress_step_done(progress);
/* verify signature */
if (!fu_synaptics_rmi_v7_device_secure_check(self, firmware, error))
return FALSE;
fu_progress_step_done(progress);
/* write fld before erase if exists */ /* write fld before erase if exists */
if (bytes_fld != NULL) { if (bytes_fld != NULL) {
if (!fu_synaptics_rmi_v7_device_write_partition( if (!fu_synaptics_rmi_v7_device_write_partition(
@ -500,15 +713,12 @@ fu_synaptics_rmi_v7_device_write_firmware(FuDevice *device,
} }
fu_progress_step_done(progress); fu_progress_step_done(progress);
/* erase all */ /* write flash config for BL > v8 */
if (!fu_synaptics_rmi_v7_device_erase_all(self, error)) { if (flash->bootloader_id[1] > 8) {
g_prefix_error(error, "failed to erase all: "); if (!fu_synaptics_rmi_v7_device_erase_partition(self,
return FALSE; RMI_PARTITION_ID_FLASH_CONFIG,
} error))
fu_progress_step_done(progress); return FALSE;
/* write flash config for v8 */
if (bytes_flashcfg != NULL) {
if (!fu_synaptics_rmi_v7_device_write_partition(self, if (!fu_synaptics_rmi_v7_device_write_partition(self,
firmware, firmware,
"flash-config", "flash-config",
@ -517,9 +727,29 @@ fu_synaptics_rmi_v7_device_write_firmware(FuDevice *device,
fu_progress_get_child(progress), fu_progress_get_child(progress),
error)) error))
return FALSE; return FALSE;
fu_progress_step_done(progress);
}
/* erase all */
if (!fu_synaptics_rmi_v7_device_erase_all(self, error)) {
g_prefix_error(error, "failed to erase all: ");
return FALSE;
} }
fu_progress_step_done(progress); fu_progress_step_done(progress);
/* write flash config for v8 */
if (flash->bootloader_id[1] == 8) {
if (!fu_synaptics_rmi_v7_device_write_partition(self,
firmware,
"flash-config",
RMI_PARTITION_ID_FLASH_CONFIG,
bytes_flashcfg,
fu_progress_get_child(progress),
error))
return FALSE;
fu_progress_step_done(progress);
}
/* write core code */ /* write core code */
if (!fu_synaptics_rmi_v7_device_write_partition(self, if (!fu_synaptics_rmi_v7_device_write_partition(self,
firmware, firmware,
@ -692,6 +922,10 @@ fu_synaptics_rmi_device_read_flash_config_v7(FuSynapticsRmiDevice *self, GError
flash->block_count_fw = tbl.partition_len; flash->block_count_fw = tbl.partition_len;
continue; continue;
} }
if (tbl.partition_id == RMI_PARTITION_ID_PUBKEY) {
flash->has_pubkey = TRUE;
continue;
}
if (tbl.partition_id == RMI_PARTITION_ID_NONE) if (tbl.partition_id == RMI_PARTITION_ID_NONE)
break; break;
} }

View File

@ -20,3 +20,9 @@ gboolean
fu_synaptics_rmi_v7_device_setup(FuSynapticsRmiDevice *self, GError **error); fu_synaptics_rmi_v7_device_setup(FuSynapticsRmiDevice *self, GError **error);
gboolean gboolean
fu_synaptics_rmi_v7_device_query_status(FuSynapticsRmiDevice *self, GError **error); fu_synaptics_rmi_v7_device_query_status(FuSynapticsRmiDevice *self, GError **error);
gboolean
fu_synaptics_rmi_v7_device_secure_check(FuSynapticsRmiDevice *self,
FuFirmware *firmware,
GError **error);
GBytes *
fu_synaptics_rmi_v7_device_get_pubkey(FuSynapticsRmiDevice *self, GError **error);