misc: Add support for enrolling config blake2b hash in executable

This commit is contained in:
mintsuki 2023-02-06 23:58:19 +01:00
parent 191ad51eaa
commit 8c7a98310a
6 changed files with 152 additions and 2 deletions

View File

@ -44,6 +44,15 @@ jobs:
- name: Clean limine-version - name: Clean limine-version
run: rm build/bin/limine-version run: rm build/bin/limine-version
- name: Clean limine-enroll-config
run: rm build/bin/limine-enroll-config
- name: Build limine-enroll-config-win32
run: make -C build/bin CC="i686-w64-mingw32-gcc" CFLAGS="-O2 -pipe" limine-enroll-config
- name: Strip limine-enroll-config-win32
run: i686-w64-mingw32-strip build/bin/limine-enroll-config.exe
- name: Clean limine-deploy - name: Clean limine-deploy
run: rm build/bin/limine-deploy run: rm build/bin/limine-deploy

View File

@ -83,7 +83,7 @@ override LIMINE_VERSION := @PACKAGE_VERSION@
override STAGE1_FILES := $(shell find '$(call SHESCAPE,$(SRCDIR))/stage1' -type f -name '*.asm') override STAGE1_FILES := $(shell find '$(call SHESCAPE,$(SRCDIR))/stage1' -type f -name '*.asm')
.PHONY: all .PHONY: all
all: limine-version $(BUILD_UEFI_X86_64) $(BUILD_UEFI_IA32) $(BUILD_UEFI_AARCH64) $(BUILD_BIOS) all: limine-version limine-enroll-config $(BUILD_UEFI_X86_64) $(BUILD_UEFI_IA32) $(BUILD_UEFI_AARCH64) $(BUILD_BIOS)
$(MAKE) '$(call SHESCAPE,$(BINDIR))/limine-cd-efi.bin' $(MAKE) '$(call SHESCAPE,$(BINDIR))/limine-cd-efi.bin'
$(call MKESCAPE,$(BINDIR))/limine-hdd.h: $(call MKESCAPE,$(BINDIR))/limine-hdd.bin $(call MKESCAPE,$(BINDIR))/limine-hdd.h: $(call MKESCAPE,$(BINDIR))/limine-hdd.bin
@ -98,6 +98,10 @@ $(call MKESCAPE,$(BINDIR))/limine-version: $(call MKESCAPE,$(BINDIR))/Makefile $
$(SED) 's/@LIMINE_VERSION@/@PACKAGE_VERSION@/g' <'$(call SHESCAPE,$(SRCDIR))/host/limine-version.c' >'$(call SHESCAPE,$(BINDIR))/limine-version.c' $(SED) 's/@LIMINE_VERSION@/@PACKAGE_VERSION@/g' <'$(call SHESCAPE,$(SRCDIR))/host/limine-version.c' >'$(call SHESCAPE,$(BINDIR))/limine-version.c'
$(MAKE) -C '$(call SHESCAPE,$(BINDIR))' limine-version $(MAKE) -C '$(call SHESCAPE,$(BINDIR))' limine-version
$(call MKESCAPE,$(BINDIR))/limine-enroll-config: $(call MKESCAPE,$(BINDIR))/Makefile $(call MKESCAPE,$(SRCDIR))/host/limine-enroll-config.c
cp '$(call SHESCAPE,$(SRCDIR))/host/limine-enroll-config.c' '$(call SHESCAPE,$(BINDIR))/'
$(MAKE) -C '$(call SHESCAPE,$(BINDIR))' limine-enroll-config
$(call MKESCAPE,$(BINDIR))/Makefile: $(call MKESCAPE,$(SRCDIR))/host/Makefile $(call MKESCAPE,$(SRCDIR))/host/.gitignore $(call MKESCAPE,$(BINDIR))/Makefile: $(call MKESCAPE,$(SRCDIR))/host/Makefile $(call MKESCAPE,$(SRCDIR))/host/.gitignore
$(MKDIR_P) '$(call SHESCAPE,$(BINDIR))' $(MKDIR_P) '$(call SHESCAPE,$(BINDIR))'
cp '$(call SHESCAPE,$(SRCDIR))/host/Makefile' '$(call SHESCAPE,$(SRCDIR))/host/.gitignore' '$(call SHESCAPE,$(BINDIR))/' cp '$(call SHESCAPE,$(SRCDIR))/host/Makefile' '$(call SHESCAPE,$(SRCDIR))/host/.gitignore' '$(call SHESCAPE,$(BINDIR))/'
@ -110,6 +114,10 @@ limine-deploy:
limine-version: limine-version:
$(MAKE) '$(call SHESCAPE,$(BINDIR))/limine-version' $(MAKE) '$(call SHESCAPE,$(BINDIR))/limine-version'
.PHONY: limine-enroll-config
limine-enroll-config:
$(MAKE) '$(call SHESCAPE,$(BINDIR))/limine-enroll-config'
.PHONY: clean .PHONY: clean
clean: limine-bios-clean limine-uefi-ia32-clean limine-uefi-x86-64-clean limine-uefi-aarch64-clean clean: limine-bios-clean limine-uefi-ia32-clean limine-uefi-x86-64-clean limine-uefi-aarch64-clean
rm -rf '$(call SHESCAPE,$(BINDIR))' '$(call SHESCAPE,$(BUILDDIR))/stage1.stamp' rm -rf '$(call SHESCAPE,$(BINDIR))' '$(call SHESCAPE,$(BUILDDIR))/stage1.stamp'
@ -146,6 +154,7 @@ endif
install-strip: install-data install-strip: install-data
$(INSTALL) -d '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))' $(INSTALL) -d '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))'
$(INSTALL_PROGRAM) -s '$(call SHESCAPE,$(BINDIR))/limine-version' '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))/' $(INSTALL_PROGRAM) -s '$(call SHESCAPE,$(BINDIR))/limine-version' '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))/'
$(INSTALL_PROGRAM) -s '$(call SHESCAPE,$(BINDIR))/limine-enroll-config' '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))/'
ifneq ($(BUILD_LIMINE_DEPLOY),no) ifneq ($(BUILD_LIMINE_DEPLOY),no)
$(INSTALL_PROGRAM) -s '$(call SHESCAPE,$(BINDIR))/limine-deploy' '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))/' $(INSTALL_PROGRAM) -s '$(call SHESCAPE,$(BINDIR))/limine-deploy' '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))/'
endif endif
@ -154,6 +163,7 @@ endif
install: install-data install: install-data
$(INSTALL) -d '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))' $(INSTALL) -d '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))'
$(INSTALL_PROGRAM) '$(call SHESCAPE,$(BINDIR))/limine-version' '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))/' $(INSTALL_PROGRAM) '$(call SHESCAPE,$(BINDIR))/limine-version' '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))/'
$(INSTALL_PROGRAM) '$(call SHESCAPE,$(BINDIR))/limine-enroll-config' '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))/'
ifneq ($(BUILD_LIMINE_DEPLOY),no) ifneq ($(BUILD_LIMINE_DEPLOY),no)
$(INSTALL_PROGRAM) '$(call SHESCAPE,$(BINDIR))/limine-deploy' '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))/' $(INSTALL_PROGRAM) '$(call SHESCAPE,$(BINDIR))/limine-deploy' '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))/'
endif endif
@ -161,6 +171,7 @@ endif
.PHONY: uninstall .PHONY: uninstall
uninstall: uninstall:
rm -f '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))/limine-version' rm -f '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))/limine-version'
rm -f '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))/limine-enroll-config'
rm -f '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))/limine-deploy' rm -f '$(call SHESCAPE,$(DESTDIR)$(ACBINDIR))/limine-deploy'
rm -rf '$(call SHESCAPE,$(DESTDIR)$(ACDATAROOTDIR))/limine' rm -rf '$(call SHESCAPE,$(DESTDIR)$(ACDATAROOTDIR))/limine'
rm -f '$(call SHESCAPE,$(DESTDIR)$(ACINCLUDEDIR))/limine.h' rm -f '$(call SHESCAPE,$(DESTDIR)$(ACINCLUDEDIR))/limine.h'

