mirror of
https://git.proxmox.com/git/fwupd
synced 2025-07-25 08:11:52 +00:00
genesys: scaler: Remove FuGenesysMtkFooter and XOR encryption
This commit is contained in:
parent
0c8079b13c
commit
0fbd5e17fe
@ -15,6 +15,8 @@
|
||||
#include "fu-genesys-scaler-device.h"
|
||||
#include "fu-genesys-scaler-firmware.h"
|
||||
|
||||
#define GENESYS_SCALER_BANK_SIZE 0x200000U
|
||||
|
||||
#define GENESYS_SCALER_MSTAR_READ 0x7a
|
||||
#define GENESYS_SCALER_MSTAR_WRITE 0x7b
|
||||
#define GENESYS_SCALER_MSTAR_DATA_OUT 0x7c
|
||||
@ -72,7 +74,6 @@ struct _FuGenesysScalerDevice {
|
||||
guint16 gpio_out_reg;
|
||||
guint16 gpio_en_reg;
|
||||
guint8 gpio_val;
|
||||
FuGenesysMtkFooter footer;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FuGenesysScalerDevice, fu_genesys_scaler_device, FU_TYPE_DEVICE)
|
||||
@ -1720,70 +1721,27 @@ fu_genesys_scaler_device_prepare_firmware(FuDevice *device,
|
||||
{
|
||||
FuGenesysScalerDevice *self = FU_GENESYS_SCALER_DEVICE(device);
|
||||
g_autoptr(FuFirmware) firmware = fu_genesys_scaler_firmware_new();
|
||||
g_autoptr(FuFirmware) footer = fu_firmware_new();
|
||||
g_autoptr(FuFirmware) payload = fu_firmware_new();
|
||||
g_autoptr(GBytes) fw_payload = NULL;
|
||||
g_autoptr(GBytes) fw_footer = NULL;
|
||||
g_autoptr(GBytes) blob_payload = NULL;
|
||||
g_autoptr(GBytes) blob_public_key = NULL;
|
||||
|
||||
/* parse firmware */
|
||||
if (!fu_firmware_parse(firmware, fw, flags, error))
|
||||
return NULL;
|
||||
|
||||
/* payload */
|
||||
fw_payload = fu_common_bytes_new_offset(fw,
|
||||
0,
|
||||
g_bytes_get_size(fw) - sizeof(FuGenesysMtkFooter),
|
||||
error);
|
||||
if (fw_payload == NULL)
|
||||
/* check public-key */
|
||||
blob_public_key =
|
||||
fu_firmware_get_image_by_id_bytes(firmware, FU_FIRMWARE_ID_SIGNATURE, error);
|
||||
if (blob_public_key == NULL)
|
||||
return NULL;
|
||||
if (!fu_firmware_parse(payload, fw_payload, flags, error))
|
||||
return NULL;
|
||||
fu_firmware_set_id(payload, FU_FIRMWARE_ID_PAYLOAD);
|
||||
fu_firmware_add_image(firmware, payload);
|
||||
|
||||
/* check size */
|
||||
if (g_bytes_get_size(fw_payload) > fu_device_get_firmware_size_max(device)) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"firmware too large, got 0x%x, expected <= 0x%x",
|
||||
(guint)g_bytes_get_size(fw_payload),
|
||||
(guint)fu_device_get_firmware_size_max(device));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* footer */
|
||||
fw_footer = fu_common_bytes_new_offset(fw,
|
||||
g_bytes_get_size(fw) - sizeof(FuGenesysMtkFooter),
|
||||
sizeof(FuGenesysMtkFooter),
|
||||
error);
|
||||
if (!fu_firmware_parse(footer, fw_footer, flags, error))
|
||||
return NULL;
|
||||
if (!fu_memcpy_safe((guint8 *)&self->footer,
|
||||
sizeof(self->footer),
|
||||
0, /* dst */
|
||||
g_bytes_get_data(fw_footer, NULL),
|
||||
g_bytes_get_size(fw_footer),
|
||||
0, /* src */
|
||||
sizeof(self->footer),
|
||||
error))
|
||||
return NULL;
|
||||
fu_genesys_scaler_firmware_decrypt((guint8 *)&self->footer, sizeof(self->footer));
|
||||
if (g_getenv("FWUPD_GENESYS_SCALER_VERBOSE") != NULL) {
|
||||
fu_common_dump_raw(G_LOG_DOMAIN,
|
||||
"Footer",
|
||||
(const guint8 *)&self->footer,
|
||||
sizeof(self->footer));
|
||||
"PublicKey",
|
||||
g_bytes_get_data(blob_public_key, NULL),
|
||||
g_bytes_get_size(blob_public_key));
|
||||
}
|
||||
if (memcmp(self->footer.data.header.default_head,
|
||||
MTK_RSA_HEADER,
|
||||
sizeof(self->footer.data.header.default_head)) != 0) {
|
||||
g_set_error_literal(error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "invalid footer");
|
||||
return NULL;
|
||||
}
|
||||
if (memcmp(&self->footer.data.public_key,
|
||||
if (memcmp(g_bytes_get_data(blob_public_key, NULL),
|
||||
&self->public_key,
|
||||
sizeof(self->footer.data.public_key) && sizeof(self->public_key)) != 0 &&
|
||||
sizeof(self->public_key)) != 0 &&
|
||||
(flags & FWUPD_INSTALL_FLAG_FORCE) == 0) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
@ -1791,8 +1749,20 @@ fu_genesys_scaler_device_prepare_firmware(FuDevice *device,
|
||||
"mismatch public-key");
|
||||
return NULL;
|
||||
}
|
||||
fu_firmware_set_id(footer, FU_FIRMWARE_ID_HEADER);
|
||||
fu_firmware_add_image(firmware, footer);
|
||||
|
||||
/* check size */
|
||||
blob_payload = fu_firmware_get_image_by_id_bytes(firmware, FU_FIRMWARE_ID_PAYLOAD, error);
|
||||
if (blob_payload == NULL)
|
||||
return NULL;
|
||||
if (g_bytes_get_size(blob_payload) > fu_device_get_firmware_size_max(device)) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"firmware too large, got 0x%x, expected <= 0x%x",
|
||||
(guint)g_bytes_get_size(blob_payload),
|
||||
(guint)fu_device_get_firmware_size_max(device));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* success */
|
||||
return g_steal_pointer(&firmware);
|
||||
@ -1806,7 +1776,7 @@ fu_genesys_scaler_device_write_firmware(FuDevice *device,
|
||||
GError **error)
|
||||
{
|
||||
FuGenesysScalerDevice *self = FU_GENESYS_SCALER_DEVICE(device);
|
||||
guint addr = fu_firmware_get_addr(firmware);
|
||||
guint addr = 0;
|
||||
gsize size;
|
||||
const guint8 *data;
|
||||
g_autofree guint8 *buf = NULL;
|
||||
@ -1818,11 +1788,8 @@ fu_genesys_scaler_device_write_firmware(FuDevice *device,
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 54, NULL);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 42, NULL);
|
||||
|
||||
/* sanity check */
|
||||
if (fu_device_has_flag(device, FWUPD_DEVICE_FLAG_DUAL_IMAGE) && addr == 0) {
|
||||
g_set_error(error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "invalid address");
|
||||
return FALSE;
|
||||
}
|
||||
if (fu_device_has_flag(device, FWUPD_DEVICE_FLAG_DUAL_IMAGE))
|
||||
addr = GENESYS_SCALER_BANK_SIZE;
|
||||
|
||||
payload = fu_firmware_get_image_by_id(firmware, FU_FIRMWARE_ID_PAYLOAD, error);
|
||||
if (payload == NULL)
|
||||
|
@ -12,26 +12,11 @@
|
||||
|
||||
struct _FuGenesysScalerFirmware {
|
||||
FuFirmwareClass parent_instance;
|
||||
FuGenesysMtkFooter footer;
|
||||
guint protect_sector_addr[2];
|
||||
gsize protect_sector_size[2];
|
||||
guint public_key_addr;
|
||||
gsize public_key_size;
|
||||
guint second_image_program_addr;
|
||||
FuGenesysPublicKey public_key;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FuGenesysScalerFirmware, fu_genesys_scaler_firmware, FU_TYPE_FIRMWARE)
|
||||
|
||||
void
|
||||
fu_genesys_scaler_firmware_decrypt(guint8 *buf, gsize bufsz)
|
||||
{
|
||||
const gchar *key = "mstar";
|
||||
const gsize keylen = strlen(key);
|
||||
|
||||
for (guint i = 0; i < bufsz; i++)
|
||||
buf[i] ^= key[i % keylen];
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_genesys_scaler_firmware_parse(FuFirmware *firmware,
|
||||
GBytes *fw,
|
||||
@ -43,87 +28,41 @@ fu_genesys_scaler_firmware_parse(FuFirmware *firmware,
|
||||
FuGenesysScalerFirmware *self = FU_GENESYS_SCALER_FIRMWARE(firmware);
|
||||
gsize bufsz = 0;
|
||||
const guint8 *buf = g_bytes_get_data(fw, &bufsz);
|
||||
g_autoptr(FuFirmware) firmware_payload = NULL;
|
||||
g_autoptr(FuFirmware) firmware_public_key = NULL;
|
||||
g_autoptr(GBytes) blob_payload = NULL;
|
||||
g_autoptr(GBytes) blob_public_key = NULL;
|
||||
|
||||
if (!fu_memcpy_safe((guint8 *)&self->footer,
|
||||
sizeof(self->footer),
|
||||
if (!fu_memcpy_safe((guint8 *)&self->public_key,
|
||||
sizeof(self->public_key),
|
||||
0, /* dst */
|
||||
buf,
|
||||
bufsz,
|
||||
bufsz - sizeof(self->footer), /* src */
|
||||
sizeof(self->footer),
|
||||
bufsz - sizeof(self->public_key), /* src */
|
||||
sizeof(self->public_key),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_genesys_scaler_firmware_decrypt((guint8 *)&self->footer, sizeof(self->footer));
|
||||
if (memcmp(self->footer.data.header.default_head,
|
||||
MTK_RSA_HEADER,
|
||||
sizeof(self->footer.data.header.default_head)) != 0) {
|
||||
g_autofree gchar *str = NULL;
|
||||
str = fu_common_strsafe((const gchar *)self->footer.data.header.default_head,
|
||||
sizeof(self->footer.data.header.default_head));
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"invalid footer, expected %s, and got %s",
|
||||
MTK_RSA_HEADER,
|
||||
str);
|
||||
fu_common_dump_raw(G_LOG_DOMAIN,
|
||||
"PublicKey",
|
||||
(const guint8 *)&self->public_key,
|
||||
sizeof(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_INTERNAL, "invalid public-key");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (self->footer.data.header.configuration_setting.bits.second_image) {
|
||||
guint32 addr;
|
||||
if (!fu_common_read_uint32_safe(
|
||||
self->footer.data.header.second_image_program_addr,
|
||||
sizeof(self->footer.data.header.second_image_program_addr),
|
||||
0,
|
||||
&addr,
|
||||
G_LITTLE_ENDIAN,
|
||||
error))
|
||||
return FALSE;
|
||||
if (addr % GENESYS_SCALER_BANK_SIZE != 0) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"invalid address, expected a multiple of 0x%x, and got 0x%x",
|
||||
GENESYS_SCALER_BANK_SIZE,
|
||||
addr);
|
||||
return FALSE;
|
||||
}
|
||||
self->second_image_program_addr = addr;
|
||||
fu_firmware_set_addr(firmware, addr);
|
||||
}
|
||||
if (self->footer.data.header.configuration_setting.bits.decrypt_mode) {
|
||||
if (!fu_common_read_uint32_safe(
|
||||
self->footer.data.header.scaler_public_key_addr,
|
||||
sizeof(self->footer.data.header.scaler_public_key_addr),
|
||||
0,
|
||||
&self->public_key_addr,
|
||||
G_LITTLE_ENDIAN,
|
||||
error))
|
||||
return FALSE;
|
||||
self->public_key_size = 0x1000;
|
||||
}
|
||||
/* set payload */
|
||||
blob_payload = g_bytes_new(buf, bufsz - sizeof(self->public_key));
|
||||
firmware_payload = fu_firmware_new_from_bytes(blob_payload);
|
||||
fu_firmware_set_id(firmware_payload, FU_FIRMWARE_ID_PAYLOAD);
|
||||
fu_firmware_add_image(firmware, firmware_payload);
|
||||
|
||||
if (self->footer.data.header.configuration_setting.bits.special_protect_sector) {
|
||||
if (self->footer.data.header.protect_sector[0].area.size) {
|
||||
self->protect_sector_addr[0] =
|
||||
(self->footer.data.header.protect_sector[0].area.addr_high << 16) |
|
||||
(self->footer.data.header.protect_sector[0].area.addr_low[1] << 8) |
|
||||
(self->footer.data.header.protect_sector[0].area.addr_low[0]);
|
||||
self->protect_sector_addr[0] *= 0x1000;
|
||||
self->protect_sector_size[0] =
|
||||
self->footer.data.header.protect_sector[0].area.size * 0x1000;
|
||||
}
|
||||
|
||||
if (self->footer.data.header.protect_sector[1].area.size) {
|
||||
self->protect_sector_addr[1] =
|
||||
(self->footer.data.header.protect_sector[1].area.addr_high << 16) |
|
||||
(self->footer.data.header.protect_sector[1].area.addr_low[1] << 8) |
|
||||
(self->footer.data.header.protect_sector[1].area.addr_low[0]);
|
||||
self->protect_sector_addr[1] *= 0x1000;
|
||||
self->protect_sector_size[1] =
|
||||
self->footer.data.header.protect_sector[1].area.size * 0x1000;
|
||||
}
|
||||
}
|
||||
/* set public-key */
|
||||
blob_public_key = g_bytes_new(&self->public_key, sizeof(self->public_key));
|
||||
firmware_public_key = fu_firmware_new_from_bytes(blob_public_key);
|
||||
fu_firmware_set_id(firmware_public_key, FU_FIRMWARE_ID_SIGNATURE);
|
||||
fu_firmware_add_image(firmware, firmware_public_key);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
@ -135,82 +74,14 @@ fu_genesys_scaler_firmware_export(FuFirmware *firmware,
|
||||
XbBuilderNode *bn)
|
||||
{
|
||||
FuGenesysScalerFirmware *self = FU_GENESYS_SCALER_FIRMWARE(firmware);
|
||||
gchar N[0x200 + 1] = {'\0'};
|
||||
gchar E[0x006 + 1] = {'\0'};
|
||||
|
||||
if (self->footer.data.header.model_name[0] != '\0') {
|
||||
fu_xmlb_builder_insert_kv(bn,
|
||||
"model_name",
|
||||
(const gchar *)self->footer.data.header.model_name);
|
||||
}
|
||||
if (self->footer.data.header.scaler_group[0] != '\0') {
|
||||
fu_xmlb_builder_insert_kv(bn,
|
||||
"scaler_group",
|
||||
(const gchar *)self->footer.data.header.scaler_group);
|
||||
}
|
||||
if (self->footer.data.header.panel_type[0] != '\0') {
|
||||
fu_xmlb_builder_insert_kv(bn,
|
||||
"panel_type",
|
||||
(const gchar *)self->footer.data.header.panel_type);
|
||||
}
|
||||
if (self->footer.data.header.scaler_packet_date[0] != '\0') {
|
||||
fu_xmlb_builder_insert_kv(
|
||||
bn,
|
||||
"scaler_packet_date",
|
||||
(const gchar *)self->footer.data.header.scaler_packet_date);
|
||||
}
|
||||
if (self->footer.data.header.scaler_packet_version[0] != '\0') {
|
||||
fu_xmlb_builder_insert_kv(
|
||||
bn,
|
||||
"scaler_packet_version",
|
||||
(const gchar *)self->footer.data.header.scaler_packet_version);
|
||||
}
|
||||
fu_xmlb_builder_insert_kx(bn,
|
||||
"configuration_setting",
|
||||
self->footer.data.header.configuration_setting.r8);
|
||||
memcpy(N, self->public_key.N + 4, sizeof(N) - 1);
|
||||
fu_xmlb_builder_insert_kv(bn, "N", N);
|
||||
|
||||
if (self->footer.data.header.configuration_setting.bits.second_image)
|
||||
fu_xmlb_builder_insert_kx(bn,
|
||||
"second_image_program_addr",
|
||||
self->second_image_program_addr);
|
||||
|
||||
if (self->footer.data.header.configuration_setting.bits.decrypt_mode) {
|
||||
gchar N[0x200 + 1] = {'\0'};
|
||||
gchar E[0x006 + 1] = {'\0'};
|
||||
|
||||
fu_xmlb_builder_insert_kx(bn, "public_key_addr", self->public_key_addr);
|
||||
fu_xmlb_builder_insert_kx(bn, "public_key_size", self->public_key_size);
|
||||
|
||||
memcpy(N, self->footer.data.public_key.N + 4, sizeof(N) - 1);
|
||||
fu_xmlb_builder_insert_kv(bn, "N", N);
|
||||
|
||||
memcpy(E, self->footer.data.public_key.E + 4, sizeof(E) - 1);
|
||||
fu_xmlb_builder_insert_kv(bn, "E", E);
|
||||
}
|
||||
|
||||
if (self->footer.data.header.configuration_setting.bits.special_protect_sector) {
|
||||
if (self->protect_sector_size[0]) {
|
||||
fu_xmlb_builder_insert_kx(bn,
|
||||
"protect_sector_addr0",
|
||||
self->protect_sector_addr[0]);
|
||||
fu_xmlb_builder_insert_kx(bn,
|
||||
"protect_sector_size0",
|
||||
self->protect_sector_size[0]);
|
||||
}
|
||||
|
||||
if (self->protect_sector_size[1]) {
|
||||
fu_xmlb_builder_insert_kx(bn,
|
||||
"protect_sector_addr1",
|
||||
self->protect_sector_addr[1]);
|
||||
fu_xmlb_builder_insert_kx(bn,
|
||||
"protect_sector_size1",
|
||||
self->protect_sector_size[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (self->footer.data.header.configuration_setting.bits.boot_code_size_in_header) {
|
||||
fu_xmlb_builder_insert_kx(bn,
|
||||
"boot_code_size",
|
||||
self->footer.data.header.boot_code_size);
|
||||
}
|
||||
memcpy(E, self->public_key.E + 4, sizeof(E) - 1);
|
||||
fu_xmlb_builder_insert_kv(bn, "E", E);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -220,10 +91,23 @@ fu_genesys_scaler_firmware_build(FuFirmware *firmware, XbNode *n, GError **error
|
||||
const gchar *tmp;
|
||||
|
||||
/* optional properties */
|
||||
tmp = xb_node_query_text(n, "model_name", NULL);
|
||||
tmp = xb_node_query_text(n, "N", NULL);
|
||||
if (tmp != NULL) {
|
||||
if (!fu_memcpy_safe((guint8 *)&self->footer.data.header.model_name,
|
||||
sizeof(self->footer.data.header.model_name),
|
||||
if (!fu_memcpy_safe((guint8 *)&self->public_key.N,
|
||||
sizeof(self->public_key.N),
|
||||
0x0, /* dst */
|
||||
(const guint8 *)tmp,
|
||||
strlen(tmp),
|
||||
0x0, /* src */
|
||||
strlen(tmp),
|
||||
error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tmp = xb_node_query_text(n, "E", NULL);
|
||||
if (tmp != NULL) {
|
||||
if (!fu_memcpy_safe((guint8 *)&self->public_key.E,
|
||||
sizeof(self->public_key.E),
|
||||
0x0, /* dst */
|
||||
(const guint8 *)tmp,
|
||||
strlen(tmp),
|
||||
@ -241,7 +125,6 @@ static GBytes *
|
||||
fu_genesys_scaler_firmware_write(FuFirmware *firmware, GError **error)
|
||||
{
|
||||
FuGenesysScalerFirmware *self = FU_GENESYS_SCALER_FIRMWARE(firmware);
|
||||
FuGenesysMtkFooter footer = {0x0};
|
||||
g_autoptr(GByteArray) buf = g_byte_array_new();
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
|
||||
@ -251,27 +134,8 @@ fu_genesys_scaler_firmware_write(FuFirmware *firmware, GError **error)
|
||||
return NULL;
|
||||
fu_byte_array_append_bytes(buf, blob);
|
||||
|
||||
/* "encrypted" footer */
|
||||
if (!fu_memcpy_safe((guint8 *)&footer,
|
||||
sizeof(footer),
|
||||
0, /* dst */
|
||||
(guint8 *)&self->footer,
|
||||
sizeof(self->footer),
|
||||
0, /* src */
|
||||
sizeof(footer),
|
||||
error))
|
||||
return NULL;
|
||||
if (!fu_memcpy_safe((guint8 *)&footer.data.header.default_head,
|
||||
sizeof(footer.data.header.default_head),
|
||||
0, /* dst */
|
||||
(guint8 *)&MTK_RSA_HEADER,
|
||||
strlen(MTK_RSA_HEADER),
|
||||
0, /* src */
|
||||
strlen(MTK_RSA_HEADER),
|
||||
error))
|
||||
return NULL;
|
||||
fu_genesys_scaler_firmware_decrypt((guint8 *)&footer, sizeof(footer));
|
||||
g_byte_array_append(buf, (const guint8 *)&footer, sizeof(footer));
|
||||
/* public-key */
|
||||
g_byte_array_append(buf, (const guint8 *)&self->public_key, sizeof(self->public_key));
|
||||
|
||||
/* success */
|
||||
return g_byte_array_free_to_bytes(g_steal_pointer(&buf));
|
||||
|
@ -19,132 +19,5 @@ G_DECLARE_FINAL_TYPE(FuGenesysScalerFirmware,
|
||||
|
||||
#define GENESYS_SCALER_BANK_SIZE 0x200000U
|
||||
|
||||
#define MTK_RSA_HEADER "MTK_RSA_HEADER"
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
guint8 default_head[14];
|
||||
guint8 reserved_0e_0f[2];
|
||||
guint8 model_name[16];
|
||||
guint8 reserved_20;
|
||||
guint8 size[2];
|
||||
guint8 reserved_23_27[5];
|
||||
guint8 scaler_group[10];
|
||||
guint8 reserved_32_53[34];
|
||||
guint8 panel_type[10];
|
||||
guint8 scaler_packet_date[8];
|
||||
guint8 reserved_66_67[2];
|
||||
guint8 scaler_packet_version[4];
|
||||
guint8 reserved_6c_7f[20];
|
||||
union {
|
||||
guint8 r8;
|
||||
struct {
|
||||
/*
|
||||
* Decrypt Mode:
|
||||
*
|
||||
* 0: Scaler decrypt
|
||||
* 1: ISP Tool decrypt
|
||||
*/
|
||||
guint8 decrypt_mode : 1;
|
||||
|
||||
/*
|
||||
* Second Image:
|
||||
*
|
||||
* 0: 1st image or dual image; programming address at 0x000000
|
||||
* 1: 2nd image; programming address set by .second_image_program_addr
|
||||
*/
|
||||
guint8 second_image : 1;
|
||||
|
||||
/*
|
||||
* Dual image turn:
|
||||
*
|
||||
* 0: fix second programing address set by .second_image_program_addr
|
||||
* 1: support “Dual image turn” rule
|
||||
* - TSUM: Not supported
|
||||
* - MST9U: ISP Tool need update to DUT least version image address
|
||||
* - HAWK: Not supported
|
||||
*/
|
||||
guint8 dual_image_turn : 1;
|
||||
|
||||
/*
|
||||
* Special Protect Sector:
|
||||
*
|
||||
* 0: No Special Protect sector
|
||||
* 1: Support Special Protect sector
|
||||
*/
|
||||
guint8 special_protect_sector : 1;
|
||||
|
||||
/*
|
||||
* HAWK bypass mode
|
||||
*
|
||||
* 0: No support HAWK bypass mode
|
||||
* 1: Support HAWK bypass mode
|
||||
*/
|
||||
guint8 hawk_bypass_mode : 1;
|
||||
|
||||
/*
|
||||
* Boot Code Size in header
|
||||
*
|
||||
* 0: Follow original search bin address rule
|
||||
* 1: Get Boot code size from header set by .boot_code_size
|
||||
*/
|
||||
guint8 boot_code_size_in_header : 1;
|
||||
|
||||
/* Reserved */
|
||||
guint8 reserved_6_7 : 2;
|
||||
} __attribute__((packed)) bits;
|
||||
} configuration_setting;
|
||||
|
||||
guint8 reserved_81_85[5];
|
||||
|
||||
/* If configuration_setting.bits.second_image set */
|
||||
guint8 second_image_program_addr[4];
|
||||
|
||||
/*
|
||||
* If configuration_setting.bits.decrypt is set
|
||||
*
|
||||
* TSUM/HAWK: ISP Tool need protect flash public address can’t erase and write
|
||||
* MST9U: Not supported
|
||||
*/
|
||||
guint8 scaler_public_key_addr[4];
|
||||
|
||||
/*
|
||||
* If configuration_setting.bits.special_protect_sector is set
|
||||
*
|
||||
* ISP Tool can't erase "Special Protect Sector" area.
|
||||
*
|
||||
* [19:00]: Protect continuous sector start.
|
||||
* [23:20]: Protect sector continuous number.
|
||||
*
|
||||
* Examples: If need to protect FA000 ~FFFFF, Special Protect sector = 0x6000FA;
|
||||
* If need to protect FA000 only, Special Protect sector = 0x1000FA;
|
||||
* If no need to protect, Special Protect sector = 0x000000;
|
||||
*/
|
||||
union {
|
||||
guint8 r24[3];
|
||||
struct {
|
||||
guint8 addr_low[2];
|
||||
guint8 addr_high : 4;
|
||||
guint8 size : 4;
|
||||
} __attribute__((packed)) area;
|
||||
} protect_sector[2];
|
||||
|
||||
/*
|
||||
* If configuration.bits .second_image and .dual_image_turn are set
|
||||
* and .boot_code_size.
|
||||
*/
|
||||
guint32 boot_code_size;
|
||||
} FuGenesysMtkRsaHeader;
|
||||
|
||||
typedef union __attribute__((packed)) {
|
||||
guint8 raw[0x312];
|
||||
struct {
|
||||
FuGenesysPublicKey public_key;
|
||||
FuGenesysMtkRsaHeader header;
|
||||
} data;
|
||||
} FuGenesysMtkFooter;
|
||||
|
||||
void
|
||||
fu_genesys_scaler_firmware_decrypt(guint8 *buf, gsize bufsz);
|
||||
|
||||
FuFirmware *
|
||||
fu_genesys_scaler_firmware_new(void);
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user