1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-12 13:18:14 +03:00

fundamental: Add HWID calculation

This commit is contained in:
anonymix007 2024-10-10 18:35:02 +03:00
parent 09f16de6d8
commit 26060eb7a0
3 changed files with 142 additions and 0 deletions

View File

@ -0,0 +1,120 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/*
* Based on Nikita Travkin's dtbloader implementation.
* Copyright (c) 2024 Nikita Travkin <nikita@trvn.ru>
*
* https://github.com/TravMurav/dtbloader/blob/main/src/chid.c
*/
/*
* Based on Linaro dtbloader implementation.
* Copyright (c) 2019, Linaro. All rights reserved.
*
* https://github.com/aarch64-laptops/edk2/blob/dtbloader-app/EmbeddedPkg/Application/ConfigTableLoader/CHID.c
*/
#if SD_BOOT
# include "efi-string.h"
# include "util.h"
#else
# include <byteswap.h>
# include <string.h>
# include <uchar.h>
# include <utf8.h>
#define strsize16(str) ((char16_strlen(str) + 1) * sizeof(char16_t))
#endif
#include "chid-fundamental.h"
#include "macro-fundamental.h"
#include "memory-util-fundamental.h"
#include "sha1-fundamental.h"
static void get_chid(const char16_t *const smbios_fields[static _CHID_SMBIOS_FIELDS_MAX], uint32_t mask, EFI_GUID *ret_chid) {
assert(mask != 0);
assert(ret_chid);
const EFI_GUID namespace = { UINT32_C(0x12d8ff70), UINT16_C(0x7f4c), UINT16_C(0x7d4c), {} }; /* Swapped to BE */
struct sha1_ctx ctx = {};
sha1_init_ctx(&ctx);
sha1_process_bytes(&namespace, sizeof(namespace), &ctx);
for (unsigned i = 0; i < _CHID_SMBIOS_FIELDS_MAX; i++)
if ((mask >> i) & 1) {
if (i > 0)
sha1_process_bytes(L"&", 2, &ctx);
sha1_process_bytes(smbios_fields[i], strsize16(smbios_fields[i]), &ctx);
}
uint8_t hash[SHA1_DIGEST_SIZE];
sha1_finish_ctx(&ctx, hash);
assert_cc(sizeof(hash) >= sizeof(*ret_chid));
memcpy(ret_chid, hash, sizeof(*ret_chid));
/* Convert the resulting CHID back to little-endian: */
ret_chid->Data1 = bswap_32(ret_chid->Data1);
ret_chid->Data2 = bswap_16(ret_chid->Data2);
ret_chid->Data3 = bswap_16(ret_chid->Data3);
/* set specific bits according to RFC4122 Section 4.1.3 */
ret_chid->Data3 = (ret_chid->Data3 & 0x0fff) | (5 << 12);
ret_chid->Data4[0] = (ret_chid->Data4[0] & UINT8_C(0x3f)) | UINT8_C(0x80);
}
static const uint32_t chid_smbios_table[CHID_TYPES_MAX] = {
[3] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_FAMILY) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_NAME) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_SKU) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_PRODUCT),
[4] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_FAMILY) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_NAME) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_SKU),
[5] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_FAMILY) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_NAME),
[6] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_SKU) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_PRODUCT),
[7] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_SKU),
[8] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_NAME) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_PRODUCT),
[9] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_PRODUCT_NAME),
[10] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_FAMILY) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_PRODUCT),
[11] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_FAMILY),
[13] = (UINT32_C(1) << CHID_SMBIOS_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_MANUFACTURER) |
(UINT32_C(1) << CHID_SMBIOS_BASEBOARD_PRODUCT),
};
void chid_calculate(const char16_t *const smbios_fields[static _CHID_SMBIOS_FIELDS_MAX], EFI_GUID ret_chids[static CHID_TYPES_MAX]) {
assert(smbios_fields);
assert(ret_chids);
for (size_t i = 0; i < _CHID_SMBIOS_FIELDS_MAX; i++)
if (chid_smbios_table[i] != 0)
get_chid(smbios_fields, chid_smbios_table[i], &ret_chids[i]);
else
memzero(&ret_chids[i], sizeof(EFI_GUID));
}

View File

@ -0,0 +1,21 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#pragma once
#include "efi-fundamental.h"
#include "string-util-fundamental.h"
#define CHID_TYPES_MAX 15
typedef enum ChidSmbiosFields {
CHID_SMBIOS_MANUFACTURER,
CHID_SMBIOS_FAMILY,
CHID_SMBIOS_PRODUCT_NAME,
CHID_SMBIOS_PRODUCT_SKU,
CHID_SMBIOS_BASEBOARD_MANUFACTURER,
CHID_SMBIOS_BASEBOARD_PRODUCT,
_CHID_SMBIOS_FIELDS_MAX,
} ChidSmbiosFields;
/* CHID (also called HWID by fwupd) is described at https://github.com/fwupd/fwupd/blob/main/docs/hwids.md */
void chid_calculate(const char16_t *const smbios_fields[static _CHID_SMBIOS_FIELDS_MAX], EFI_GUID ret_chids[static CHID_TYPES_MAX]);

View File

@ -4,6 +4,7 @@ fundamental_include = include_directories('.')
fundamental_sources = files(
'bootspec-fundamental.c',
'chid-fundamental.c',
'efivars-fundamental.c',
'iovec-util-fundamental.h',
'sha1-fundamental.c',