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>
This commit is contained in:
parent
cb6bb3bc47
commit
e1741c512c
|
@ -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)
|
||||
|
|
|
@ -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 $<
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
subdirs-$(CONFIG_SOC_BROADCOM_CYGNUS) += secimage
|
Binary file not shown.
|
@ -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)
|
|
@ -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 $@ $^
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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_ */
|
|
@ -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
|
Loading…
Reference in New Issue