Coverage Report

Created: 2025-11-24 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fwupd/plugins/genesys/fu-genesys-scaler-firmware.c
Line
Count
Source
1
/*
2
 * Copyright 2021 Gaƫl PORTAY <gael.portay@collabora.com>
3
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
5
 */
6
7
#include "config.h"
8
9
#include "fu-genesys-common.h"
10
#include "fu-genesys-scaler-firmware.h"
11
12
struct _FuGenesysScalerFirmware {
13
  FuFirmware parent_instance;
14
  FuGenesysPublicKey public_key;
15
};
16
17
345
G_DEFINE_TYPE(FuGenesysScalerFirmware, fu_genesys_scaler_firmware, FU_TYPE_FIRMWARE)
18
345
19
345
static gboolean
20
345
fu_genesys_scaler_firmware_parse(FuFirmware *firmware,
21
345
         GInputStream *stream,
22
345
         FuFirmwareParseFlags flags,
23
345
         GError **error)
24
345
{
25
148
  FuGenesysScalerFirmware *self = FU_GENESYS_SCALER_FIRMWARE(firmware);
26
148
  gsize streamsz = 0;
27
148
  g_autoptr(FuFirmware) firmware_payload = fu_firmware_new();
28
148
  g_autoptr(FuFirmware) firmware_public_key = NULL;
29
148
  g_autoptr(GInputStream) stream_payload = NULL;
30
148
  g_autoptr(GBytes) blob_public_key = NULL;
31
32
148
  if (!fu_input_stream_size(stream, &streamsz, error))
33
0
    return FALSE;
34
148
  if (streamsz < sizeof(self->public_key)) {
35
39
    g_set_error_literal(error,
36
39
            FWUPD_ERROR,
37
39
            FWUPD_ERROR_INVALID_DATA,
38
39
            "image is too small");
39
39
    return FALSE;
40
39
  }
41
109
  if (!fu_input_stream_read_safe(stream,
42
109
               (guint8 *)&self->public_key,
43
109
               sizeof(self->public_key),
44
109
               0,           /* dst */
45
109
               streamsz - sizeof(self->public_key), /* src */
46
109
               sizeof(self->public_key),
47
109
               error))
48
0
    return FALSE;
49
109
  fu_dump_raw(G_LOG_DOMAIN,
50
109
        "PublicKey",
51
109
        (const guint8 *)&self->public_key,
52
109
        sizeof(self->public_key));
53
109
  if (memcmp(self->public_key.N, "N = ", 4) != 0 ||
54
60
      memcmp(self->public_key.E, "E = ", 4) != 0) {
55
58
    g_set_error_literal(error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "invalid public-key");
56
58
    return FALSE;
57
58
  }
58
59
  /* set payload */
60
51
  stream_payload =
61
51
      fu_partial_input_stream_new(stream, 0, streamsz - sizeof(self->public_key), error);
62
51
  if (stream_payload == NULL)
63
0
    return FALSE;
64
51
  if (!fu_firmware_parse_stream(firmware_payload, stream_payload, 0x0, flags, error))
65
2
    return FALSE;
66
49
  fu_firmware_set_id(firmware_payload, FU_FIRMWARE_ID_PAYLOAD);
67
49
  if (!fu_firmware_add_image(firmware, firmware_payload, error))
68
0
    return FALSE;
69
70
  /* set public-key */
71
49
  blob_public_key = g_bytes_new(&self->public_key, sizeof(self->public_key));
72
49
  firmware_public_key = fu_firmware_new_from_bytes(blob_public_key);
73
49
  fu_firmware_set_id(firmware_public_key, FU_FIRMWARE_ID_SIGNATURE);
74
49
  if (!fu_firmware_add_image(firmware, firmware_public_key, error))
75
0
    return FALSE;
76
77
  /* success */
78
49
  return TRUE;
79
49
}
80
81
static void
82
fu_genesys_scaler_firmware_export(FuFirmware *firmware,
83
          FuFirmwareExportFlags flags,
84
          XbBuilderNode *bn)