View File

@ -3,10 +3,17 @@
#include <lib/config.h> #include <lib/config.h>
#include <lib/libc.h> #include <lib/libc.h>
#include <lib/misc.h> #include <lib/misc.h>
#include <lib/readline.h>
#include <mm/pmm.h> #include <mm/pmm.h>
#include <fs/file.h> #include <fs/file.h>
#include <lib/print.h> #include <lib/print.h>
#include <pxe/tftp.h> #include <pxe/tftp.h>
#include <crypt/blake2b.h>
#define CONFIG_B2SUM_SIGNATURE "++CONFIG_B2SUM_SIGNATURE++"
#define CONFIG_B2SUM_EMPTY "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
const char *config_b2sum = CONFIG_B2SUM_SIGNATURE CONFIG_B2SUM_EMPTY;
static bool config_get_entry_name(char *ret, size_t index, size_t limit); static bool config_get_entry_name(char *ret, size_t index, size_t limit);
static char *config_get_entry(size_t *size, size_t index); static char *config_get_entry(size_t *size, size_t index);
@ -136,6 +143,29 @@ struct macro {
static struct macro *macros = NULL; static struct macro *macros = NULL;
int init_config(size_t config_size) { int init_config(size_t config_size) {
config_b2sum += sizeof(CONFIG_B2SUM_SIGNATURE) - 1;
if (memcmp((void *)config_b2sum, CONFIG_B2SUM_EMPTY, 128) != 0) {
uint8_t out_buf[BLAKE2B_OUT_BYTES];
blake2b(out_buf, config_addr, config_size - 2);
uint8_t hash_buf[BLAKE2B_OUT_BYTES];
for (size_t i = 0; i < BLAKE2B_OUT_BYTES; i++) {
hash_buf[i] = digit_to_int(config_b2sum[i * 2]) << 4 | digit_to_int(config_b2sum[i * 2 + 1]);
}
if (memcmp(hash_buf, out_buf, BLAKE2B_OUT_BYTES) != 0) {
print("!!! CHECKSUM MISMATCH FOR CONFIG FILE !!!\n");
print("If you do not know what this means, ANSWER WITH 'N' NOW!\n");
print("Proceed with boot anyways? [y/N]: ");
if (getchar() != 'y') {
print("\n");
panic(true, "Checksum mismatch for config file");
}
print("\n");
}
}
// add trailing newline if not present // add trailing newline if not present
config_addr[config_size - 2] = '\n'; config_addr[config_size - 2] = '\n';

2
host/.gitignore vendored
View File

@ -2,3 +2,5 @@ limine-deploy
limine-deploy.exe limine-deploy.exe
limine-version limine-version
limine-version.exe limine-version.exe
limine-enroll-config
limine-enroll-config.exe

View File

@ -6,7 +6,7 @@ PREFIX ?= /usr/local
CFLAGS ?= -g -O2 -pipe -Wall -Wextra CFLAGS ?= -g -O2 -pipe -Wall -Wextra
.PHONY: all .PHONY: all
all: limine-deploy limine-version all: limine-deploy limine-version limine-enroll-config
.PHONY: install-data .PHONY: install-data
install-data: all install-data: all
@ -26,20 +26,26 @@ install: install-data
$(INSTALL) -d '$(DESTDIR)$(PREFIX)/bin' $(INSTALL) -d '$(DESTDIR)$(PREFIX)/bin'
$(INSTALL) limine-deploy '$(DESTDIR)$(PREFIX)/bin/' $(INSTALL) limine-deploy '$(DESTDIR)$(PREFIX)/bin/'
$(INSTALL) limine-version '$(DESTDIR)$(PREFIX)/bin/' $(INSTALL) limine-version '$(DESTDIR)$(PREFIX)/bin/'
$(INSTALL) limine-enroll-config '$(DESTDIR)$(PREFIX)/bin/'
.PHONY: install-strip .PHONY: install-strip
install-strip: install-data install-strip: install-data
$(INSTALL) -d '$(DESTDIR)$(PREFIX)/bin' $(INSTALL) -d '$(DESTDIR)$(PREFIX)/bin'
$(INSTALL) -s limine-deploy '$(DESTDIR)$(PREFIX)/bin/' $(INSTALL) -s limine-deploy '$(DESTDIR)$(PREFIX)/bin/'
$(INSTALL) -s limine-version '$(DESTDIR)$(PREFIX)/bin/' $(INSTALL) -s limine-version '$(DESTDIR)$(PREFIX)/bin/'
$(INSTALL) -s limine-enroll-config '$(DESTDIR)$(PREFIX)/bin/'
.PHONY: clean .PHONY: clean
clean: clean:
rm -f limine-deploy limine-deploy.exe rm -f limine-deploy limine-deploy.exe
rm -f limine-version limine-version.exe rm -f limine-version limine-version.exe
rm -f limine-enroll-config limine-enroll-config.exe
limine-deploy: limine-deploy.c limine-hdd.h limine-deploy: limine-deploy.c limine-hdd.h
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -std=c99 -D__USE_MINGW_ANSI_STDIO limine-deploy.c $(LIBS) -o $@ $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -std=c99 -D__USE_MINGW_ANSI_STDIO limine-deploy.c $(LIBS) -o $@
limine-version: limine-version.c limine-version: limine-version.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -std=c99 -D__USE_MINGW_ANSI_STDIO limine-version.c $(LIBS) -o $@ $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -std=c99 -D__USE_MINGW_ANSI_STDIO limine-version.c $(LIBS) -o $@
limine-enroll-config: limine-enroll-config.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -std=c99 -D__USE_MINGW_ANSI_STDIO limine-enroll-config.c $(LIBS) -o $@

View File

@ -0,0 +1,92 @@
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CONFIG_B2SUM_SIGNATURE "++CONFIG_B2SUM_SIGNATURE++"
int main(int argc, char *argv[]) {
int ret = 1;
char *bootloader = NULL;
FILE *bootloader_file = NULL;
if (argc <= 2) {
fprintf(stderr, "usage: %s <Limine bootloader executable> <128-byte BLAKE2B of config file>\n", argv[0]);
goto cleanup;
}
if (strlen(argv[2]) != 128) {
fprintf(stderr, "ERROR: BLAKE2B specified is not 128 characters long\n");
goto cleanup;
}
bootloader_file = fopen(argv[1], "r+b");
if (bootloader_file == NULL) {
perror("ERROR");
goto cleanup;;
}
if (fseek(bootloader_file, 0, SEEK_END) != 0) {
perror("ERROR");
goto cleanup;
}
size_t bootloader_size = ftell(bootloader_file);
rewind(bootloader_file);
bootloader = malloc(bootloader_size);
if (bootloader == NULL) {
perror("ERROR");
goto cleanup;
}
if (fread(bootloader, bootloader_size, 1, bootloader_file) != 1) {
perror("ERROR");
goto cleanup;
}
char *checksum_loc = NULL;
size_t checked_count = 0;
const char *config_b2sum_sign = CONFIG_B2SUM_SIGNATURE;
for (size_t i = 0; i < bootloader_size; i++) {
if (bootloader[i] != config_b2sum_sign[checked_count]) {
checked_count = 0;
continue;
}
checked_count++;
if (checked_count == sizeof(CONFIG_B2SUM_SIGNATURE) - 1) {
checksum_loc = &bootloader[i + 1];
break;
}
}
if (checksum_loc == NULL) {
fprintf(stderr, "ERROR: Checksum location not found in provided executable\n");
goto cleanup;
}
memcpy(checksum_loc, argv[2], 128);
if (fseek(bootloader_file, 0, SEEK_SET) != 0) {
perror("ERROR");
goto cleanup;
}
if (fwrite(bootloader, bootloader_size, 1, bootloader_file) != 1) {
perror("ERROR");
goto cleanup;
}
fprintf(stderr, "Config file BLAKE2B successfully enrolled!\n");
ret = 0;
cleanup:
if (bootloader != NULL) {
free(bootloader);
}
if (bootloader_file != NULL) {
fclose(bootloader_file);
}
return ret;
}