summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2015-02-09 18:15:17 -0800
committerPatrick Georgi <pgeorgi@google.com>2015-04-22 08:59:18 +0200
commite1741c512c66c468f3c3399aff451ae428cd6824 (patch)
tree07e1d8aff86068e2f2f86b753713bec4ad8b2549
parentcb6bb3bc47bf55e47bdc60c53c5f40617c6a8d9b (diff)
downloadcoreboot-e1741c512c66c468f3c3399aff451ae428cd6824.tar.xz
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.inc2
-rw-r--r--src/soc/broadcom/cygnus/Makefile.inc41
-rw-r--r--util/broadcom/Makefile.inc1
-rw-r--r--util/broadcom/khmacsha256bin0 -> 32 bytes
-rw-r--r--util/broadcom/secimage/Makefile37
-rw-r--r--util/broadcom/secimage/Makefile.inc18
-rw-r--r--util/broadcom/secimage/crypto.c75
-rw-r--r--util/broadcom/secimage/io.c121
-rw-r--r--util/broadcom/secimage/misc.c136
-rw-r--r--util/broadcom/secimage/sbi.c184
-rw-r--r--util/broadcom/secimage/secimage.h46
-rw-r--r--util/broadcom/unauth.cfg20
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
new file mode 100644
index 0000000000..c4911202c1
--- /dev/null
+++ b/util/broadcom/khmacsha256
Binary files differ
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