mirror of
https://git.proxmox.com/git/fwupd
synced 2025-05-02 16:45:45 +00:00
117 lines
2.6 KiB
C
117 lines
2.6 KiB
C
/*
|
|
* Copyright (C) 2018 Evan Lojewski
|
|
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
|
*
|
|
* SPDX-License-Identifier: GPL-2+
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <fwupdplugin.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "fu-bcm57xx-common.h"
|
|
|
|
guint32
|
|
fu_bcm57xx_nvram_crc(const guint8 *buf, gsize bufsz)
|
|
{
|
|
return fu_common_crc32(buf, bufsz);
|
|
}
|
|
|
|
gboolean
|
|
fu_bcm57xx_verify_crc(GBytes *fw, GError **error)
|
|
{
|
|
guint32 crc_actual;
|
|
guint32 crc_file = 0;
|
|
gsize bufsz = 0x0;
|
|
const guint8 *buf = g_bytes_get_data(fw, &bufsz);
|
|
|
|
/* expected */
|
|
if (!fu_common_read_uint32_safe(buf,
|
|
bufsz,
|
|
bufsz - sizeof(guint32),
|
|
&crc_file,
|
|
G_LITTLE_ENDIAN,
|
|
error))
|
|
return FALSE;
|
|
|
|
/* reality */
|
|
crc_actual = fu_bcm57xx_nvram_crc(buf, bufsz - sizeof(guint32));
|
|
if (crc_actual != crc_file) {
|
|
g_set_error(error,
|
|
FWUPD_ERROR,
|
|
FWUPD_ERROR_NOT_SUPPORTED,
|
|
"invalid CRC, expected 0x%08x got: 0x%08x",
|
|
(guint)crc_file,
|
|
(guint)crc_actual);
|
|
return FALSE;
|
|
}
|
|
|
|
/* success */
|
|
return TRUE;
|
|
}
|
|
|
|
gboolean
|
|
fu_bcm57xx_verify_magic(GBytes *fw, gsize offset, GError **error)
|
|
{
|
|
guint32 magic = 0;
|
|
gsize bufsz = 0x0;
|
|
const guint8 *buf = g_bytes_get_data(fw, &bufsz);
|
|
|
|
/* hardcoded value */
|
|
if (!fu_common_read_uint32_safe(buf, bufsz, offset, &magic, G_BIG_ENDIAN, error))
|
|
return FALSE;
|
|
if (magic != BCM_NVRAM_MAGIC) {
|
|
g_set_error(error,
|
|
FWUPD_ERROR,
|
|
FWUPD_ERROR_NOT_SUPPORTED,
|
|
"invalid magic, got: 0x%x",
|
|
(guint)magic);
|
|
return FALSE;
|
|
}
|
|
|
|
/* success */
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
fu_bcm57xx_veritem_free(Bcm57xxVeritem *veritem)
|
|
{
|
|
g_free(veritem->branch);
|
|
g_free(veritem->version);
|
|
g_free(veritem);
|
|
}
|
|
|
|
Bcm57xxVeritem *
|
|
fu_bcm57xx_veritem_new(const guint8 *buf, gsize bufsz)
|
|
{
|
|
g_autofree gchar *tmp = NULL;
|
|
g_autoptr(Bcm57xxVeritem) veritem = g_new0(Bcm57xxVeritem, 1);
|
|
struct {
|
|
const gchar *prefix;
|
|
const gchar *branch;
|
|
FwupdVersionFormat verfmt;
|
|
} data[] = {{"5719-v", BCM_FW_BRANCH_UNKNOWN, FWUPD_VERSION_FORMAT_PAIR},
|
|
{"stage1-", BCM_FW_BRANCH_OSS_FIRMWARE, FWUPD_VERSION_FORMAT_TRIPLET},
|
|
{NULL, NULL, 0}};
|
|
|
|
/* do not assume this is NUL terminated */
|
|
tmp = g_strndup((const gchar *)buf, bufsz);
|
|
if (tmp == NULL || tmp[0] == '\0')
|
|
return NULL;
|
|
|
|
/* use prefix to define object */
|
|
for (guint i = 0; data[i].prefix != NULL; i++) {
|
|
if (g_str_has_prefix(tmp, data[i].prefix)) {
|
|
veritem->version = g_strdup(tmp + strlen(data[i].prefix));
|
|
veritem->branch = g_strdup(data[i].branch);
|
|
veritem->verfmt = data[i].verfmt;
|
|
return g_steal_pointer(&veritem);
|
|
}
|
|
}
|
|
veritem->verfmt = FWUPD_VERSION_FORMAT_UNKNOWN;
|
|
veritem->version = g_strdup(tmp);
|
|
return g_steal_pointer(&veritem);
|
|
}
|