From 37feebdc7640c5a57369ec9b25cd33c6b8687505 Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Sun, 11 Mar 2018 18:27:19 -0700 Subject: [PATCH 1/9] Read and measure CBFS files into initrd during init --- boards/kgpe-d16/kgpe-d16.config | 2 +- boards/librem13v2/librem13v2.config | 2 +- boards/qemu-coreboot/qemu-coreboot.config | 2 +- boards/x220/x220.config | 2 +- boards/x230-flash/x230-flash.config | 2 +- boards/x230/x230.config | 2 +- initrd/bin/cbfs-init | 34 +++ initrd/bin/kexec-seal-key | 1 + initrd/bin/seal-totp | 1 + initrd/etc/functions | 2 +- initrd/init | 8 +- patches/flashtools.patch | 302 ++++++++++++++++++++++ 12 files changed, 351 insertions(+), 9 deletions(-) create mode 100755 initrd/bin/cbfs-init create mode 100644 patches/flashtools.patch diff --git a/boards/kgpe-d16/kgpe-d16.config b/boards/kgpe-d16/kgpe-d16.config index 3888aeec..f783f462 100644 --- a/boards/kgpe-d16/kgpe-d16.config +++ b/boards/kgpe-d16/kgpe-d16.config @@ -1,5 +1,5 @@ # Configuration for a kgpe-d16 running non-Qubes -CONFIG_COREBOOT=y +export CONFIG_COREBOOT=y CONFIG_COREBOOT_CONFIG=config/coreboot-kgpe-d16.config CONFIG_LINUX_CONFIG=config/linux-kgpe-d16.config diff --git a/boards/librem13v2/librem13v2.config b/boards/librem13v2/librem13v2.config index 9cfea3d2..f029b45f 100644 --- a/boards/librem13v2/librem13v2.config +++ b/boards/librem13v2/librem13v2.config @@ -2,7 +2,7 @@ CONFIG_LINUX_CONFIG=config/linux-librem13v2.config CONFIG_COREBOOT_CONFIG=config/coreboot-librem13v2.config -CONFIG_COREBOOT=y +export CONFIG_COREBOOT=y CONFIG_CRYPTSETUP=y CONFIG_FLASHROM=y CONFIG_GPG=y diff --git a/boards/qemu-coreboot/qemu-coreboot.config b/boards/qemu-coreboot/qemu-coreboot.config index fe2963a6..e095bed5 100644 --- a/boards/qemu-coreboot/qemu-coreboot.config +++ b/boards/qemu-coreboot/qemu-coreboot.config @@ -1,7 +1,7 @@ # Configuration for building a coreboot ROM that works in the. # the qemu emulator. Note that the TPM does not work, so this # will just drop into the recovery shell. -CONFIG_COREBOOT=y +export CONFIG_COREBOOT=y CONFIG_COREBOOT_CONFIG=config/coreboot-qemu.config CONFIG_LINUX_CONFIG=config/linux-qemu.config diff --git a/boards/x220/x220.config b/boards/x220/x220.config index a6aa9732..0b901bdb 100644 --- a/boards/x220/x220.config +++ b/boards/x220/x220.config @@ -1,6 +1,6 @@ # Configuration for a x220 running Qubes and other OS # The Linux configuration is close enough to the x230 -CONFIG_COREBOOT=y +export CONFIG_COREBOOT=y CONFIG_COREBOOT_CONFIG=config/coreboot-x220.config CONFIG_LINUX_CONFIG=config/linux-x230.config diff --git a/boards/x230-flash/x230-flash.config b/boards/x230-flash/x230-flash.config index ad5f2c5d..3c426e65 100644 --- a/boards/x230-flash/x230-flash.config +++ b/boards/x230-flash/x230-flash.config @@ -1,7 +1,7 @@ # Minimal configuration for a x230 to support flashrom, USB and networking BOARD=x230.flash -CONFIG_COREBOOT=y +export CONFIG_COREBOOT=y CONFIG_FLASHROM=y CONFIG_FLASHTOOLS=y CONFIG_PCIUTILS=y diff --git a/boards/x230/x230.config b/boards/x230/x230.config index d65fc395..7a22c5d5 100644 --- a/boards/x230/x230.config +++ b/boards/x230/x230.config @@ -1,5 +1,5 @@ # Configuration for a x230 running Qubes and other OSes -CONFIG_COREBOOT=y +export CONFIG_COREBOOT=y CONFIG_COREBOOT_CONFIG=config/coreboot-x230.config CONFIG_LINUX_CONFIG=config/linux-x230.config diff --git a/initrd/bin/cbfs-init b/initrd/bin/cbfs-init new file mode 100755 index 00000000..a5ca711c --- /dev/null +++ b/initrd/bin/cbfs-init @@ -0,0 +1,34 @@ +#!/bin/ash +set -e -o pipefail +. /etc/functions + +# Update initrd with CBFS files +if [ -z "$CBFS_PCR" ]; then + CBFS_PCR=7 +fi + +# Load individual files +cbfsfiles=`cbfs -l 2>/dev/null | grep "^initrd/"` # \ +# || die "cbfs list files failed" +# qemu dies - ignore check for now + +for cbfsname in `echo $cbfsfiles`; do + filename=${cbfsname:6} + if [ ! -z "$filename" ]; then + echo "Loading $filename from CBFS" + mkdir -p `dirname $filename` \ + || die "$filename: mkdir failed" + cbfs -r $cbfsname > "$filename" \ + || die "$filename: cbfs file read failed" + if [ "$CONFIG_TPM" = "y" ]; then + TMPFILE=/tmp/cbfs.$$ + echo "$filename" > $TMPFILE + cat $filename >> $TMPFILE + tpm extend -ix "$CBFS_PCR" -if $TMPFILE \ + || die "$filename: tpm extend failed" + fi + fi +done + +# TODO: copy CBFS file named "initrd.tgz" to /tmp, measure and extract +# TODO: key convenience: take "keys/*.asc" and gpg --import them diff --git a/initrd/bin/kexec-seal-key b/initrd/bin/kexec-seal-key index 05216191..5f6ab6b3 100755 --- a/initrd/bin/kexec-seal-key +++ b/initrd/bin/kexec-seal-key @@ -106,6 +106,7 @@ tpm sealfile2 \ -ix 4 0000000000000000000000000000000000000000 \ -ix 5 0000000000000000000000000000000000000000 \ -ix 6 $luks_pcr \ + -ix 7 X \ || die "Unable to seal secret" rm -f "$KEY_FILE" \ diff --git a/initrd/bin/seal-totp b/initrd/bin/seal-totp index fc89d897..f46f4520 100755 --- a/initrd/bin/seal-totp +++ b/initrd/bin/seal-totp @@ -41,6 +41,7 @@ if ! tpm sealfile2 \ -ix 2 X \ -ix 3 X \ -ix 4 0000000000000000000000000000000000000000 \ + -ix 7 X \ ; then rm -f "$TOTP_SECRET" die "Unable to seal secret" diff --git a/initrd/etc/functions b/initrd/etc/functions index 658990ff..dd30d7a7 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -36,7 +36,7 @@ pause_recovery() { } pcrs() { - head -7 /sys/class/tpm/tpm0/pcrs + head -8 /sys/class/tpm/tpm0/pcrs } confirm_totp() diff --git a/initrd/init b/initrd/init index 527188f9..4bc5e865 100755 --- a/initrd/init +++ b/initrd/init @@ -51,6 +51,10 @@ if [ ! -z "$CONFIG_USB_BOOT_DEV" ]; then echo >> /etc/fstab "$CONFIG_USB_BOOT_DEV /media auto defaults,ro 0 0" fi +if [ "$CONFIG_COREBOOT" = "y" ]; then + /bin/cbfs-init +fi + # Setup recovery serial shell if [ ! -z "$CONFIG_BOOT_RECOVERY_SERIAL" ]; then stty -F "$CONFIG_BOOT_RECOVERY_SERIAL" 115200 @@ -72,7 +76,7 @@ if [ "$boot_option" = "r" ]; then # Start an interactive shell recovery 'User requested recovery shell' # just in case... - if [ "$CONFIG_TPM" = y ]; then + if [ "$CONFIG_TPM" = "y" ]; then tpm extend -ix 4 -ic recovery fi exec /bin/ash @@ -102,7 +106,7 @@ else fi # belts and suspenders, just in case... -if [ "$CONFIG_TPM" = y ]; then +if [ "$CONFIG_TPM" = "y" ]; then tpm extend -ix 4 -ic recovery fi exec /bin/ash diff --git a/patches/flashtools.patch b/patches/flashtools.patch new file mode 100644 index 00000000..97ed3bd0 --- /dev/null +++ b/patches/flashtools.patch @@ -0,0 +1,302 @@ +diff --git ./.gitignore ./.gitignore +index eb53396..bf46e4e 100644 +--- ./.gitignore ++++ ./.gitignore +@@ -5,3 +5,4 @@ + flashtool + peek + poke ++cbfs +diff --git ./Makefile ./Makefile +index 27e28b5..ffb187c 100644 +--- ./Makefile ++++ ./Makefile +@@ -1,6 +1,7 @@ + TARGETS += flashtool + TARGETS += poke + TARGETS += peek ++TARGETS += cbfs + + CFLAGS += \ + -std=c99 \ +@@ -17,6 +18,7 @@ all: $(TARGETS) + flashtool: flashtool.o spiflash.o util.o + peek: peek.o util.o + poke: poke.o util.o ++cbfs: cbfs.o + + $(TARGETS): + $(CC) $(LDFLAGS) -o $@ $^ +diff --git ./cbfs.c ./cbfs.c +new file mode 100644 +index 0000000..7e11c88 +--- /dev/null ++++ ./cbfs.c +@@ -0,0 +1,267 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define CBFS_HEADER_MAGIC 0x4F524243 ++#define CBFS_HEADER_VERSION1 0x31313131 ++#define CBFS_HEADER_VERSION2 0x31313132 ++#define CBFS_HEADER_VERSION CBFS_HEADER_VERSION2 ++ ++int verbose = 0; ++ ++static const struct option long_options[] = { ++ { "verbose", 0, NULL, 'v' }, ++ { "read", 1, NULL, 'r' }, ++ { "list", 0, NULL, 'l' }, ++ { "help", 0, NULL, 'h' }, ++ { NULL, 0, NULL, 0 }, ++}; ++ ++ ++static const char usage[] = ++"Usage: sudo cbfs [options]\n" ++"\n" ++"-h | -? | --help This help\n" ++"-v | --verbose Increase verbosity\n" ++"-r | --read file Read the CBFS filed and dump to stdout\n" ++"-l | --list List the raw files in the CBFS\n" ++"\n"; ++ ++struct cbfs_header { ++ uint32_t magic; ++ uint32_t version; ++ uint32_t romsize; ++ uint32_t bootblocksize; ++ uint32_t align; /* hard coded to 64 byte */ ++ uint32_t offset; ++ uint32_t architecture; /* Version 2 */ ++ uint32_t pad[1]; ++}; ++ ++#define CBFS_FILE_MAGIC "LARCHIVE" ++ ++struct cbfs_file { ++ uint8_t magic[8]; ++ /* length of file data */ ++ uint32_t len; ++ uint32_t type; ++ /* offset to struct cbfs_file_attribute or 0 */ ++ uint32_t attributes_offset; ++ /* length of header incl. variable data */ ++ uint32_t offset; ++ char filename[]; ++}; ++ ++ ++int main(int argc, char** argv) { ++ const char * const prog_name = argv[0]; ++ if (argc <= 1) ++ { ++ fprintf(stderr, "%s", usage); ++ return EXIT_FAILURE; ++ } ++ ++ int opt; ++ int do_read = 0; ++ int do_list = 0; ++ const char * filename = NULL; ++ while ((opt = getopt_long(argc, argv, "h?vlr:", long_options, NULL)) != -1) ++ { ++ switch(opt) ++ { ++ case 'v': ++ verbose++; ++ break; ++ case 'l': ++ do_list = 1; ++ break; ++ case 'r': ++ do_read = 1; ++ filename = optarg; ++ break; ++ case '?': case 'h': ++ printf("%s", usage); ++ return EXIT_SUCCESS; ++ default: ++ fprintf(stderr, "%s", usage); ++ return EXIT_FAILURE; ++ } ++ } ++ ++ argc -= optind; ++ argv += optind; ++ if (argc != 0) ++ { ++ fprintf(stderr, "%s: Excess arguments?\n", prog_name); ++ return EXIT_FAILURE; ++ } ++ ++ int fd; ++ fd = open("/dev/mem", O_RDONLY); ++ if (fd < 0) { ++ fprintf(stderr, "Failed to open /dev/mem : %s\n", strerror(errno)); ++ return EXIT_FAILURE; ++ } ++ ++ uint64_t end = 0x100000000; ++ if (verbose) { ++ printf("Seeking to %lx\n", end-4); ++ } ++ if (lseek(fd, end-4, SEEK_SET) == -1) { ++ fprintf(stderr, "Failed to seek to %lx\n", end-4); ++ return EXIT_FAILURE; ++ } ++ ++ int32_t header_delta; ++ if (read(fd, &header_delta, sizeof(header_delta)) < 0) { ++ fprintf(stderr, "Failed to read header offset\n"); ++ return EXIT_FAILURE; ++ } ++ if (verbose) { ++ printf("Header Offset: %d\n", header_delta); ++ } ++ ++ uint64_t header_off; ++ if (header_delta < 0) { ++ header_off = end - ((uint64_t)(-header_delta)); ++ } else { ++ header_off = ((uint64_t)header_delta); ++ } ++ ++ if (verbose) { ++ printf("Seeking to %lx\n", header_off); ++ } ++ if (lseek(fd, header_off, SEEK_SET) == -1) { ++ fprintf(stderr, "Failed to seek to %lx\n", header_off); ++ return EXIT_FAILURE; ++ } ++ ++ struct cbfs_header header; ++ if (read(fd, &header, sizeof(struct cbfs_header)) < 0) { ++ fprintf(stderr, "Failed to read header\n"); ++ return EXIT_FAILURE; ++ } ++ header.magic = ntohl(header.magic); ++ header.version = ntohl(header.version); ++ header.romsize = ntohl(header.romsize); ++ header.bootblocksize = ntohl(header.bootblocksize); ++ header.align = ntohl(header.align); ++ header.offset = ntohl(header.offset); ++ header.architecture = ntohl(header.architecture); ++ ++ if (verbose) { ++ printf("Header magic : %x\n", header.magic); ++ printf("Header version : %x\n", header.version); ++ printf("Header ROM size : %x\n", header.romsize); ++ printf("Header boot block size: %x\n", header.bootblocksize); ++ printf("Header align : %x\n", header.align); ++ printf("Header offset : %x\n", header.offset); ++ printf("Header arch : %x\n", header.architecture); ++ } ++ ++ if (header.magic != CBFS_HEADER_MAGIC) { ++ fprintf(stderr, "Failed to find valid header\n"); ++ return EXIT_FAILURE; ++ } ++ ++ uint32_t align = header.align; ++ // loop through files ++ uint64_t off = end - ((uint64_t) header.romsize) + ((uint64_t) header.offset); ++ while (1) { ++ if (verbose) { ++ printf("Potential CBFS File Offset: %lx\n", off); ++ } ++ if (lseek(fd, off, SEEK_SET) == -1) { ++ fprintf(stderr, "Failed to seek to next CBFS offset %lx\n", off); ++ return EXIT_FAILURE; ++ } ++ ++ struct cbfs_file file; ++ if (read(fd, &file, sizeof(struct cbfs_file)) < 0) { ++ fprintf(stderr, "Failed to read cbfs file header\n"); ++ return EXIT_FAILURE; ++ } ++ ++ file.len = ntohl(file.len); ++ file.type = ntohl(file.type); ++ file.attributes_offset = ntohl(file.attributes_offset); ++ file.offset = ntohl(file.offset); ++ ++ if (verbose) { ++ printf("File magic : %.8s\n", file.magic); ++ printf("File len : %x\n", file.len); ++ printf("File type : %x\n", file.type); ++ printf("File attributes_offset : %x\n", file.attributes_offset); ++ printf("File offset : %x\n", file.offset); ++ } ++ ++ if (strncmp((char *)file.magic, CBFS_FILE_MAGIC, 8) != 0) { ++ break; ++ } ++ ++ size_t name_size = file.offset - sizeof(struct cbfs_file); ++ char *name = calloc(name_size, sizeof(char)); ++ if (read(fd, name, name_size) < 0) { ++ fprintf(stderr, "Failed to read cbfs file name\n"); ++ return EXIT_FAILURE; ++ } ++ if (verbose) { ++ printf("File name : '%s'\n", name); ++ } ++ ++ if (do_list && file.type == 0x50) { ++ printf("%s\n", name); ++ } ++ if (do_read && file.type == 0x50 && ++ strncmp(name, filename, name_size) == 0) ++ { ++ uint64_t file_off = off + file.offset; ++ if (verbose) { ++ printf("Seeking to %lx\n-------- Start Data\n", file_off); ++ } ++ if (lseek(fd, file_off, SEEK_SET) == -1) { ++ fprintf(stderr, "Failed to seek to file data at %lx\n", file_off); ++ return EXIT_FAILURE; ++ } ++ ++ char *file_data = malloc(file.len); ++ if (read(fd, file_data, file.len) < 0) { ++ fprintf(stderr, "Failed to read file data\n"); ++ return EXIT_FAILURE; ++ } ++ if (write(STDOUT_FILENO, file_data, file.len) == -1) { ++ fprintf(stderr, "Failed to write file to stdout: %s\n", ++ strerror(errno)); ++ return EXIT_FAILURE; ++ } ++ free(file_data); ++ if (verbose) { ++ printf("\n-------- End Data\n"); ++ } ++ do_read++; ++ } ++ ++ uint64_t inc = (align + (file.offset + file.len) - 1) & (~(align-1)); ++ off += inc; ++ if (verbose) { ++ printf("File Off+Len : %x\n", file.offset + file.len); ++ printf("Align : %x\n", align); ++ printf("Inc : %lx\n", inc); ++ printf("Next file align : %lx\n", off); ++ } ++ } ++ ++ if (do_read == 1) { ++ fprintf(stderr, "Failed to find CBFS file named '%s'\n", filename); ++ return EXIT_FAILURE; ++ } ++ ++ return EXIT_SUCCESS; ++} From d0294b1142d4c9ee49834c89ccc9afc12c1f80d8 Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Tue, 13 Mar 2018 17:55:34 -0700 Subject: [PATCH 2/9] Add all supported network modules to network-init-recovery also fix verbiage in comments --- initrd/bin/network-init-recovery | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/initrd/bin/network-init-recovery b/initrd/bin/network-init-recovery index 82a4a209..23ebcb25 100755 --- a/initrd/bin/network-init-recovery +++ b/initrd/bin/network-init-recovery @@ -3,23 +3,22 @@ # bring up the ethernet; maybe should do DHCP? ifconfig lo 127.0.0.1 -if [ -f /lib/modules/e1000.ko ]; then - insmod /lib/modules/e1000.ko -fi - -if [ -f /lib/modules/e1000e.ko ]; then - insmod /lib/modules/e1000e.ko -fi +network_modules="e1000 e1000e igb sfc mdio mlx4_core mlx4_en" +for module in `echo $network_modules`; do + if [ -f /lib/modules/$module.ko ]; then + insmod /lib/modules/$module.ko + fi +done if [ -e /sys/class/net/eth0 ]; then - # Setup static IP + # Set up static IP if [ ! -z "$CONFIG_BOOT_STATIC_IP" ]; then ifconfig eth0 $CONFIG_BOOT_STATIC_IP fi - # TODO: setup DHCP if available + # TODO: Set up DHCP if available ifconfig eth0 > /dev/ttyprintk - # Setup the ssh server, allow root logins and log to stderr + # Set up the ssh server, allow root logins and log to stderr if [ ! -d /etc/dropbear ]; then mkdir /etc/dropbear fi From e0c1ab2d79496a924f976a8de6b6d4434c06cfb6 Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Fri, 23 Mar 2018 09:29:47 -0700 Subject: [PATCH 3/9] Update cbfs-init script for new cbfs tool option --- initrd/bin/cbfs-init | 7 +- patches/flashtools.patch | 216 +++++++++++++++++++++++++-------------- 2 files changed, 142 insertions(+), 81 deletions(-) diff --git a/initrd/bin/cbfs-init b/initrd/bin/cbfs-init index a5ca711c..3c5e753e 100755 --- a/initrd/bin/cbfs-init +++ b/initrd/bin/cbfs-init @@ -8,9 +8,8 @@ if [ -z "$CBFS_PCR" ]; then fi # Load individual files -cbfsfiles=`cbfs -l 2>/dev/null | grep "^initrd/"` # \ -# || die "cbfs list files failed" -# qemu dies - ignore check for now +cbfsfiles=`cbfs -t 50 -l 2>/dev/null | grep "^initrd/"` \ + || die "cbfs list files failed" for cbfsname in `echo $cbfsfiles`; do filename=${cbfsname:6} @@ -18,7 +17,7 @@ for cbfsname in `echo $cbfsfiles`; do echo "Loading $filename from CBFS" mkdir -p `dirname $filename` \ || die "$filename: mkdir failed" - cbfs -r $cbfsname > "$filename" \ + cbfs -t 50 -r $cbfsname > "$filename" \ || die "$filename: cbfs file read failed" if [ "$CONFIG_TPM" = "y" ]; then TMPFILE=/tmp/cbfs.$$ diff --git a/patches/flashtools.patch b/patches/flashtools.patch index 97ed3bd0..4b21e04c 100644 --- a/patches/flashtools.patch +++ b/patches/flashtools.patch @@ -8,7 +8,7 @@ index eb53396..bf46e4e 100644 poke +cbfs diff --git ./Makefile ./Makefile -index 27e28b5..ffb187c 100644 +index 27e28b5..f02daee 100644 --- ./Makefile +++ ./Makefile @@ -1,6 +1,7 @@ @@ -23,16 +23,16 @@ index 27e28b5..ffb187c 100644 flashtool: flashtool.o spiflash.o util.o peek: peek.o util.o poke: poke.o util.o -+cbfs: cbfs.o ++cbfs: cbfs.o util.o $(TARGETS): $(CC) $(LDFLAGS) -o $@ $^ diff --git ./cbfs.c ./cbfs.c new file mode 100644 -index 0000000..7e11c88 +index 0000000..bab5f76 --- /dev/null +++ ./cbfs.c -@@ -0,0 +1,267 @@ +@@ -0,0 +1,271 @@ +#include +#include +#include @@ -43,6 +43,7 @@ index 0000000..7e11c88 +#include +#include +#include ++#include "util.h" + +#define CBFS_HEADER_MAGIC 0x4F524243 +#define CBFS_HEADER_VERSION1 0x31313131 @@ -55,6 +56,7 @@ index 0000000..7e11c88 + { "verbose", 0, NULL, 'v' }, + { "read", 1, NULL, 'r' }, + { "list", 0, NULL, 'l' }, ++ { "type", 0, NULL, 't' }, + { "help", 0, NULL, 'h' }, + { NULL, 0, NULL, 0 }, +}; @@ -65,8 +67,9 @@ index 0000000..7e11c88 +"\n" +"-h | -? | --help This help\n" +"-v | --verbose Increase verbosity\n" -+"-r | --read file Read the CBFS filed and dump to stdout\n" -+"-l | --list List the raw files in the CBFS\n" ++"-r | --read file Export a CBFS file to stdout\n" ++"-l | --list List the names of CBFS files\n" ++"-t | --type 50 Filter to specific CBFS file type (hex)\n" +"\n"; + +struct cbfs_header { @@ -106,8 +109,11 @@ index 0000000..7e11c88 + int opt; + int do_read = 0; + int do_list = 0; ++ int do_type = 0; ++ uint32_t cbfs_file_type = 0; + const char * filename = NULL; -+ while ((opt = getopt_long(argc, argv, "h?vlr:", long_options, NULL)) != -1) ++ while ((opt = getopt_long(argc, argv, "h?vlr:t:", ++ long_options, NULL)) != -1) + { + switch(opt) + { @@ -121,8 +127,12 @@ index 0000000..7e11c88 + do_read = 1; + filename = optarg; + break; ++ case 't': ++ do_type = 1; ++ cbfs_file_type = strtoul(optarg, NULL, 16); ++ break; + case '?': case 'h': -+ printf("%s", usage); ++ fprintf(stderr, "%s", usage); + return EXIT_SUCCESS; + default: + fprintf(stderr, "%s", usage); @@ -147,20 +157,13 @@ index 0000000..7e11c88 + + uint64_t end = 0x100000000; + if (verbose) { -+ printf("Seeking to %lx\n", end-4); ++ fprintf(stderr, "Seeking to %lx\n", end-4); + } -+ if (lseek(fd, end-4, SEEK_SET) == -1) { -+ fprintf(stderr, "Failed to seek to %lx\n", end-4); -+ return EXIT_FAILURE; -+ } -+ + int32_t header_delta; -+ if (read(fd, &header_delta, sizeof(header_delta)) < 0) { -+ fprintf(stderr, "Failed to read header offset\n"); -+ return EXIT_FAILURE; -+ } ++ copy_physical(end-4, sizeof(header_delta), &header_delta); ++ + if (verbose) { -+ printf("Header Offset: %d\n", header_delta); ++ fprintf(stderr, "Header Offset: %d\n", header_delta); + } + + uint64_t header_off; @@ -171,18 +174,11 @@ index 0000000..7e11c88 + } + + if (verbose) { -+ printf("Seeking to %lx\n", header_off); ++ fprintf(stderr, "Seeking to %lx\n", header_off); + } -+ if (lseek(fd, header_off, SEEK_SET) == -1) { -+ fprintf(stderr, "Failed to seek to %lx\n", header_off); -+ return EXIT_FAILURE; -+ } -+ + struct cbfs_header header; -+ if (read(fd, &header, sizeof(struct cbfs_header)) < 0) { -+ fprintf(stderr, "Failed to read header\n"); -+ return EXIT_FAILURE; -+ } ++ copy_physical(header_off, sizeof(struct cbfs_header), &header); ++ + header.magic = ntohl(header.magic); + header.version = ntohl(header.version); + header.romsize = ntohl(header.romsize); @@ -192,13 +188,13 @@ index 0000000..7e11c88 + header.architecture = ntohl(header.architecture); + + if (verbose) { -+ printf("Header magic : %x\n", header.magic); -+ printf("Header version : %x\n", header.version); -+ printf("Header ROM size : %x\n", header.romsize); -+ printf("Header boot block size: %x\n", header.bootblocksize); -+ printf("Header align : %x\n", header.align); -+ printf("Header offset : %x\n", header.offset); -+ printf("Header arch : %x\n", header.architecture); ++ fprintf(stderr, "Header magic : %x\n", header.magic); ++ fprintf(stderr, "Header version : %x\n", header.version); ++ fprintf(stderr, "Header ROM size : %x\n", header.romsize); ++ fprintf(stderr, "Header boot block size: %x\n", header.bootblocksize); ++ fprintf(stderr, "Header align : %x\n", header.align); ++ fprintf(stderr, "Header offset : %x\n", header.offset); ++ fprintf(stderr, "Header arch : %x\n", header.architecture); + } + + if (header.magic != CBFS_HEADER_MAGIC) { @@ -208,21 +204,14 @@ index 0000000..7e11c88 + + uint32_t align = header.align; + // loop through files -+ uint64_t off = end - ((uint64_t) header.romsize) + ((uint64_t) header.offset); -+ while (1) { ++ uint64_t off = end - ((uint64_t) header.romsize) + ++ ((uint64_t) header.offset); ++ while (off < end) { + if (verbose) { -+ printf("Potential CBFS File Offset: %lx\n", off); ++ fprintf(stderr, "Potential CBFS File Offset: %lx\n", off); + } -+ if (lseek(fd, off, SEEK_SET) == -1) { -+ fprintf(stderr, "Failed to seek to next CBFS offset %lx\n", off); -+ return EXIT_FAILURE; -+ } -+ + struct cbfs_file file; -+ if (read(fd, &file, sizeof(struct cbfs_file)) < 0) { -+ fprintf(stderr, "Failed to read cbfs file header\n"); -+ return EXIT_FAILURE; -+ } ++ copy_physical(off, sizeof(struct cbfs_file), &file); + + file.len = ntohl(file.len); + file.type = ntohl(file.type); @@ -230,11 +219,11 @@ index 0000000..7e11c88 + file.offset = ntohl(file.offset); + + if (verbose) { -+ printf("File magic : %.8s\n", file.magic); -+ printf("File len : %x\n", file.len); -+ printf("File type : %x\n", file.type); -+ printf("File attributes_offset : %x\n", file.attributes_offset); -+ printf("File offset : %x\n", file.offset); ++ fprintf(stderr, "File magic : %.8s\n", file.magic); ++ fprintf(stderr, "File len : %x\n", file.len); ++ fprintf(stderr, "File type : %x\n", file.type); ++ fprintf(stderr, "File attributes_offset : %x\n", file.attributes_offset); ++ fprintf(stderr, "File offset : %x\n", file.offset); + } + + if (strncmp((char *)file.magic, CBFS_FILE_MAGIC, 8) != 0) { @@ -243,53 +232,68 @@ index 0000000..7e11c88 + + size_t name_size = file.offset - sizeof(struct cbfs_file); + char *name = calloc(name_size, sizeof(char)); -+ if (read(fd, name, name_size) < 0) { -+ fprintf(stderr, "Failed to read cbfs file name\n"); -+ return EXIT_FAILURE; -+ } ++ copy_physical(off+sizeof(struct cbfs_file), name_size, name); ++ + if (verbose) { -+ printf("File name : '%s'\n", name); ++ fprintf(stderr, "File name : '%s'\n", name); + } + -+ if (do_list && file.type == 0x50) { ++ if (do_list && ++ (!do_type || (do_type && file.type == cbfs_file_type))) { + printf("%s\n", name); + } -+ if (do_read && file.type == 0x50 && ++ ++ if (do_read && ++ (!do_type || (do_type && file.type == cbfs_file_type)) && + strncmp(name, filename, name_size) == 0) + { + uint64_t file_off = off + file.offset; + if (verbose) { -+ printf("Seeking to %lx\n-------- Start Data\n", file_off); -+ } -+ if (lseek(fd, file_off, SEEK_SET) == -1) { -+ fprintf(stderr, "Failed to seek to file data at %lx\n", file_off); -+ return EXIT_FAILURE; ++ fprintf(stderr, "Seeking to %lx\n-------- Start Data\n", file_off); + } + + char *file_data = malloc(file.len); -+ if (read(fd, file_data, file.len) < 0) { -+ fprintf(stderr, "Failed to read file data\n"); ++ if (file_data == NULL) { ++ fprintf(stderr, "Failed to allocate memory for file data: length=%d\n", ++ file.len); + return EXIT_FAILURE; + } -+ if (write(STDOUT_FILENO, file_data, file.len) == -1) { -+ fprintf(stderr, "Failed to write file to stdout: %s\n", -+ strerror(errno)); -+ return EXIT_FAILURE; ++ copy_physical(file_off, file.len, file_data); ++ ++ for (size_t offset = 0 ; offset < file.len ; ) { ++ const ssize_t rc = write( ++ STDOUT_FILENO, ++ file_data + offset, ++ file.len - offset ++ ); ++ ++ if (rc <= 0) { ++ fprintf(stderr, "Failed to write file to stdout: %s\n", ++ strerror(errno)); ++ return EXIT_FAILURE; ++ } ++ ++ offset += rc; + } -+ free(file_data); ++ + if (verbose) { -+ printf("\n-------- End Data\n"); ++ fprintf(stderr, "\n-------- End Data\n"); + } ++ + do_read++; ++ free(file_data); ++ free(name); ++ break; + } + ++ free(name); + uint64_t inc = (align + (file.offset + file.len) - 1) & (~(align-1)); + off += inc; + if (verbose) { -+ printf("File Off+Len : %x\n", file.offset + file.len); -+ printf("Align : %x\n", align); -+ printf("Inc : %lx\n", inc); -+ printf("Next file align : %lx\n", off); ++ fprintf(stderr, "File Off+Len : %x\n", file.offset + file.len); ++ fprintf(stderr, "Align : %x\n", align); ++ fprintf(stderr, "Inc : %lx\n", inc); ++ fprintf(stderr, "Next file align : %lx\n", off); + } + } + @@ -300,3 +304,61 @@ index 0000000..7e11c88 + + return EXIT_SUCCESS; +} +diff --git ./flashtool.c ./flashtool.c +index be429e8..a756519 100644 +--- ./flashtool.c ++++ ./flashtool.c +@@ -204,8 +204,8 @@ write_to_spi( + #ifdef __darwin__ + #define PCIEXBAR 0xE0000000 // MBP11,2 + #else +-#define PCIEXBAR 0x80000000 // Winterfell +-//#define PCIEXBAR 0xF8000000 // x230 ++//#define PCIEXBAR 0x80000000 // Winterfell ++#define PCIEXBAR 0xF8000000 // x230 + #endif + + int +diff --git ./util.c ./util.c +index 55ae71f..d79eda7 100644 +--- ./util.c ++++ ./util.c +@@ -153,3 +153,22 @@ map_physical( + + return (void *)(addr + page_offset); + } ++ ++void ++copy_physical( ++ uint64_t phys_addr, ++ size_t len, ++ volatile void * dest ++) ++{ ++ const uint8_t * const buf = map_physical(phys_addr, len); ++ if (buf == NULL) ++ { ++ perror("mmap"); ++ exit(EXIT_FAILURE); ++ } ++ ++ memcpy(dest, buf, len); ++ ++ munmap((uint8_t *)buf, len); ++} +diff --git ./util.h ./util.h +index 6846007..d9fb59c 100644 +--- ./util.h ++++ ./util.h +@@ -34,4 +34,11 @@ memcpy_width( + mem_op_t op + ); + ++extern void ++copy_physical( ++ uint64_t phys_addr, ++ size_t len, ++ volatile void *dest ++); ++ + #endif From 8b1d194b5a13cf586e3e15318b044f99442f4ac1 Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Sat, 31 Mar 2018 15:36:14 -0700 Subject: [PATCH 4/9] Update flashtools patch with latest --- patches/flashtools.patch | 66 ++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 37 deletions(-) diff --git a/patches/flashtools.patch b/patches/flashtools.patch index 4b21e04c..8b859b3f 100644 --- a/patches/flashtools.patch +++ b/patches/flashtools.patch @@ -29,10 +29,10 @@ index 27e28b5..f02daee 100644 $(CC) $(LDFLAGS) -o $@ $^ diff --git ./cbfs.c ./cbfs.c new file mode 100644 -index 0000000..bab5f76 +index 0000000..c0ddf48 --- /dev/null +++ ./cbfs.c -@@ -0,0 +1,271 @@ +@@ -0,0 +1,262 @@ +#include +#include +#include @@ -56,7 +56,7 @@ index 0000000..bab5f76 + { "verbose", 0, NULL, 'v' }, + { "read", 1, NULL, 'r' }, + { "list", 0, NULL, 'l' }, -+ { "type", 0, NULL, 't' }, ++ { "type", 1, NULL, 't' }, + { "help", 0, NULL, 'h' }, + { NULL, 0, NULL, 0 }, +}; @@ -140,6 +140,11 @@ index 0000000..bab5f76 + } + } + ++ if (!do_list && !do_read) { ++ fprintf(stderr, "%s", usage); ++ return EXIT_FAILURE; ++ } ++ + argc -= optind; + argv += optind; + if (argc != 0) @@ -148,14 +153,8 @@ index 0000000..bab5f76 + return EXIT_FAILURE; + } + -+ int fd; -+ fd = open("/dev/mem", O_RDONLY); -+ if (fd < 0) { -+ fprintf(stderr, "Failed to open /dev/mem : %s\n", strerror(errno)); -+ return EXIT_FAILURE; -+ } -+ + uint64_t end = 0x100000000; ++ + if (verbose) { + fprintf(stderr, "Seeking to %lx\n", end-4); + } @@ -166,18 +165,13 @@ index 0000000..bab5f76 + fprintf(stderr, "Header Offset: %d\n", header_delta); + } + -+ uint64_t header_off; -+ if (header_delta < 0) { -+ header_off = end - ((uint64_t)(-header_delta)); -+ } else { -+ header_off = ((uint64_t)header_delta); -+ } ++ uint64_t header_off = end + header_delta; + + if (verbose) { + fprintf(stderr, "Seeking to %lx\n", header_off); + } + struct cbfs_header header; -+ copy_physical(header_off, sizeof(struct cbfs_header), &header); ++ copy_physical(header_off, sizeof(header), &header); + + header.magic = ntohl(header.magic); + header.version = ntohl(header.version); @@ -203,15 +197,17 @@ index 0000000..bab5f76 + } + + uint32_t align = header.align; ++ + // loop through files + uint64_t off = end - ((uint64_t) header.romsize) + + ((uint64_t) header.offset); ++ void *rom = map_physical(off, end - off); + while (off < end) { + if (verbose) { + fprintf(stderr, "Potential CBFS File Offset: %lx\n", off); + } + struct cbfs_file file; -+ copy_physical(off, sizeof(struct cbfs_file), &file); ++ memcpy(&file, rom, sizeof(file)); + + file.len = ntohl(file.len); + file.type = ntohl(file.type); @@ -230,9 +226,8 @@ index 0000000..bab5f76 + break; + } + -+ size_t name_size = file.offset - sizeof(struct cbfs_file); -+ char *name = calloc(name_size, sizeof(char)); -+ copy_physical(off+sizeof(struct cbfs_file), name_size, name); ++ size_t name_size = file.offset - sizeof(file); ++ char *name = (char *)rom + sizeof(file); + + if (verbose) { + fprintf(stderr, "File name : '%s'\n", name); @@ -252,14 +247,12 @@ index 0000000..bab5f76 + fprintf(stderr, "Seeking to %lx\n-------- Start Data\n", file_off); + } + -+ char *file_data = malloc(file.len); -+ if (file_data == NULL) { -+ fprintf(stderr, "Failed to allocate memory for file data: length=%d\n", -+ file.len); ++ if (file_off + file.len > end) { ++ fprintf(stderr, "File offset/length extends beyond ROM"); + return EXIT_FAILURE; + } -+ copy_physical(file_off, file.len, file_data); + ++ char *file_data = (char *) rom + file.offset; + for (size_t offset = 0 ; offset < file.len ; ) { + const ssize_t rc = write( + STDOUT_FILENO, @@ -281,19 +274,17 @@ index 0000000..bab5f76 + } + + do_read++; -+ free(file_data); -+ free(name); + break; + } + -+ free(name); + uint64_t inc = (align + (file.offset + file.len) - 1) & (~(align-1)); + off += inc; ++ rom += inc; + if (verbose) { + fprintf(stderr, "File Off+Len : %x\n", file.offset + file.len); + fprintf(stderr, "Align : %x\n", align); + fprintf(stderr, "Inc : %lx\n", inc); -+ fprintf(stderr, "Next file align : %lx\n", off); ++ fprintf(stderr, "Next file off : %lx\n", off); + } + } + @@ -320,13 +311,16 @@ index be429e8..a756519 100644 int diff --git ./util.c ./util.c -index 55ae71f..d79eda7 100644 +index 55ae71f..a3cf593 100644 --- ./util.c +++ ./util.c -@@ -153,3 +153,22 @@ map_physical( +@@ -151,5 +151,22 @@ map_physical( - return (void *)(addr + page_offset); - } + close(fd); + +- return (void *)(addr + page_offset); ++ return (void *)(addr + page_offset); ++} + +void +copy_physical( @@ -343,9 +337,7 @@ index 55ae71f..d79eda7 100644 + } + + memcpy(dest, buf, len); -+ -+ munmap((uint8_t *)buf, len); -+} + } diff --git ./util.h ./util.h index 6846007..d9fb59c 100644 --- ./util.h From 8644a3648863398ae655efc495dd3e9cb89ee308 Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Fri, 20 Apr 2018 10:46:08 -0700 Subject: [PATCH 5/9] Drop unnecessary flashtools.patch Also added convenience call to import keys and removed credentials --- initrd/.gnupg/pubring.gpg | Bin 1785 -> 0 bytes initrd/.gnupg/secring.gpg | Bin 1860 -> 0 bytes initrd/.gnupg/trustdb.gpg | Bin 1280 -> 0 bytes initrd/.ssh/authorized_keys | 1 - initrd/bin/cbfs-init | 4 +- patches/flashtools.patch | 356 ------------------------------------ 6 files changed, 3 insertions(+), 358 deletions(-) delete mode 100644 initrd/.gnupg/pubring.gpg delete mode 100644 initrd/.gnupg/secring.gpg delete mode 100644 initrd/.gnupg/trustdb.gpg delete mode 100644 initrd/.ssh/authorized_keys delete mode 100644 patches/flashtools.patch diff --git a/initrd/.gnupg/pubring.gpg b/initrd/.gnupg/pubring.gpg deleted file mode 100644 index 8963af39708ff3b883da488a2d8c49796ef7e1ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1785 zcmZwGX;=~n0>*I;0TG!r^G-$b!~+d!cC;){)G)=gJW9es@yG*pl!O_NEJ1WMv+_ps zsKIr@t1J~yP>aUG`zp`2a@9u7YCLAzefHUXcK7T1@&EkZ0w7Yxcg6e}P!>>auys}S zt88hnnvwxcTnor$ z_%Dp_B7GceX1v03?^^fN1a~#`+q~|Gab8qEg^kON8xbhZ-H0~|_8%&u_?AcpF$K=| zl4`xW4VDR?@IR<^e)&sTKMD|l@ezmc7>>{H9G#lzL@w&9 z?2j>g)sIZvTnt;72abl^)Yx-%Dk?7A-}W9N9xJ?JSXe8d%J5*FD90>IA{!8Jbou%jPTdXy+38B53m^oY_5@rl0m@f!2 z(Z_`SK|uWRAYUi+n_B;|aFeA=I%qQt53<3iPnede=!2*e#WBsM?~?4n$TzKitqNyd zKW62K*2uI2c-%ti>a1Jf>5DmqZh5Jn(r`Xu&<3onzOl0CX;zwb;=yxuczT~u9Eb)~ z*DELAUGek1X&N1VKcv6prl?6EQ6!ydWfSEJ6&wYEr^4+?GUAOaX_gRu1^q61O_@uX zwJe=3L2j1stFL*RGS}x1jo^arCT|M8sZFPo> zWnObTLD$V&lGd@c2?{{N-DNeZb|xh^tRxstneQBWxTJwyS69ub14j0UR5hVsX}aF2 z!l+!gmXCk`F*@u5h<4V(&hNK}LL`$n_&QeA2^_~X6)PCF_MJ^zPDXFk^vcq9mX4m9 zLP6v)-HUe~)o_qNPfW98MC1d#gF|+`uBt&68lCeip5;O8L$ZlM9)a^I zDeZAtv-G5tT9_ht&l_6p2Jg5P{P}+VHgg?Yu3o z(~i#(*q*1ZrkjbCItXkCop56T!!M*Gt@xA+9Gm8l^`V4Aq6psn;~wXkfd#vhMiark zFORLwNqgWwofCTcd4NNkF3B?}931hsi;Y=oWTo%m1Z#6;F}k4GRw_}>#Gr^yieO9D z&!Szo3`XvU8)$G~oUwf6j^NfULFVa6EZJoeQd|LjB$|dO&i9EOeg2REEqMMSLWd!=McGi&L$18uZ+c@I+3pgJ%h4BE}=#ZqE1&rRb z%M?G-t7{x8x%(@hM1Mv}+Cmx_joWdhYmXJX@qHo8_g~0={%EFGayj&zrV;4w3FZH? zlQVvtP~=+`=<>M@L?ejQm4*-AxWo8K+oy`*hc=cjG;Y zIy?h{adRGFRo6gmI>@WcL5GO{BxNvyHVnu-jFmO}r#L+G{?xS>dL8B2>J3Pt z%IG#{W2%3(_OH%8ZK~NCR_KeF3x#;+C}HLAvUvk%4u=M=nAmaM^*pyvpESt$;rjKXs!GH`d@H{>j!AcBGQEG>?VkB4?XLM(H}w7TnZ7X9-NM@uZm&{_ZAj{N`H z;h|uA_FDT?NM03$E~s|?GR7P^8|NDqB7V_sfY z*cTT*Cu*4IZly``8J&@w^a%Gm^&cknO|o}(&`*dqI6G_YZHFA~6O%(mdy;}L-&X~W z5OSfV>xX?kfYLhpQsYLE>2ji0Q*vdtk>X}c=;T}%IEi^gl#o9nsp_p*Lsk7;Hg>7A zTpmj%yTX+Yo`LOFNm#{%>m^#LwMsyRx)uxSChZ5!(HzhCN)M;pQDd_pn0-JatT)ft zLnp`G-lwS5#$Gdw;d_ E2bz>0U;qFB diff --git a/initrd/.gnupg/secring.gpg b/initrd/.gnupg/secring.gpg deleted file mode 100644 index c8bdd473d409a2a33fe4b839d84a8fbaa0e212a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1860 zcmb8uXHXLe0tMg{k`O}HAkqawq=phO#JvSYsR0aCP>K?R211b%K!_x}6j2fa3nCV3 zK#FcS*3fJ~s0pBPk?)jLABgszBu!EXu=tr8PmznHg6K-XKoxk=E%GZ)N_?IR%>aD+c>0~5;noG9iE!# zKrZSj?~OHh*@sNpTnt~B2abkbSKoDUEGjPC+xiY79xJK#-!v{n|)kgGM3q?D(+0;Tq@fY0#MU}$-AP=9v z6h7Qpdfv9hS~Hyx+Np|}!xbW7=0Kv^f*=cXMA#P$BpeO)bHu!^4H%0sUOKOhF~#yA z8;ttIX_<;%h#E;8+idbS*$#|+-QwSZI_2^qJ6E(urtKr(7fM%WU4u@X%Pn-xPy3jT z_YH?O;B54altfRn)2)*BpROa&dxhd444}GRDdo5QrYhjf>zyEdjl7Gn*9J;)Erf1voBpJuN;(Cm(lfNXbV`~vnK!Y#Ks#L8kN?v$L z2%IwCG4xK3VJK*7=sUH8K1Jl97b{{B-;_*oF`l)0_{?+=7XCU4+X zoQfkjo@pXR8MO4CN?%UFY}E9~(sq^(yHBAZ^4PA$TMuhENT4US*&#COzV7}Z+a4E{ zU~~13`4!LdV0IFUDu^~t=h(Qe5u}IUd`fCteD*9oIkgt1z}@wMR=dL6Z-jihSFp`o zhag!h@FQ7;=?L}EJk}p8g)-u%`3!3CRg zSNbb&{^s3>^V}A2-fIXG05&n9$u$dD-D&43ew26TI8<`yH@+AB86|lOsc$%L%ayJ@ zR_G%1hBDuMCVxHHOpoM3*l7(z(4AvS|A8uZ{3x-=uPVs-Q!9u@6sai=A=){CTqfYk zi*yS~CecNWB$=?_kKdiTbm+ZIW-AUR!eWFowK5tvOoL%|fsL@9d?OF-TsMy=t3LjK8;@1kFU)$L-Yno0z|P28 e=wRgVyu#5$k)=|cvD$EExe#7am09ic4b`93?JRl# diff --git a/initrd/.gnupg/trustdb.gpg b/initrd/.gnupg/trustdb.gpg deleted file mode 100644 index 929b06874eaecac2f20ab5f26374306b5b752afd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1280 zcmZQfFGy!*W@Ke#Vql1Pr}s7Le3B0XCSc^k6vHYq M#5HZGI)pL?00wp!nE(I) diff --git a/initrd/.ssh/authorized_keys b/initrd/.ssh/authorized_keys deleted file mode 100644 index c90a2b76..00000000 --- a/initrd/.ssh/authorized_keys +++ /dev/null @@ -1 +0,0 @@ -ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCuf59gWFcsnxdXAj7wvbzYto6JTmCF3pAXRS2RGipJUOqmWFayL8mKKLJMPpLoB60oaFno6+Uedbm93v/UQvt1FMWbhBe6Y15KawXEnmX1pjCfGbfbB9UC+EM8l9QPaQfdgCGt8e/CeM+kQKQ0X38d9WvaSNoP0EC9xoMsx7scbhy5O1VtmUYuDNXC2ZtAmCQLS2rC5RyweLA0DFWbmyOa75STEOYe0xuG8Kix7gBUP/LwawZN8URrszTzJonewYEF/PQoltcCnqkIbgVvMnm1N/hS42/911gPzlD29F1ZjhVplraOtlRKD0D5ogR5/5hKyL48MRbt9pi7lm0MtdeR hudson@diamond diff --git a/initrd/bin/cbfs-init b/initrd/bin/cbfs-init index 3c5e753e..5108159d 100755 --- a/initrd/bin/cbfs-init +++ b/initrd/bin/cbfs-init @@ -30,4 +30,6 @@ for cbfsname in `echo $cbfsfiles`; do done # TODO: copy CBFS file named "initrd.tgz" to /tmp, measure and extract -# TODO: key convenience: take "keys/*.asc" and gpg --import them + +# Post processing of keys +gpg --import /.gnupg/keys/* 2>/dev/null || true diff --git a/patches/flashtools.patch b/patches/flashtools.patch deleted file mode 100644 index 8b859b3f..00000000 --- a/patches/flashtools.patch +++ /dev/null @@ -1,356 +0,0 @@ -diff --git ./.gitignore ./.gitignore -index eb53396..bf46e4e 100644 ---- ./.gitignore -+++ ./.gitignore -@@ -5,3 +5,4 @@ - flashtool - peek - poke -+cbfs -diff --git ./Makefile ./Makefile -index 27e28b5..f02daee 100644 ---- ./Makefile -+++ ./Makefile -@@ -1,6 +1,7 @@ - TARGETS += flashtool - TARGETS += poke - TARGETS += peek -+TARGETS += cbfs - - CFLAGS += \ - -std=c99 \ -@@ -17,6 +18,7 @@ all: $(TARGETS) - flashtool: flashtool.o spiflash.o util.o - peek: peek.o util.o - poke: poke.o util.o -+cbfs: cbfs.o util.o - - $(TARGETS): - $(CC) $(LDFLAGS) -o $@ $^ -diff --git ./cbfs.c ./cbfs.c -new file mode 100644 -index 0000000..c0ddf48 ---- /dev/null -+++ ./cbfs.c -@@ -0,0 +1,262 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "util.h" -+ -+#define CBFS_HEADER_MAGIC 0x4F524243 -+#define CBFS_HEADER_VERSION1 0x31313131 -+#define CBFS_HEADER_VERSION2 0x31313132 -+#define CBFS_HEADER_VERSION CBFS_HEADER_VERSION2 -+ -+int verbose = 0; -+ -+static const struct option long_options[] = { -+ { "verbose", 0, NULL, 'v' }, -+ { "read", 1, NULL, 'r' }, -+ { "list", 0, NULL, 'l' }, -+ { "type", 1, NULL, 't' }, -+ { "help", 0, NULL, 'h' }, -+ { NULL, 0, NULL, 0 }, -+}; -+ -+ -+static const char usage[] = -+"Usage: sudo cbfs [options]\n" -+"\n" -+"-h | -? | --help This help\n" -+"-v | --verbose Increase verbosity\n" -+"-r | --read file Export a CBFS file to stdout\n" -+"-l | --list List the names of CBFS files\n" -+"-t | --type 50 Filter to specific CBFS file type (hex)\n" -+"\n"; -+ -+struct cbfs_header { -+ uint32_t magic; -+ uint32_t version; -+ uint32_t romsize; -+ uint32_t bootblocksize; -+ uint32_t align; /* hard coded to 64 byte */ -+ uint32_t offset; -+ uint32_t architecture; /* Version 2 */ -+ uint32_t pad[1]; -+}; -+ -+#define CBFS_FILE_MAGIC "LARCHIVE" -+ -+struct cbfs_file { -+ uint8_t magic[8]; -+ /* length of file data */ -+ uint32_t len; -+ uint32_t type; -+ /* offset to struct cbfs_file_attribute or 0 */ -+ uint32_t attributes_offset; -+ /* length of header incl. variable data */ -+ uint32_t offset; -+ char filename[]; -+}; -+ -+ -+int main(int argc, char** argv) { -+ const char * const prog_name = argv[0]; -+ if (argc <= 1) -+ { -+ fprintf(stderr, "%s", usage); -+ return EXIT_FAILURE; -+ } -+ -+ int opt; -+ int do_read = 0; -+ int do_list = 0; -+ int do_type = 0; -+ uint32_t cbfs_file_type = 0; -+ const char * filename = NULL; -+ while ((opt = getopt_long(argc, argv, "h?vlr:t:", -+ long_options, NULL)) != -1) -+ { -+ switch(opt) -+ { -+ case 'v': -+ verbose++; -+ break; -+ case 'l': -+ do_list = 1; -+ break; -+ case 'r': -+ do_read = 1; -+ filename = optarg; -+ break; -+ case 't': -+ do_type = 1; -+ cbfs_file_type = strtoul(optarg, NULL, 16); -+ break; -+ case '?': case 'h': -+ fprintf(stderr, "%s", usage); -+ return EXIT_SUCCESS; -+ default: -+ fprintf(stderr, "%s", usage); -+ return EXIT_FAILURE; -+ } -+ } -+ -+ if (!do_list && !do_read) { -+ fprintf(stderr, "%s", usage); -+ return EXIT_FAILURE; -+ } -+ -+ argc -= optind; -+ argv += optind; -+ if (argc != 0) -+ { -+ fprintf(stderr, "%s: Excess arguments?\n", prog_name); -+ return EXIT_FAILURE; -+ } -+ -+ uint64_t end = 0x100000000; -+ -+ if (verbose) { -+ fprintf(stderr, "Seeking to %lx\n", end-4); -+ } -+ int32_t header_delta; -+ copy_physical(end-4, sizeof(header_delta), &header_delta); -+ -+ if (verbose) { -+ fprintf(stderr, "Header Offset: %d\n", header_delta); -+ } -+ -+ uint64_t header_off = end + header_delta; -+ -+ if (verbose) { -+ fprintf(stderr, "Seeking to %lx\n", header_off); -+ } -+ struct cbfs_header header; -+ copy_physical(header_off, sizeof(header), &header); -+ -+ header.magic = ntohl(header.magic); -+ header.version = ntohl(header.version); -+ header.romsize = ntohl(header.romsize); -+ header.bootblocksize = ntohl(header.bootblocksize); -+ header.align = ntohl(header.align); -+ header.offset = ntohl(header.offset); -+ header.architecture = ntohl(header.architecture); -+ -+ if (verbose) { -+ fprintf(stderr, "Header magic : %x\n", header.magic); -+ fprintf(stderr, "Header version : %x\n", header.version); -+ fprintf(stderr, "Header ROM size : %x\n", header.romsize); -+ fprintf(stderr, "Header boot block size: %x\n", header.bootblocksize); -+ fprintf(stderr, "Header align : %x\n", header.align); -+ fprintf(stderr, "Header offset : %x\n", header.offset); -+ fprintf(stderr, "Header arch : %x\n", header.architecture); -+ } -+ -+ if (header.magic != CBFS_HEADER_MAGIC) { -+ fprintf(stderr, "Failed to find valid header\n"); -+ return EXIT_FAILURE; -+ } -+ -+ uint32_t align = header.align; -+ -+ // loop through files -+ uint64_t off = end - ((uint64_t) header.romsize) + -+ ((uint64_t) header.offset); -+ void *rom = map_physical(off, end - off); -+ while (off < end) { -+ if (verbose) { -+ fprintf(stderr, "Potential CBFS File Offset: %lx\n", off); -+ } -+ struct cbfs_file file; -+ memcpy(&file, rom, sizeof(file)); -+ -+ file.len = ntohl(file.len); -+ file.type = ntohl(file.type); -+ file.attributes_offset = ntohl(file.attributes_offset); -+ file.offset = ntohl(file.offset); -+ -+ if (verbose) { -+ fprintf(stderr, "File magic : %.8s\n", file.magic); -+ fprintf(stderr, "File len : %x\n", file.len); -+ fprintf(stderr, "File type : %x\n", file.type); -+ fprintf(stderr, "File attributes_offset : %x\n", file.attributes_offset); -+ fprintf(stderr, "File offset : %x\n", file.offset); -+ } -+ -+ if (strncmp((char *)file.magic, CBFS_FILE_MAGIC, 8) != 0) { -+ break; -+ } -+ -+ size_t name_size = file.offset - sizeof(file); -+ char *name = (char *)rom + sizeof(file); -+ -+ if (verbose) { -+ fprintf(stderr, "File name : '%s'\n", name); -+ } -+ -+ if (do_list && -+ (!do_type || (do_type && file.type == cbfs_file_type))) { -+ printf("%s\n", name); -+ } -+ -+ if (do_read && -+ (!do_type || (do_type && file.type == cbfs_file_type)) && -+ strncmp(name, filename, name_size) == 0) -+ { -+ uint64_t file_off = off + file.offset; -+ if (verbose) { -+ fprintf(stderr, "Seeking to %lx\n-------- Start Data\n", file_off); -+ } -+ -+ if (file_off + file.len > end) { -+ fprintf(stderr, "File offset/length extends beyond ROM"); -+ return EXIT_FAILURE; -+ } -+ -+ char *file_data = (char *) rom + file.offset; -+ for (size_t offset = 0 ; offset < file.len ; ) { -+ const ssize_t rc = write( -+ STDOUT_FILENO, -+ file_data + offset, -+ file.len - offset -+ ); -+ -+ if (rc <= 0) { -+ fprintf(stderr, "Failed to write file to stdout: %s\n", -+ strerror(errno)); -+ return EXIT_FAILURE; -+ } -+ -+ offset += rc; -+ } -+ -+ if (verbose) { -+ fprintf(stderr, "\n-------- End Data\n"); -+ } -+ -+ do_read++; -+ break; -+ } -+ -+ uint64_t inc = (align + (file.offset + file.len) - 1) & (~(align-1)); -+ off += inc; -+ rom += inc; -+ if (verbose) { -+ fprintf(stderr, "File Off+Len : %x\n", file.offset + file.len); -+ fprintf(stderr, "Align : %x\n", align); -+ fprintf(stderr, "Inc : %lx\n", inc); -+ fprintf(stderr, "Next file off : %lx\n", off); -+ } -+ } -+ -+ if (do_read == 1) { -+ fprintf(stderr, "Failed to find CBFS file named '%s'\n", filename); -+ return EXIT_FAILURE; -+ } -+ -+ return EXIT_SUCCESS; -+} -diff --git ./flashtool.c ./flashtool.c -index be429e8..a756519 100644 ---- ./flashtool.c -+++ ./flashtool.c -@@ -204,8 +204,8 @@ write_to_spi( - #ifdef __darwin__ - #define PCIEXBAR 0xE0000000 // MBP11,2 - #else --#define PCIEXBAR 0x80000000 // Winterfell --//#define PCIEXBAR 0xF8000000 // x230 -+//#define PCIEXBAR 0x80000000 // Winterfell -+#define PCIEXBAR 0xF8000000 // x230 - #endif - - int -diff --git ./util.c ./util.c -index 55ae71f..a3cf593 100644 ---- ./util.c -+++ ./util.c -@@ -151,5 +151,22 @@ map_physical( - - close(fd); - -- return (void *)(addr + page_offset); -+ return (void *)(addr + page_offset); -+} -+ -+void -+copy_physical( -+ uint64_t phys_addr, -+ size_t len, -+ volatile void * dest -+) -+{ -+ const uint8_t * const buf = map_physical(phys_addr, len); -+ if (buf == NULL) -+ { -+ perror("mmap"); -+ exit(EXIT_FAILURE); -+ } -+ -+ memcpy(dest, buf, len); - } -diff --git ./util.h ./util.h -index 6846007..d9fb59c 100644 ---- ./util.h -+++ ./util.h -@@ -34,4 +34,11 @@ memcpy_width( - mem_op_t op - ); - -+extern void -+copy_physical( -+ uint64_t phys_addr, -+ size_t len, -+ volatile void *dest -+); -+ - #endif From 48ca75a482d27d714b31dc0aee17f481406f1326 Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Fri, 20 Apr 2018 15:11:12 -0700 Subject: [PATCH 6/9] Add "heads/" prefix to all Heads-related cbfs files Needed to identify which files should be preserved between upgrades such as "heads/initrd/*" or "heads/counter" --- initrd/bin/cbfs-init | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/initrd/bin/cbfs-init b/initrd/bin/cbfs-init index 5108159d..7589890f 100755 --- a/initrd/bin/cbfs-init +++ b/initrd/bin/cbfs-init @@ -8,11 +8,11 @@ if [ -z "$CBFS_PCR" ]; then fi # Load individual files -cbfsfiles=`cbfs -t 50 -l 2>/dev/null | grep "^initrd/"` \ +cbfsfiles=`cbfs -t 50 -l 2>/dev/null | grep "^heads/initrd/"` \ || die "cbfs list files failed" for cbfsname in `echo $cbfsfiles`; do - filename=${cbfsname:6} + filename=${cbfsname:12} if [ ! -z "$filename" ]; then echo "Loading $filename from CBFS" mkdir -p `dirname $filename` \ From 1cbae3cc12cae7c90b263a02d746c2f25e1a5e0d Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Sat, 21 Apr 2018 17:21:37 -0700 Subject: [PATCH 7/9] Preserve custom CBFS files on flashrom updates --- initrd/bin/cbfs-init | 3 +-- initrd/bin/flashrom-kgpe-d16.sh | 17 ++++++++++++++--- initrd/bin/flashrom-x230.sh | 17 ++++++++++++++--- initrd/etc/functions | 16 ++++++++++++++++ 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/initrd/bin/cbfs-init b/initrd/bin/cbfs-init index 7589890f..9c80d8bd 100755 --- a/initrd/bin/cbfs-init +++ b/initrd/bin/cbfs-init @@ -8,8 +8,7 @@ if [ -z "$CBFS_PCR" ]; then fi # Load individual files -cbfsfiles=`cbfs -t 50 -l 2>/dev/null | grep "^heads/initrd/"` \ - || die "cbfs list files failed" +cbfsfiles=`cbfs -t 50 -l 2>/dev/null | grep "^heads/initrd/"` for cbfsname in `echo $cbfsfiles`; do filename=${cbfsname:12} diff --git a/initrd/bin/flashrom-kgpe-d16.sh b/initrd/bin/flashrom-kgpe-d16.sh index 135c4b6c..801c1b83 100755 --- a/initrd/bin/flashrom-kgpe-d16.sh +++ b/initrd/bin/flashrom-kgpe-d16.sh @@ -1,13 +1,24 @@ #!/bin/sh . /etc/functions -ROM="$1" -if [ -z "$1" ]; then - die "Usage: $0 /media/kgpe-d16.rom" +if [ "$1" = "-c" ]; then + CLEAN=1 + ROM="$2" +else + CLEAN=0 + ROM="$1" +fi + +if [ ! -e "$ROM" ]; then + die "Usage: $0 [-c] /media/kgpe-d16.rom" fi cp "$ROM" /tmp/kgpe-d16.rom sha256sum /tmp/kgpe-d16.rom +if [ "$CLEAN" -eq 0 ]; then + preserve_rom /tmp/kgpe-d16.rom \ + || die "$ROM: Config preservation failed" +fi flashrom \ --force \ diff --git a/initrd/bin/flashrom-x230.sh b/initrd/bin/flashrom-x230.sh index 475d8263..ee978f32 100755 --- a/initrd/bin/flashrom-x230.sh +++ b/initrd/bin/flashrom-x230.sh @@ -1,13 +1,24 @@ #!/bin/sh . /etc/functions -ROM="$1" -if [ -z "$1" ]; then - die "Usage: $0 /media/x230.rom" +if [ "$1" = "-c" ]; then + CLEAN=1 + ROM="$2" +else + CLEAN=0 + ROM="$1" +fi + +if [ ! -e "$ROM" ]; then + die "Usage: $0 [-c] /media/x230.rom" fi cp "$ROM" /tmp/x230.rom sha256sum /tmp/x230.rom +if [ "$CLEAN" -eq 0 ]; then + preserve_rom /tmp/x230.rom \ + || die "$ROM: Config preservation failed" +fi flashrom \ --force \ diff --git a/initrd/etc/functions b/initrd/etc/functions index dd30d7a7..067eabc8 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -198,3 +198,19 @@ check_config() { cp $1/kexec*.txt /tmp/kexec \ || die "Failed to copy kexec boot params to tmp" } + +preserve_rom() { + new_rom="$1" + old_files=`cbfs -t 50 -l 2>/dev/null | grep "^heads/"` + + for old_file in `echo $old_files`; do + new_file=`cbfs -o $1 -l | grep -x $old_file` + if [ -z "$new_file" ]; then + echo "+++ Adding $old_file to $1" + cbfs -t 50 -r $old_file >/tmp/rom.$$ \ + || die "Failed to read cbfs file from ROM" + cbfs -o $1 -a $old_file -f /tmp/rom.$$ \ + || die "Failed to write cbfs file to new ROM file" + fi + done +} From 789c2db70d0013f3ae164a32fd408ae8689497d0 Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Sat, 21 Apr 2018 18:29:52 -0700 Subject: [PATCH 8/9] Add flashtool to all coreboot-based boards --- boards/kgpe-d16/kgpe-d16.config | 1 + boards/librem13v2/librem13v2.config | 1 + 2 files changed, 2 insertions(+) diff --git a/boards/kgpe-d16/kgpe-d16.config b/boards/kgpe-d16/kgpe-d16.config index f783f462..466fdf01 100644 --- a/boards/kgpe-d16/kgpe-d16.config +++ b/boards/kgpe-d16/kgpe-d16.config @@ -5,6 +5,7 @@ CONFIG_LINUX_CONFIG=config/linux-kgpe-d16.config CONFIG_CRYPTSETUP=y CONFIG_FLASHROM=y +CONFIG_FLASHTOOLS=y CONFIG_GPG=y CONFIG_KEXEC=y CONFIG_UTIL_LINUX=y diff --git a/boards/librem13v2/librem13v2.config b/boards/librem13v2/librem13v2.config index f029b45f..39a1b325 100644 --- a/boards/librem13v2/librem13v2.config +++ b/boards/librem13v2/librem13v2.config @@ -5,6 +5,7 @@ CONFIG_COREBOOT_CONFIG=config/coreboot-librem13v2.config export CONFIG_COREBOOT=y CONFIG_CRYPTSETUP=y CONFIG_FLASHROM=y +CONFIG_FLASHTOOLS=y CONFIG_GPG=y CONFIG_KEXEC=y CONFIG_UTIL_LINUX=y From c0f3a4bb79fda146c2733f42ff625e51e25068ba Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Sun, 29 Apr 2018 19:58:44 -0700 Subject: [PATCH 9/9] Read and measure an EFI file into initrd during init --- boards/qemu-linuxboot/qemu-linuxboot.config | 2 +- initrd/bin/cbfs-init | 11 +++----- initrd/bin/key-init | 8 ++++++ initrd/bin/uefi-init | 28 +++++++++++++++++++++ initrd/init | 4 +++ modules/flashtools | 1 + modules/linuxboot | 6 +++++ 7 files changed, 52 insertions(+), 8 deletions(-) create mode 100755 initrd/bin/key-init create mode 100755 initrd/bin/uefi-init diff --git a/boards/qemu-linuxboot/qemu-linuxboot.config b/boards/qemu-linuxboot/qemu-linuxboot.config index 2480ebd9..f7114174 100644 --- a/boards/qemu-linuxboot/qemu-linuxboot.config +++ b/boards/qemu-linuxboot/qemu-linuxboot.config @@ -1,6 +1,6 @@ # Configuration for emulating LinuxBoot+Heads with qemu # -CONFIG_LINUXBOOT=y +export CONFIG_LINUXBOOT=y CONFIG_LINUXBOOT_BOARD=qemu CONFIG_LINUX_CONFIG=config/linux-linuxboot.config diff --git a/initrd/bin/cbfs-init b/initrd/bin/cbfs-init index 9c80d8bd..ee6276a8 100755 --- a/initrd/bin/cbfs-init +++ b/initrd/bin/cbfs-init @@ -3,8 +3,8 @@ set -e -o pipefail . /etc/functions # Update initrd with CBFS files -if [ -z "$CBFS_PCR" ]; then - CBFS_PCR=7 +if [ -z "$CONFIG_PCR" ]; then + CONFIG_PCR=7 fi # Load individual files @@ -22,13 +22,10 @@ for cbfsname in `echo $cbfsfiles`; do TMPFILE=/tmp/cbfs.$$ echo "$filename" > $TMPFILE cat $filename >> $TMPFILE - tpm extend -ix "$CBFS_PCR" -if $TMPFILE \ + tpm extend -ix "$CONFIG_PCR" -if $TMPFILE \ || die "$filename: tpm extend failed" fi fi done -# TODO: copy CBFS file named "initrd.tgz" to /tmp, measure and extract - -# Post processing of keys -gpg --import /.gnupg/keys/* 2>/dev/null || true +# TODO: copy CBFS file named "heads/initrd.tgz" to /tmp, measure and extract diff --git a/initrd/bin/key-init b/initrd/bin/key-init new file mode 100755 index 00000000..2d684a8d --- /dev/null +++ b/initrd/bin/key-init @@ -0,0 +1,8 @@ +#!/bin/ash +set -e -o pipefail +. /etc/functions + +# Post processing of keys +gpg --import /.gnupg/keys/* 2>/dev/null || true + +# TODO: split out gpg keys into multiple rings by function diff --git a/initrd/bin/uefi-init b/initrd/bin/uefi-init new file mode 100755 index 00000000..600d2072 --- /dev/null +++ b/initrd/bin/uefi-init @@ -0,0 +1,28 @@ +#!/bin/ash +set -e -o pipefail +. /etc/functions + +# Update initrd with CBFS files +if [ -z "$CONFIG_PCR" ]; then + CONFIG_PCR=7 +fi + +CONFIG_GUID="74696e69-6472-632e-7069-6f2f75736572" + +# copy EFI file named $CONFIG_GUID to /tmp, measure and extract +GUID=`uefi -l | grep "^$CONFIG_GUID"` + +if [ -n "GUID" ]; then + echo "Loading $GUID from ROM" + TMPFILE=/tmp/uefi.$$ + uefi -r $GUID | gunzip -c > $TMPFILE \ + || die "Failed to read config GUID from ROM" + + if [ "$CONFIG_TPM" = "y" ]; then + tpm extend -ix "$CONFIG_PCR" -if $TMPFILE \ + || die "$filename: tpm extend failed" + fi + + ( cd / ; cpio -iud < $TMPFILE 2>/dev/null ) \ + || die "Failed to extract config GUID" +fi diff --git a/initrd/init b/initrd/init index 4bc5e865..d489f6ae 100755 --- a/initrd/init +++ b/initrd/init @@ -54,6 +54,10 @@ fi if [ "$CONFIG_COREBOOT" = "y" ]; then /bin/cbfs-init fi +if [ "$CONFIG_LINUXBOOT" = "y" ]; then + /bin/uefi-init +fi +/bin/key-init # Setup recovery serial shell if [ ! -z "$CONFIG_BOOT_RECOVERY_SERIAL" ]; then diff --git a/modules/flashtools b/modules/flashtools index fddd761e..d95c2152 100644 --- a/modules/flashtools +++ b/modules/flashtools @@ -21,6 +21,7 @@ flashtools_output := \ peek \ poke \ cbfs \ + uefi \ flashtools_libraries := \ diff --git a/modules/linuxboot b/modules/linuxboot index 7392bc2e..822b664c 100644 --- a/modules/linuxboot +++ b/modules/linuxboot @@ -24,10 +24,15 @@ linuxboot_configure := \ fi ; \ touch .config ; \ +ifdef CUSTOM + CUSTOMPWD=$(pwd)/$(CUSTOM) +endif + linuxboot_target := \ BOARD=$(linuxboot_board) \ KERNEL=$(build)/$(BOARD)/bzImage \ INITRD=$(build)/$(BOARD)/initrd.cpio.xz \ + CUSTOM=$(CUSTOMPWD) \ $(if $(CONFIG_LINUXBOOT_ROM), ROM=$(pwd)/$(CONFIG_LINUXBOOT_ROM)) \ all @@ -74,4 +79,5 @@ linuxboot.run: $(build)/$(BOARD)/linuxboot.rom BOARD:=$(linuxboot_board) \ KERNEL=$(build)/$(BOARD)/bzImage \ INITRD=$(build)/$(BOARD)/initrd.cpio.xz \ + CUSTOM=$(CUSTOMPWD) \ run