diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2015-02-09 18:15:17 -0800 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2015-04-22 08:59:18 +0200 |
commit | e1741c512c66c468f3c3399aff451ae428cd6824 (patch) | |
tree | 07e1d8aff86068e2f2f86b753713bec4ad8b2549 | |
parent | cb6bb3bc47bf55e47bdc60c53c5f40617c6a8d9b (diff) |
broadcom/cygnus: add secimage and sign bootblock
secimage is a tool which adds a header and signature to the binary
first loaded by the soc. ARM core frequency is set to 1 Ghz.
BUG=chrome-os-partner:36421
BRANCH=broadcom-firmware
TEST=booted b0 board
Change-Id: Ia08600d45c47ee4f08d253980036916e44b0044a
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 36284d1b242c26b0b5aac2894f7ed1790da1ef15
Original-Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Original-Reviewed-on: https://chrome-internal-review.googlesource.com/197155
Original-Reviewed-by: Scott Branden <sbranden@broadcom.com>
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
Original-Commit-Queue: Daisuke Nojiri <dnojiri@google.com>
Original-Tested-by: Daisuke Nojiri <dnojiri@google.com>
Original-Change-Id: Iaddd24006b368c8f37e075cb51e151e985029f3b
Original-Reviewed-on: https://chromium-review.googlesource.com/264417
Reviewed-on: http://review.coreboot.org/9914
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
-rw-r--r-- | Makefile.inc | 2 | ||||
-rw-r--r-- | src/soc/broadcom/cygnus/Makefile.inc | 41 | ||||
-rw-r--r-- | util/broadcom/Makefile.inc | 1 | ||||
-rw-r--r-- | util/broadcom/khmacsha256 | bin | 0 -> 32 bytes | |||
-rw-r--r-- | util/broadcom/secimage/Makefile | 37 | ||||
-rw-r--r-- | util/broadcom/secimage/Makefile.inc | 18 | ||||
-rw-r--r-- | util/broadcom/secimage/crypto.c | 75 | ||||
-rw-r--r-- | util/broadcom/secimage/io.c | 121 | ||||
-rw-r--r-- | util/broadcom/secimage/misc.c | 136 | ||||
-rw-r--r-- | util/broadcom/secimage/sbi.c | 184 | ||||
-rw-r--r-- | util/broadcom/secimage/secimage.h | 46 | ||||
-rw-r--r-- | util/broadcom/unauth.cfg | 20 |
12 files changed, 679 insertions, 2 deletions
diff --git a/Makefile.inc b/Makefile.inc index 985146119f..04e8085978 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -54,7 +54,7 @@ PHONY+= clean-abuild coreboot lint lint-stable build-dirs # root source directories of coreboot subdirs-y := src/lib src/console src/device src/ec src/southbridge src/soc subdirs-y += src/northbridge src/superio src/drivers src/cpu src/vendorcode -subdirs-y += util/cbfstool util/sconfig util/nvramtool +subdirs-y += util/cbfstool util/sconfig util/nvramtool util/broadcom subdirs-y += src/arch/arm src/arch/arm64 src/arch/mips src/arch/riscv subdirs-y += src/arch/x86 subdirs-y += src/mainboard/$(MAINBOARDDIR) diff --git a/src/soc/broadcom/cygnus/Makefile.inc b/src/soc/broadcom/cygnus/Makefile.inc index a1459c0790..dce4e3d0b1 100644 --- a/src/soc/broadcom/cygnus/Makefile.inc +++ b/src/soc/broadcom/cygnus/Makefile.inc @@ -57,6 +57,45 @@ ramstage-$(CONFIG_DRIVERS_UART) += ns16550.c CPPFLAGS_common += -Isrc/soc/broadcom/cygnus/include/ -$(objcbfs)/bootblock.bin: $(objcbfs)/bootblock.elf +$(objcbfs)/bootblock.tmp: $(objcbfs)/bootblock.elf @printf " OBJCOPY $(subst $(obj)/,,$(@))\n" $(OBJCOPY_bootblock) -O binary $< $@ + +ifneq ($(V),1) +redirect := > /dev/null +endif + +# Options used in the command line: +# -out: path of the output file +# -config: path to the file containing unauth header +# -hmac: path to the file containing hmac for sha256 +# -bl: boot image file, ie. input file +# +# Authenticated header parameters: +# +# SBIConfiguration /* Indicates SBI config */ +# SYMMETRIC 0x0040 +# +# CustomerID; /* Customer ID */ +# TYPE bits [31-28] +# PRODUCTION 0x6 +# DEVELOPMENT 0x9 +# CUSTOMER_ID bits [27-0] +# +# ProductID; /* Product ID */ +# +# CustomerRevisionID; /* Customer Revision ID */ +# +# SBIUsage /* Boot Image Usage */ +# NONE 0 /* All purposes */ +# SLEEP 1 +# DEEP_SLEEP 2 +# EXCEPTION 4 +$(objcbfs)/bootblock.bin: $(objcbfs)/bootblock.tmp \ + $(objutil)/broadcom/secimage/secimage \ + util/broadcom/unauth.cfg \ + util/broadcom/khmacsha256 + @printf " SIGN $(subst $(obj)/,,$(@))\n" + $(objutil)/broadcom/secimage/secimage -out $@ \ + -config util/broadcom/unauth.cfg \ + -hmac util/broadcom/khmacsha256 -bl $< diff --git a/util/broadcom/Makefile.inc b/util/broadcom/Makefile.inc new file mode 100644 index 0000000000..eaf51a4549 --- /dev/null +++ b/util/broadcom/Makefile.inc @@ -0,0 +1 @@ +subdirs-$(CONFIG_SOC_BROADCOM_CYGNUS) += secimage
\ No newline at end of file diff --git a/util/broadcom/khmacsha256 b/util/broadcom/khmacsha256 Binary files differnew file mode 100644 index 0000000000..c4911202c1 --- /dev/null +++ b/util/broadcom/khmacsha256 diff --git a/util/broadcom/secimage/Makefile b/util/broadcom/secimage/Makefile new file mode 100644 index 0000000000..8d050fed98 --- /dev/null +++ b/util/broadcom/secimage/Makefile @@ -0,0 +1,37 @@ +# +# Copyright (C) 2015 Broadcom Corporation +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation version 2. +# +# This program is distributed "as is" WITHOUT ANY WARRANTY of any +# kind, whether express or implied; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# + +TARGET = secimage +OBJS = crypto.o io.o misc.o sbi.o +CC = gcc +RM = rm +CFLAGS += -Wall -g + +LIBS = -lgmp -lssl -lcrypto + +%.o : %.c + $(CC) -c $(CFLAGS) -o $@ $< + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CC) -o $@ $(OBJS) $(LIBS) + +install: + install -d $(DESTDIR)/usr/bin + install $(TARGET) $(DESTDIR)/usr/bin + +.PHONY: clean + +clean: + $(RM) -f $(TARGET) $(OBJS) diff --git a/util/broadcom/secimage/Makefile.inc b/util/broadcom/secimage/Makefile.inc new file mode 100644 index 0000000000..6581dd1210 --- /dev/null +++ b/util/broadcom/secimage/Makefile.inc @@ -0,0 +1,18 @@ +secimageobj := +secimageobj += crypto.o +secimageobj += io.o +secimageobj += misc.o +secimageobj += sbi.o + +LIBS = -lgmp -lssl -lcrypto + +additional-dirs += $(objutil)/broadcom/secimage + +$(objutil)/broadcom/secimage/%.o: $(top)/util/broadcom/secimage/%.c + printf " HOSTCC $(subst $(objutil)/,,$(@))\n" + $(HOSTCC) $(HOSTCFLAGS) -c -o $@ $< + +$(objutil)/broadcom/secimage/secimage: \ + $(addprefix $(objutil)/broadcom/secimage/,$(secimageobj)) + printf " HOSTCC $(subst $(objutil)/,,$(@)) (link)\n" + $(HOSTCC) $(LIBS) -o $@ $^ diff --git a/util/broadcom/secimage/crypto.c b/util/broadcom/secimage/crypto.c new file mode 100644 index 0000000000..c1afbc898d --- /dev/null +++ b/util/broadcom/secimage/crypto.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2015 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include "secimage.h" +#include <openssl/hmac.h> + + +/*---------------------------------------------------------------------- + * Name : HmacSha256Hash + * Purpose : + * Input : none + * Output : none + *---------------------------------------------------------------------*/ +int HmacSha256Hash(uint8_t *data, uint32_t len, uint8_t *hash, uint8_t *key) +{ + HMAC_CTX hctx; + + HMAC_CTX_init(&hctx); + HMAC_Init_ex(&hctx, key, 32, EVP_sha256(), NULL); + + /* + * FIXME: why we need this? NULL means to use whatever there is? + * if removed, result is different + */ + HMAC_Init_ex(&hctx, NULL, 0, NULL, NULL); + HMAC_Update(&hctx, data, len); + HMAC_Final(&hctx, hash, NULL); + + HMAC_CTX_cleanup(&hctx); + return 0; +} + + +/*---------------------------------------------------------------------- + * Name : AppendHMACSignature + * Purpose : Appends HMAC signature at the end of the data + *---------------------------------------------------------------------*/ +int AppendHMACSignature(uint8_t *data, uint32_t length, char *filename, + uint32_t offset) +{ + uint8_t hmackey[32]; + uint32_t len; + uint32_t status; + uint8_t *digest = data + length; + + len = ReadBinaryFile(filename, hmackey, 32); + if (len != 32) { + printf("Error reading hmac key file\n"); + return 0; + } + + status = HmacSha256Hash(&data[offset], length - offset, digest, + hmackey); + + if (status) { + printf("HMAC-SHA256 hash error\n"); + return 0; + } + + return 32; +} diff --git a/util/broadcom/secimage/io.c b/util/broadcom/secimage/io.c new file mode 100644 index 0000000000..4d99aad8ea --- /dev/null +++ b/util/broadcom/secimage/io.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2015 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include <stdio.h> +#include <string.h> +#include "secimage.h" + +/*---------------------------------------------------------------------- + * Name : ReadBinaryFile + * Purpose : Read some data from file of raw binary + * Input : fname : file to be read + * buf : buffer which is the data desitnation + * maxlen : maiximum length of data to be read + * Output : none + *---------------------------------------------------------------------*/ +int ReadBinaryFile(char *fname, uint8_t *buf, int maxlen) +{ + FILE *fp = NULL; + int len = 0; + + fp = fopen(fname, "rb"); + if (fp == NULL) + return 0; + printf("fname=%s, len=%d\n", fname, maxlen); + len = fread(buf, 1, maxlen, fp); + fclose(fp); + + return len; +} + + +/*---------------------------------------------------------------------- + * Name : FileSizeGet + * Purpose : Return the size of the file + * Input : file: FILE * to the file to be processed + * Output : none + *---------------------------------------------------------------------*/ +size_t FileSizeGet(FILE *file) +{ + long length; + + fseek(file, 0, SEEK_END); + length = ftell(file); + rewind(file); + return (size_t)length; +} + + +/*---------------------------------------------------------------------- + * Name : DataRead + * Purpose : Read all the data from a file + * Input : filename : file to be read + * buf : buffer which is the data destination + * length : length of data to be read + * Output : none + *---------------------------------------------------------------------*/ +int DataRead(char *filename, uint8_t *buf, int *length) +{ + FILE *file; + int len = *length; + + file = fopen(filename, "rb"); + if (file == NULL) { + printf("Unable to open file: %s\n", filename); + return -1; + } + len = FileSizeGet(file); + if (len < *length) + *length = len; + else + /* Do not exceed the maximum length of the buffer */ + len = *length; + if (fread((uint8_t *)buf, 1, len, file) != len) { + printf("Error reading data (%d bytes) from file: %s\n", + len, filename); + return -1; + } + fclose(file); + return 0; +} + + +/*---------------------------------------------------------------------- + * Name : DataWrite + * Purpose : Write some binary data to a file + * Input : filename : file to be written + * buf : buffer which is the data source + * length : length of data to be written + * Output : none + *---------------------------------------------------------------------*/ +int DataWrite(char *filename, char *buf, int length) +{ + FILE *file; + + file = fopen(filename, "wb"); + if (file == NULL) { + printf("Unable to open output file %s\n", filename); + return -1; + } + if (fwrite(buf, 1, length, file) < length) { + printf("Unable to write %d bytes to output file %s (0x%X).\n", + length, filename, ferror(file)); + fclose(file); + return -1; + } + + fflush(file); + fclose(file); + return 0; +} diff --git a/util/broadcom/secimage/misc.c b/util/broadcom/secimage/misc.c new file mode 100644 index 0000000000..7a93834a42 --- /dev/null +++ b/util/broadcom/secimage/misc.c @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2015 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include <stdio.h> +#include <string.h> +#include "secimage.h" + + +unsigned char filebuffer[2048]; + + +void FillHeaderFromConfigFile(char *h, char *ConfigFileName) +{ + + int byte_count = 0; + char *ptr; + FILE *fp; + unsigned int Tag; + unsigned int Length; + unsigned int Reserved; + HEADER *h1 = (HEADER *)h; + + fp = fopen(ConfigFileName, "rb"); + if (fp != NULL) { + printf("\r\n Reading config information from file \r\n"); + byte_count = fread(filebuffer, 1, 2048, fp); + if (byte_count > 0) { + ptr = strstr((char *)filebuffer, "Tag="); + if (ptr) { + ptr += strlen("Tag="); + sscanf(ptr, "%x", &Tag); + h1->Tag = Tag; + } + ptr = strstr((char *)filebuffer, "Length="); + if (ptr) { + ptr += strlen("Length="); + sscanf(ptr, "%x", &Length); + h1->Length = Length; + } + ptr = strstr((char *)filebuffer, "Reserved="); + if (ptr) { + ptr += strlen("Reserved="); + sscanf(ptr, "%x", &Reserved); + h1->Reserved = Reserved; + } + } + } +} + +const uint32_t ctable[256] = { +0x0, 0x77073096, 0xee0e612c, 0x990951ba, +0x76dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, +0xedb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, +0x9b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, +0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, +0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, +0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, +0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, +0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, +0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, +0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, +0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, +0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, +0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, +0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, +0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, +0x76dc4190, 0x1db7106, 0x98d220bc, 0xefd5102a, +0x71b18589, 0x6b6b51f, 0x9fbfe4a5, 0xe8b8d433, +0x7807c9a2, 0xf00f934, 0x9609a88e, 0xe10e9818, +0x7f6a0dbb, 0x86d3d2d, 0x91646c97, 0xe6635c01, +0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, +0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, +0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, +0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, +0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, +0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, +0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, +0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, +0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, +0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, +0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, +0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, +0xedb88320, 0x9abfb3b6, 0x3b6e20c, 0x74b1d29a, +0xead54739, 0x9dd277af, 0x4db2615, 0x73dc1683, +0xe3630b12, 0x94643b84, 0xd6d6a3e, 0x7a6a5aa8, +0xe40ecf0b, 0x9309ff9d, 0xa00ae27, 0x7d079eb1, +0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, +0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, +0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, +0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, +0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, +0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, +0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, +0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, +0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, +0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, +0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, +0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, +0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x26d930a, +0x9c0906a9, 0xeb0e363f, 0x72076785, 0x5005713, +0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0xcb61b38, +0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0xbdbdf21, +0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, +0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, +0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, +0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, +0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, +0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, +0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, +0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, +0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, +0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, +0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, +0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}; + + +uint32_t calc_crc32(uint32_t initval, uint8_t *charArr, uint32_t arraySize) +{ + uint32_t cval = initval; + int ijk; + for (ijk = 0; ijk < arraySize; ijk++) + cval = (cval >> 8) ^ ctable[(cval & 0xFF) ^ *charArr++]; + + return cval; +} diff --git a/util/broadcom/secimage/sbi.c b/util/broadcom/secimage/sbi.c new file mode 100644 index 0000000000..afc5e2fce1 --- /dev/null +++ b/util/broadcom/secimage/sbi.c @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2015 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include "secimage.h" + +#define MIN_SIZE (1024*120) + +/*---------------------------------------------------------------------- + * Name : SBIUsage + * Purpose : + * Input : none + * Output : none + *---------------------------------------------------------------------*/ +int SBIUsage(void) +{ + printf("\nTo create a Secure Boot Image:\n"); + printf("secimage: -out <output binary> [-hmac hmac_binary_key] <-config configfile>"); + printf("\n\t\t[-bl input binary]\n"); + return 0; +} + +/*---------------------------------------------------------------------- + * Name : AddImagePayload + * Purpose : + * Input : none + * Output : none + *---------------------------------------------------------------------*/ +int AddImagePayload(char *h, char *filename, unsigned int filesize) +{ + uint32_t totalLen; + int length = filesize; + int padlen = 0; + int status = 0; + + totalLen = 0x40; + + status = DataRead(filename, (uint8_t *)h + totalLen, &length); + printf("\r\n Adding file %s ... \r\n", filename); + if (!status) { + if (length & 15) { + padlen = 16 - (length & 15); + memset((uint8_t *)h + totalLen + length, 0, padlen); + length += padlen; + } + + *(uint32_t *)&h[FIELD5_OFFSET] = length; + *(uint32_t *)&h[FIELD6_OFFSET] += length; + + } else + printf("Error reading image Payload from %s\n", filename); + + return status; +} + +/*---------------------------------------------------------------------- + * Name : CreateSecureBootImage + * Purpose : + * Input : none + * Output : none + *---------------------------------------------------------------------*/ +int CreateSecureBootImage(int ac, char **av) +{ + char *outfile, *configfile, *arg, *privkey = NULL, *bl = NULL; + int status = 0; + uint32_t sbiLen; + struct stat file_stat; + uint32_t add_header = 1; + outfile = *av; + unsigned int filesize; + char *buf; + --ac; ++av; + + if (ac <= 0) + return SBIUsage(); + + while (ac) { + arg = *av; + if (!strcmp(arg, "-bl")) { + --ac, ++av; + bl = *av; + } else if (!strcmp(arg, "-hmac")) { + --ac, ++av; + privkey = *av; + } else if (!strcmp(arg, "-config")) { + --ac, ++av; + configfile = *av; + } else if (!strcmp(arg, "-noheader")) { + add_header = 0; + } else { + return SBIUsage(); + } + --ac, ++av; + } + + stat(bl, &file_stat); + filesize = file_stat.st_size + MIN_SIZE; + buf = calloc(sizeof(uint8_t), filesize); + + if (buf == NULL) { + puts("Memory allocation error"); + status = -1; + goto done; + } + + *(uint32_t *)&buf[FIELD6_OFFSET] = 0x40; + *(uint32_t *)&buf[FIELD9_OFFSET] = 0x45F2D99A; + *(uint32_t *)&buf[FIELD3_OFFSET] = 0x900FFFFF; + *(uint16_t *)&buf[FIELD1_OFFSET] = 0x40; + *(uint32_t *)&buf[FIELD4_OFFSET] = 0x40; + *(uint16_t *)&buf[FIELD2_OFFSET] = 0x10; + *(uint16_t *)&buf[FIELD8_OFFSET] = 0x20; + *(uint16_t *)&buf[FIELD7_OFFSET] = 0x10; + + if (status == 0) { + + if (configfile) + FillHeaderFromConfigFile(buf, configfile); + + status = AddImagePayload(buf, bl, filesize); + if (status) { + status = -1; + goto done; + } + + sbiLen = *(uint32_t *)&buf[FIELD6_OFFSET]; + + printf("HMAC signing %d bytes\n", sbiLen); + status = AppendHMACSignature((uint8_t *)buf, sbiLen, privkey, + add_header ? 0x10 : 0x40); + if (status > 0) { + sbiLen += status; + status = 0; + } + + if (!status) { + ((HEADER *)buf)->Length = sbiLen; + ((HEADER *)buf)->crc = calc_crc32(0xFFFFFFFF, + (uint8_t *)buf, 12); + + printf("Generating Image file %s: %d bytes\n", + outfile, sbiLen); + if (!add_header) + status = DataWrite(outfile, &buf[0x40], + sbiLen - 0x40); + else + status = DataWrite(outfile, buf, sbiLen); + } + } + if (status < 0) + printf("Generation error %d\n", status); + +done: + free(buf); + return status; +} + +int main(int argc, char **argv) +{ + argc--; + argv++; + if (argc > 0) { + if (!strcmp(*argv, "-out")) + return CreateSecureBootImage(--argc, ++argv); + } + SBIUsage(); + return 0; +} diff --git a/util/broadcom/secimage/secimage.h b/util/broadcom/secimage/secimage.h new file mode 100644 index 0000000000..eff0b8fbdd --- /dev/null +++ b/util/broadcom/secimage/secimage.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2015 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#ifndef _SECIMAGE_H_ +#define _SECIMAGE_H_ + +#include <stdint.h> +#include <sys/types.h> + +#define FIELD1_OFFSET 16 +#define FIELD2_OFFSET 18 +#define FIELD3_OFFSET 20 +#define FIELD4_OFFSET 36 +#define FIELD5_OFFSET 40 +#define FIELD6_OFFSET 44 +#define FIELD7_OFFSET 48 +#define FIELD8_OFFSET 50 +#define FIELD9_OFFSET 60 + +typedef struct Header_t { + uint32_t Tag; + uint32_t Length; + uint32_t Reserved; + uint32_t crc; +} HEADER; + +int DataWrite(char *filename, char *buf, int length); +int DataRead(char *filename, uint8_t *buf, int *length); +int AppendHMACSignature(uint8_t *data, uint32_t length, char *filename, + uint32_t offset); +int ReadBinaryFile(char *fname, uint8_t *buf, int maxlen); +uint32_t calc_crc32(uint32_t initval, uint8_t *charArr, uint32_t arraySize); +void FillHeaderFromConfigFile(char *h, char *ConfigFileName); + +#endif /* _SECIMAGE_H_ */ diff --git a/util/broadcom/unauth.cfg b/util/broadcom/unauth.cfg new file mode 100644 index 0000000000..fd81a9cc71 --- /dev/null +++ b/util/broadcom/unauth.cfg @@ -0,0 +1,20 @@ +// Unauth Header +// +// struct UnAuthenticatedHeader_t { +// uint32_t Tag; /* Tag used to locate boot binary in memory */ +// uint32_t Length; /* Length of the boot binary */ +// uint32_t Reserved; /* Address for the non-authenticated boot. +// The address is aligned to 16 bytes boundary. +// The lower 4 bits are used for ClkConfig: +// Value Freq +// 1 400 +// 2 1GHz +// 3 Max (1.2GHz) +// 4 no PLL lock: 200MHz +// */ +// uint32_t crc; /* CRC computed on all other fields in this +// structure excluding crc field */ +// }; +Tag= 0xA5A5A5A5 +Length= 0x00000000 +Reserved= 0x00000002 |