85
0
{
86
0
  FuGenesysScalerFirmware *self = FU_GENESYS_SCALER_FIRMWARE(firmware);
87
0
  gchar N[0x200 + 1] = {'\0'};
88
0
  gchar E[0x006 + 1] = {'\0'};
89
90
0
  memcpy(N, self->public_key.N + 4, sizeof(N) - 1); /* nocheck:blocked */
91
0
  fu_xmlb_builder_insert_kv(bn, "N", N);
92
93
0
  memcpy(E, self->public_key.E + 4, sizeof(E) - 1); /* nocheck:blocked */
94
0
  fu_xmlb_builder_insert_kv(bn, "E", E);
95
0
}
96
97
static gboolean
98
fu_genesys_scaler_firmware_build(FuFirmware *firmware, XbNode *n, GError **error)
99
0
{
100
0
  FuGenesysScalerFirmware *self = FU_GENESYS_SCALER_FIRMWARE(firmware);
101
0
  const gchar *tmp;
102
103
  /* optional properties */
104
0
  tmp = xb_node_query_text(n, "N", NULL);
105
0
  if (tmp != NULL) {
106
0
    if (!fu_memcpy_safe((guint8 *)&self->public_key.N,
107
0
            sizeof(self->public_key.N),
108
0
            0x0, /* dst */
109
0
            (const guint8 *)tmp,
110
0
            strlen(tmp),
111
0
            0x0, /* src */
112
0
            strlen(tmp),
113
0
            error))
114
0
      return FALSE;
115
0
  }
116
117
0
  tmp = xb_node_query_text(n, "E", NULL);
118
0
  if (tmp != NULL) {
119
0
    if (!fu_memcpy_safe((guint8 *)&self->public_key.E,
120
0
            sizeof(self->public_key.E),
121
0
            0x0, /* dst */
122
0
            (const guint8 *)tmp,
123
0
            strlen(tmp),
124
0
            0x0, /* src */
125
0
            strlen(tmp),
126
0
            error))
127
0
      return FALSE;
128
0
  }
129
130
  /* success */
131
0
  return TRUE;
132
0
}
133
134
static GByteArray *
135
fu_genesys_scaler_firmware_write(FuFirmware *firmware, GError **error)
136
49
{
137
49
  FuGenesysScalerFirmware *self = FU_GENESYS_SCALER_FIRMWARE(firmware);
138
49
  g_autoptr(GByteArray) buf = g_byte_array_new();
139
49
  g_autoptr(GBytes) blob = NULL;
140
141
  /* payload */
142
49
  blob = fu_firmware_get_bytes(firmware, error);
143
49
  if (blob == NULL)
144
49
    return NULL;
145
0
  fu_byte_array_append_bytes(buf, blob);
146
147
  /* public-key */
148
0
  g_byte_array_append(buf, (const guint8 *)&self->public_key, sizeof(self->public_key));
149
150
  /* success */
151
0
  return g_steal_pointer(&buf);
152
49
}
153
154
static void
155
fu_genesys_scaler_firmware_init(FuGenesysScalerFirmware *self)
156
148
{
157
148
}
158
159
static void
160
fu_genesys_scaler_firmware_class_init(FuGenesysScalerFirmwareClass *klass)
161
1
{
162
1
  FuFirmwareClass *firmware_class = FU_FIRMWARE_CLASS(klass);
163
1
  firmware_class->parse = fu_genesys_scaler_firmware_parse;
164
1
  firmware_class->export = fu_genesys_scaler_firmware_export;
165
1
  firmware_class->build = fu_genesys_scaler_firmware_build;
166
1
  firmware_class->write = fu_genesys_scaler_firmware_write;
167
1
}
168
169
FuFirmware *
170
fu_genesys_scaler_firmware_new(void)
171
0
{
172
0
  return FU_FIRMWARE(g_object_new(FU_TYPE_GENESYS_SCALER_FIRMWARE, NULL));
173
0
}