x86: Added TXT measurement tool.
This commit is contained in:
parent
c94a88d436
commit
562e3279fd
13
Makefile
13
Makefile
|
@ -62,6 +62,7 @@ SRC := hypervisor.ld $(sort $(notdir $(foreach dir,$(SRC_DIR),$(wildcard $(dir)/
|
||||||
OBJ := $(patsubst %.ld,$(PAT_OBJ), $(patsubst %.S,$(PAT_OBJ), $(patsubst %.cpp,$(PAT_OBJ), $(SRC))))
|
OBJ := $(patsubst %.ld,$(PAT_OBJ), $(patsubst %.S,$(PAT_OBJ), $(patsubst %.cpp,$(PAT_OBJ), $(SRC))))
|
||||||
OBJ_DEP := $(OBJ:%.o=%.d)
|
OBJ_DEP := $(OBJ:%.o=%.d)
|
||||||
|
|
||||||
|
DIG := $(BLD_DIR)/digest
|
||||||
HYP := $(BLD_DIR)/$(ARCH)-nova
|
HYP := $(BLD_DIR)/$(ARCH)-nova
|
||||||
ELF := $(HYP).elf
|
ELF := $(HYP).elf
|
||||||
BIN := $(HYP).bin
|
BIN := $(HYP).bin
|
||||||
|
@ -165,6 +166,7 @@ Makefile.conf:
|
||||||
$(call message,CFG,$@)
|
$(call message,CFG,$@)
|
||||||
@cp $@.example $@
|
@cp $@.example $@
|
||||||
|
|
||||||
|
$(DIG): $(MFL) | $(BLD_DIR) tool_hst_cc
|
||||||
$(OBJ): $(MFL) | $(BLD_DIR) tool_tgt_cc
|
$(OBJ): $(MFL) | $(BLD_DIR) tool_tgt_cc
|
||||||
|
|
||||||
# Zap old-fashioned suffixes
|
# Zap old-fashioned suffixes
|
||||||
|
@ -174,12 +176,19 @@ $(OBJ): $(MFL) | $(BLD_DIR) tool_tgt_cc
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(call message,CLN,$@)
|
$(call message,CLN,$@)
|
||||||
$(RM) $(OBJ) $(HYP) $(ELF) $(BIN) $(OBJ_DEP)
|
$(RM) $(DIG) $(OBJ) $(HYP) $(ELF) $(BIN) $(OBJ_DEP)
|
||||||
|
|
||||||
install: $(HYP)
|
install: $(HYP) | $(DIG)
|
||||||
$(call message,INS,$^ =\> $(INS_DIR))
|
$(call message,INS,$^ =\> $(INS_DIR))
|
||||||
$(INSTALL) $^ $(INS_DIR)
|
$(INSTALL) $^ $(INS_DIR)
|
||||||
@$(TGT_SZ) $<
|
@$(TGT_SZ) $<
|
||||||
|
ifeq ($(ARCH),x86_64)
|
||||||
|
@echo Reference Integrity Measurements for $^
|
||||||
|
@echo $(shell $(DIG) $^ | sha1sum) "SHA1-160"
|
||||||
|
@echo $(shell $(DIG) $^ | sha256sum) "SHA2-256"
|
||||||
|
@echo $(shell $(DIG) $^ | sha384sum) "SHA2-384"
|
||||||
|
@echo $(shell $(DIG) $^ | sha512sum) "SHA2-512"
|
||||||
|
endif
|
||||||
|
|
||||||
run: $(ELF)
|
run: $(ELF)
|
||||||
$(RUN) $<
|
$(RUN) $<
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* NOVA Integrity Measurement Tool for Intel TXT
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019-2025 Udo Steinberg, BlueRock Security, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of the NOVA microhypervisor.
|
||||||
|
*
|
||||||
|
* NOVA is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* NOVA is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License version 2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
struct Mh final
|
||||||
|
{
|
||||||
|
uint64_t uuid[2];
|
||||||
|
uint32_t size, version, entry, first, mle_start, mle_end, mle_caps, cmd_start, cmd_end;
|
||||||
|
|
||||||
|
[[nodiscard]] bool valid() const
|
||||||
|
{
|
||||||
|
return uuid[0] == 0x74a7476f9082ac5a && uuid[1] == 0x42b651cba2555c0f && size == 52 && version == 0x20003;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Eh final
|
||||||
|
{
|
||||||
|
uint32_t ei_magic;
|
||||||
|
uint8_t ei_class, ei_data, ei_version, ei_osabi, ei_abiversion, ei_pad[7];
|
||||||
|
uint16_t type, machine;
|
||||||
|
uint32_t version;
|
||||||
|
uint64_t entry, ph_offset, sh_offset;
|
||||||
|
uint32_t flags;
|
||||||
|
uint16_t eh_size, ph_size, ph_count, sh_size, sh_count, strtab;
|
||||||
|
|
||||||
|
[[nodiscard]] bool valid() const
|
||||||
|
{
|
||||||
|
return ei_magic == 0x464c457f && ei_class == 2 && ei_data == 1 && ei_version == 1 && type == 2 && machine == 0x3e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ph final
|
||||||
|
{
|
||||||
|
uint32_t type, flags;
|
||||||
|
uint64_t f_offs, v_addr, p_addr, f_size, m_size, align;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
std::cerr << "You must specify a file.\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fstat (fileno (stdout), &st) == -1) {
|
||||||
|
perror ("fstat");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!S_ISFIFO (st.st_mode)) {
|
||||||
|
std::cerr << "You must pipe the output through a hash program.\n";
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const fd { open (argv[1], O_RDONLY) };
|
||||||
|
|
||||||
|
if (fd == -1) {
|
||||||
|
perror ("open");
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fstat (fd, &st) == -1) {
|
||||||
|
perror ("fstat");
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const ptr { mmap (nullptr, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0) };
|
||||||
|
|
||||||
|
if (ptr == MAP_FAILED) {
|
||||||
|
perror ("mmap");
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
close (fd);
|
||||||
|
|
||||||
|
auto const addr { reinterpret_cast<uintptr_t>(ptr) };
|
||||||
|
|
||||||
|
uint64_t size { 0 };
|
||||||
|
|
||||||
|
for (auto x { addr }; x < addr + st.st_size; x += sizeof (uint64_t)) {
|
||||||
|
auto const mh { reinterpret_cast<Mh const *>(x) };
|
||||||
|
if (mh->valid()) {
|
||||||
|
size = mh->mle_end - mh->mle_start;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!size) {
|
||||||
|
std::cerr << "File is not an MLE.\n";
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const eh { reinterpret_cast<Eh const *>(addr) };
|
||||||
|
|
||||||
|
if (!eh->valid()) {
|
||||||
|
std::cerr << "File is not an ELF.\n";
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ph { reinterpret_cast<Ph const *>(addr + eh->ph_offset) };
|
||||||
|
|
||||||
|
for (auto c { eh->ph_count }; size && c--; ph++) {
|
||||||
|
|
||||||
|
if (ph->type != 1 || ph->f_size == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto const s { std::min (size, ph->f_size) };
|
||||||
|
|
||||||
|
if (fwrite (reinterpret_cast<void const *>(addr + ph->f_offs), s, 1, stdout) != 1) {
|
||||||
|
perror ("fwrite");
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
size -= s;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue