Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NOT FOR MERGE] Test ci #20

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
fbb2984
build: remove .got.plt from final binary
krystian-hebel Feb 22, 2024
fdac326
build: move .pagedata to .bss.pagedata
krystian-hebel Feb 22, 2024
bac993a
head: build pagetables at runtime
krystian-hebel Feb 22, 2024
3b17c83
build: move everything from .data to .rodata or .bss
krystian-hebel Feb 22, 2024
8f0f6fa
head: move stack out of .text
krystian-hebel Feb 22, 2024
5a0379f
sl_header: limit amount of measured data
krystian-hebel Feb 22, 2024
67853db
head: don't use self-modifying code to switch to 64b mode
krystian-hebel Feb 23, 2024
729d480
main: rename variables
krystian-hebel Feb 23, 2024
08ddd83
head: don't test for boot protocol, use hand-off that works for all
krystian-hebel Feb 23, 2024
e36b5ae
include/slrt.h: new file with definitions for SLRT
krystian-hebel Feb 23, 2024
cc77fcf
event_log: obtain event log location from SLRT and log SKL measurements
krystian-hebel Feb 23, 2024
8c3e899
main: switch to SLRT
krystian-hebel Feb 26, 2024
a74b5ab
main: remove leftover functions specific to Linux and Multiboot2
krystian-hebel Feb 26, 2024
fc97d74
include: remove obsolete files (linux-bootparams, multiboot2, tags)
krystian-hebel Feb 26, 2024
8c4fea6
event_log: move definition of ev_log_hash_t to code
krystian-hebel Feb 26, 2024
75f3f0f
iommu.c: rework initialization function
krystian-hebel Apr 4, 2024
f16a0d0
tpmlib/tis.c: work around poor TPM implementations
krystian-hebel Apr 10, 2024
87833a0
.github/workflows/build.yml: run 'make tests'
krystian-hebel Apr 12, 2024
c00c554
sha1sum.c, sha256.c: make code work with -fstrict-aliasing
krystian-hebel Apr 15, 2024
97b94fc
Revert "build: Specify -march=btver2 explicitly, for AMD Fam16h proce…
SergiiDmytruk Apr 5, 2024
18f5358
dev: loop over CPU nodes on disabling memory protection
SergiiDmytruk Mar 29, 2024
96657b5
NOT FOR MERGE: test CI after bumping release-action
krystian-hebel May 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@ jobs:
run: |
make CC=${{matrix.compiler}} BITS=${{matrix.bits}} ${{matrix.lto}}
./extend_skl_only.sh

- name: make tests
run: |
make CC=${{matrix.compiler}} BITS=64 ${{matrix.lto}} tests
2 changes: 1 addition & 1 deletion .github/workflows/qubesos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:

jobs:
qubes-dom0-package:
uses: TrenchBoot/.github/.github/workflows/qubes-dom0-packagev2.yml@master
uses: TrenchBoot/.github/.github/workflows/qubes-dom0-packagev2.yml@bump-release-action

with:
qubes-component: 'secure-kernel-loader'
Expand Down
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ $(error Bad $$(BITS) value '$(BITS)')
endif

# There is a 64k total limit, so optimise for size. The binary may be loaded
# at an arbitray location, so build it as position independent, but link as
# at an arbitrary location, so build it as position independent, but link as
# non-pie as all relocations are internal and there is no dynamic loader to
# help.
CFLAGS += -Os -g -MMD -MP -march=btver2 -mno-sse -mno-mmx -fpie -fomit-frame-pointer
CFLAGS += -Os -g -MMD -MP -mno-sse -mno-mmx -fpie -fomit-frame-pointer
CFLAGS += -Iinclude -ffreestanding -fno-common -Wall -Werror
LDFLAGS += -nostdlib -no-pie -Wl,--build-id=none
LDFLAGS += -nostdlib -no-pie -Wl,--build-id=none,--fatal-warnings,--defsym=BITS=$(BITS)

CFLAGS_TPMLIB := -include boot.h -include errno-base.h -include byteswap.h -DEBADRQC=EINVAL

