/src/fwupd/libfwupdplugin/fu-xor.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2026 Richard Hughes <richard@hughsie.com> |
3 | | * |
4 | | * SPDX-License-Identifier: LGPL-2.1-or-later |
5 | | */ |
6 | | |
7 | 0 | #define G_LOG_DOMAIN "FuCommon" |
8 | | |
9 | | #include "config.h" |
10 | | |
11 | | #include "fu-mem-private.h" |
12 | | #include "fu-xor.h" |
13 | | |
14 | | /** |
15 | | * fu_xor8: |
16 | | * @buf: memory buffer |
17 | | * @bufsz: size of @buf |
18 | | * |
19 | | * Returns the bitwise XOR of all bytes in @buf. |
20 | | * |
21 | | * Returns: xor value |
22 | | * |
23 | | * Since: 2.1.1 |
24 | | **/ |
25 | | guint8 |
26 | | fu_xor8(const guint8 *buf, gsize bufsz) |
27 | 0 | { |
28 | 0 | guint8 tmp = 0; |
29 | 0 | g_return_val_if_fail(buf != NULL, G_MAXUINT8); |
30 | 0 | for (gsize i = 0; i < bufsz; i++) |
31 | 0 | tmp ^= buf[i]; |
32 | 0 | return tmp; |
33 | 0 | } |
34 | | |
35 | | /** |
36 | | * fu_xor8_safe: |
37 | | * @buf: source buffer |
38 | | * @bufsz: maximum size of @buf, typically `sizeof(buf)` |
39 | | * @offset: offset in bytes into @buf where XOR should start |
40 | | * @n: number of bytes to XOR from @buf |
41 | | * @value: (inout) (nullable): the initial value, and result |
42 | | * @error: (nullable): optional return location for an error |
43 | | * |
44 | | * Returns the bitwise XOR of all bytes in @buf in a safe way. |
45 | | * |
46 | | * You don't need to use this function in "obviously correct" cases, nor should |
47 | | * you use it when performance is a concern. Only use it when you're not sure if |
48 | | * malicious data from a device or firmware could cause memory corruption. |
49 | | * |
50 | | * Returns: %TRUE if @value was set, %FALSE otherwise |
51 | | * |
52 | | * Since: 2.1.1 |
53 | | **/ |
54 | | gboolean |
55 | | fu_xor8_safe(const guint8 *buf, gsize bufsz, gsize offset, gsize n, guint8 *value, GError **error) |
56 | 0 | { |
57 | 0 | g_return_val_if_fail(buf != NULL, FALSE); |
58 | 0 | g_return_val_if_fail(error == NULL || *error == NULL, FALSE); |
59 | | |
60 | 0 | if (!fu_memchk_read(bufsz, offset, n, error)) |
61 | 0 | return FALSE; |
62 | 0 | if (value != NULL) |
63 | 0 | *value ^= fu_xor8(buf + offset, n); |
64 | 0 | return TRUE; |
65 | 0 | } |