[coreboot-gerrit] New patch to review for coreboot: dd327fe broadcom/cygnus: add secimage and sign bootblock

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Tue Apr 21 15:19:11 CEST 2015


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9914

-gerrit

commit dd327fe6adf81aaaca86224b5683e53cf732106d
Author: Daisuke Nojiri <dnojiri at chromium.org>
Date:   Mon Feb 9 18:15:17 2015 -0800

    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 at chromium.org>
    Original-Commit-Id: 36284d1b242c26b0b5aac2894f7ed1790da1ef15
    Original-Signed-off-by: Daisuke Nojiri <dnojiri at chromium.org>
    Original-Reviewed-on: https://chrome-internal-review.googlesource.com/197155
    Original-Reviewed-by: Scott Branden <sbranden at broadcom.com>
    Original-Reviewed-by: Julius Werner <jwerner at chromium.org>
    Original-Commit-Queue: Daisuke Nojiri <dnojiri at google.com>
    Original-Tested-by: Daisuke Nojiri <dnojiri at google.com>
    Original-Change-Id: Iaddd24006b368c8f37e075cb51e151e985029f3b
    Original-Reviewed-on: https://chromium-review.googlesource.com/264417
---
 Makefile.inc                         |   2 +-
 src/soc/broadcom/cygnus/Makefile.inc |  41 +++++++-
 util/broadcom/Makefile.inc           |   1 +
 util/broadcom/khmacsha256            | Bin 0 -> 32 bytes
 util/broadcom/secimage/Makefile      |  37 +++++++
 util/broadcom/secimage/Makefile.inc  |  18 ++++
 util/broadcom/secimage/crypto.c      |  75 ++++++++++++++
 util/broadcom/secimage/io.c          | 121 +++++++++++++++++++++++
 util/broadcom/secimage/misc.c        | 136 ++++++++++++++++++++++++++
 util/broadcom/secimage/sbi.c         | 184 +++++++++++++++++++++++++++++++++++
 util/broadcom/secimage/secimage.h    |  46 +++++++++
 util/broadcom/unauth.cfg             |  20 ++++
 12 files changed, 679 insertions(+), 2 deletions(-)

diff --git a/Makefile.inc b/Makefile.inc
index 9851461..04e8085 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 a1459c0..dce4e3d 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 0000000..eaf51a4
--- /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 0000000..c491120
Binary files /dev/null and b/util/broadcom/khmacsha256 differ
diff --git a/util/broadcom/secimage/Makefile b/util/broadcom/secimage/Makefile
new file mode 100644
index 0000000..8d050fe
--- /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 0000000..6581dd1
--- /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 0000000..c1afbc8
--- /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 0000000..4d99aad
--- /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 0000000..7a93834
--- /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 0000000..afc5e2f
--- /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 0000000..eff0b8f
--- /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 0000000..fd81a9c
--- /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



More information about the coreboot-gerrit mailing list