Expand All @@ -54,7 +54,7 @@ all: skl.bin
# image. One reason this might fail is if the linker decides to put an
# unreferenced section ahead of .text, in which case link.lds needs adjusting.
skl.bin: skl Makefile
objcopy -O binary -S -R '.note.*' $< $@
objcopy -O binary -S -R '.note.*' -R '.got.plt' $< $@
@./sanity_check.sh

skl: link.lds $(OBJ) Makefile
Expand Down
76 changes: 49 additions & 27 deletions dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,67 +20,89 @@
#include <pci.h>
#include <dev.h>

u32 dev_locate(void)
/*
* There are only 5 bits (0x00..0x1f) for PCI slot number (see definition of
* PCI_DEVFN) and we start at 0x18 (DEV_PCI_DEVICE), so there is hard upper
* limit on how many nodes can exist.
*/
#define MAX_CPU_NODES 8

u32 dev_locate(u8 cpu_node)
{
return pci_locate(DEV_PCI_BUS,
PCI_DEVFN(DEV_PCI_DEVICE, DEV_PCI_FUNCTION));
PCI_DEVFN(DEV_PCI_DEVICE + cpu_node, DEV_PCI_FUNCTION));
}

u32 dev_read(u32 dev_cap, u32 function, u32 index)
u32 dev_read(u8 cpu_node, u32 dev_cap, u32 function, u32 index)
{
u32 value;

pci_write(0, DEV_PCI_BUS,
PCI_DEVFN(DEV_PCI_DEVICE, DEV_PCI_FUNCTION),
PCI_DEVFN(DEV_PCI_DEVICE + cpu_node, DEV_PCI_FUNCTION),
dev_cap + DEV_OP_OFFSET,
4,
(u32)(((function & 0xff) << 8) + (index & 0xff)));

pci_read(0, DEV_PCI_BUS,
PCI_DEVFN(DEV_PCI_DEVICE, DEV_PCI_FUNCTION),
PCI_DEVFN(DEV_PCI_DEVICE + cpu_node, DEV_PCI_FUNCTION),
dev_cap + DEV_DATA_OFFSET,
4, &value);

return value;
}

void dev_write(u32 dev, u32 function, u32 index, u32 value)
void dev_write(u8 cpu_node, u32 dev, u32 function, u32 index, u32 value)
{
pci_write(0, DEV_PCI_BUS,
PCI_DEVFN(DEV_PCI_DEVICE, DEV_PCI_FUNCTION),
PCI_DEVFN(DEV_PCI_DEVICE + cpu_node, DEV_PCI_FUNCTION),
dev + DEV_OP_OFFSET,
4,
(u32)(((function & 0xff) << 8) + (index & 0xff)) );

pci_write(0, DEV_PCI_BUS,
PCI_DEVFN(DEV_PCI_DEVICE, DEV_PCI_FUNCTION),
PCI_DEVFN(DEV_PCI_DEVICE + cpu_node, DEV_PCI_FUNCTION),
dev + DEV_DATA_OFFSET,
4, value);
}

void dev_disable_sl(u32 dev)
void dev_disable_sl(u8 cpu_node, u32 dev)
{
u32 dev_cr = dev_read(dev, DEV_CR, 0);
dev_write(dev, DEV_CR, 0, dev_cr & ~(DEV_CR_SL_DEV_EN_MASK));
u32 dev_cr = dev_read(cpu_node, dev, DEV_CR, 0);
dev_write(cpu_node, dev, DEV_CR, 0, dev_cr & ~(DEV_CR_SL_DEV_EN_MASK));
}

void disable_memory_protection(void)
{
u32 dev_cap, sldev;

dev_cap = dev_locate();
if (dev_cap) {
/* Older families with remains of DEV */
dev_disable_sl(dev_cap);
return;
}

/* Fam 17h uses different DMA protection control register */
pci_read(0, MCH_PCI_BUS,
PCI_DEVFN(MCH_PCI_DEVICE, MCH_PCI_FUNCTION),
MEMPROT_CR, 4, &sldev);
pci_write(0, MCH_PCI_BUS,
PCI_DEVFN(MCH_PCI_DEVICE, MCH_PCI_FUNCTION),
MEMPROT_CR, 4, sldev & ~(MEMPROT_EN));
u32 dev_cap, sldev, vid_did;
u8 cpu_node = 0;

dev_cap = dev_locate(cpu_node);
if (dev_cap) {
/* Older families with remains of DEV */
do {
dev_disable_sl(cpu_node, dev_cap);

cpu_node++;
if (cpu_node == MAX_CPU_NODES)
break;

dev_cap = dev_locate(cpu_node);
} while (dev_cap);
return;
}

/* Fam 17h uses different DMA protection control register */
while (cpu_node < MAX_CPU_NODES &&
pci_read(0, MCH_PCI_BUS,
PCI_DEVFN(MCH_PCI_DEVICE + cpu_node, MCH_PCI_FUNCTION),
VIDDID, 4, &vid_did) == 0 &&
vid_did != 0xffffffffU) {
u8 devfn = PCI_DEVFN(MCH_PCI_DEVICE + cpu_node, MCH_PCI_FUNCTION);

pci_read(0, MCH_PCI_BUS, devfn, MEMPROT_CR, 4, &sldev);
pci_write(0, MCH_PCI_BUS, devfn, MEMPROT_CR, 4, sldev & ~(MEMPROT_EN));

cpu_node++;
}
}

98 changes: 47 additions & 51 deletions event_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
*/

#include <boot.h>
#include <sha1sum.h>
#include <sha256.h>
#include <slrt.h>
#include <string.h>
#include <tags.h>
#include "tpmlib/tpm.h"
#include "tpmlib/tpm2_constants.h"

Expand Down Expand Up @@ -105,20 +107,29 @@ typedef struct __packed {
typedef struct __packed {
u32 pcr;
u32 event_type;
u8 digest[20];
u8 digest[SHA1_DIGEST_SIZE];
u32 event_size;
/* u8 event[]; */
} tpm12_event_t;

/* The same as TPML_DIGEST_VALUES but little endian, as event log expects it */
typedef struct __packed {
u32 count;
u16 sha1_id;
u8 sha1_hash[SHA1_DIGEST_SIZE];
u16 sha256_id;
u8 sha256_hash[SHA256_DIGEST_SIZE];
} ev_log_hash_t;

typedef struct __packed {
u32 pcr;
u32 event_type;
ev_log_hash_t digests; /* defined in boot.h */
ev_log_hash_t digests;
u32 event_size;
/* u8 event[]; */
} tpm20_event_t;

static tpm12_spec_id_ev_t tpm12_id_struct = {
static const tpm12_spec_id_ev_t tpm12_id_struct = {
.c.signature = "Spec ID Event00",
.c.spec_ver_minor = 2,
.c.spec_ver_major = 1,
Expand All @@ -139,7 +150,7 @@ static tpm12_spec_id_ev_t tpm12_id_struct = {
.hdr.next_event_offset = sizeof(tpm12_event_log_header)
};

static tpm20_spec_id_ev_t tpm20_id_struct = {
static const tpm20_spec_id_ev_t tpm20_id_struct = {
.c.signature = "Spec ID Event03",
.c.spec_ver_minor = 0,
.c.spec_ver_major = 2,
Expand All @@ -155,7 +166,7 @@ static tpm20_spec_id_ev_t tpm20_id_struct = {
.el.next_record_offset = sizeof(tpm20_spec_id_ev_t) + sizeof(tpm12_event_t)
};

int log_event_tpm12(u32 pcr, u8 sha1[20], char *event)
int log_event_tpm12(u32 pcr, u8 sha1[SHA1_DIGEST_SIZE], char *event)
{
tpm12_event_t ev;
tpm12_spec_id_ev_t *base = (tpm12_spec_id_ev_t *)
Expand All @@ -176,7 +187,8 @@ int log_event_tpm12(u32 pcr, u8 sha1[20], char *event)
return 1;
}

int log_event_tpm20(u32 pcr, u8 sha1[20], u8 sha256[32], char *event)
int log_event_tpm20(u32 pcr, u8 sha1[SHA1_DIGEST_SIZE],
u8 sha256[SHA256_DIGEST_SIZE], char *event)
{
tpm20_event_t ev;
tpm20_spec_id_ev_t *base = (tpm20_spec_id_ev_t *)
Expand Down Expand Up @@ -204,9 +216,12 @@ int log_event_tpm20(u32 pcr, u8 sha1[20], u8 sha256[32], char *event)
int event_log_init(struct tpm *tpm)
{
unsigned int min_size;
struct skl_tag_evtlog *t = next_of_type(&bootloader_data, SKL_TAG_EVENT_LOG);
struct slr_entry_log_info *info;
u8 hash[SHA1_DIGEST_SIZE];

info = next_entry_with_tag(NULL, SLR_ENTRY_LOG_INFO);

if ( t == NULL || next_of_type(t, SKL_TAG_EVENT_LOG) != NULL )
if ( info == NULL || next_entry_with_tag(info, SLR_ENTRY_LOG_INFO) != NULL )
goto err;

min_size = sizeof (tpm12_event_t);
Expand All @@ -227,11 +242,11 @@ int event_log_init(struct tpm *tpm)
}

/* Note that min_size does not include tpmXX_event_t.event[] entries */
if ( t->size < min_size )
if ( info->size < min_size )
goto err;

ptr_current = evtlog_base = _p(t->address);
limit = _p(t->address + t->size);
ptr_current = evtlog_base = _p(info->addr);
limit = _p(info->addr + info->size);

/* Check for overflow */
if ( ptr_current > limit )
Expand All @@ -245,12 +260,12 @@ int event_log_init(struct tpm *tpm)
if ( !(_p(limit) < _p(_start) || _p(_start + SLB_SIZE) < _p(ptr_current)) )
goto err;

tpm12_id_struct.hdr.container_size =
tpm20_id_struct.el.allocated_event_container_size =
t->size;
tpm20_id_struct.el.phys_addr = _u(evtlog_base);
memset(ptr_current, 0, info->size);

memset(ptr_current, 0, t->size);
/* Check if log format matches TPM family */
if ((tpm->family == TPM12 && info->format != SLR_LOG_FORMAT_TPM12_TXT) ||
(tpm->family == TPM20 && info->format != SLR_LOG_FORMAT_TPM20_TCG))
goto err;

/* Write log header */
{
Expand All @@ -267,49 +282,30 @@ int event_log_init(struct tpm *tpm)
log_write(&ev, sizeof(ev));
}

if ( tpm->family == TPM12 )
/* Sizes were checked earlier so log_write() won't fail here */
if ( tpm->family == TPM12 ) {
tpm12_spec_id_ev_t *id = (tpm12_spec_id_ev_t *)ptr_current;
log_write(&tpm12_id_struct, sizeof(tpm12_id_struct));
else
id->hdr.container_size = info->size;
} else {
tpm20_spec_id_ev_t *id = (tpm20_spec_id_ev_t *)ptr_current;
log_write(&tpm20_id_struct, sizeof(tpm20_id_struct));
id->el.allocated_event_container_size = info->size;
id->el.phys_addr = _u(evtlog_base);
}

/* Log what was done by SKINIT */
sha1sum(hash, _start, _end_of_measured - _start);
if ( tpm->family == TPM12 )
{
struct skl_tag_hash *h = next_of_type(&bootloader_data, SKL_TAG_SKL_HASH);

while ( h != NULL )
{
if ( h->algo_id == TPM_ALG_SHA1 )
return log_event_tpm12(17, h->digest, "SKINIT");

h = next_of_type(h, SKL_TAG_SKL_HASH);
}

/* No SHA1 hash was passed by a bootloader? */
return 1;
return log_event_tpm12(17, hash, "SKINIT");
}
else
else if ( tpm->family == TPM20 )
{
struct skl_tag_hash *h = next_of_type(&bootloader_data, SKL_TAG_SKL_HASH);
u8 *sha1 = NULL;
u8 *sha256 = NULL;

while ( h != NULL )
{
if ( h->algo_id == TPM_ALG_SHA1 )
sha1 = h->digest;
u8 sha256_hash[SHA256_DIGEST_SIZE];

if ( h->algo_id == TPM_ALG_SHA256 )
sha256 = h->digest;

if ( sha1 != NULL && sha256 != NULL )
return log_event_tpm20(17, sha1, sha256, "SKINIT");

h = next_of_type(h, SKL_TAG_SKL_HASH);
}

/* Either SHA1 or SHA256 hash wasn't passed by a bootloader? */
return 1;
sha256sum(sha256_hash, _start, _end_of_measured - _start);
return log_event_tpm20(17, hash, sha256_hash, "SKINIT");
}

err:
Expand Down
Loading
Loading