summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--Makefile.rules19
-rw-r--r--Makefile.toolchain3
-rw-r--r--board/bds/build.mk1
-rw-r--r--board/daisy/build.mk1
-rw-r--r--board/link/build.mk1
-rw-r--r--board/snow/build.mk1
-rw-r--r--chip/lm4/build.mk1
-rw-r--r--chip/stm32/build.mk1
-rw-r--r--common/build.mk31
-rw-r--r--common/fmap.c1
-rw-r--r--common/uart_buffering.c5
-rw-r--r--common/vboot.c147
-rw-r--r--common/vboot_stub.c168
-rw-r--r--core/cortex-m/build.mk1
-rw-r--r--include/util.h8
-rw-r--r--test/build.mk4
-rw-r--r--util/build.mk1
18 files changed, 375 insertions, 22 deletions
diff --git a/Makefile b/Makefile
index 998009a3cd..ee86da1881 100644
--- a/Makefile
+++ b/Makefile
@@ -38,6 +38,8 @@ include common/build.mk
include test/build.mk
include util/build.mk
+includes+=$(includes-y)
+
objs_from_dir=$(foreach obj,$(2), $(out)/$(1)/$(obj))
# Get all sources to build
@@ -47,6 +49,7 @@ all-y+=$(call objs_from_dir,board/$(BOARD),$(board-y))
all-y+=$(call objs_from_dir,private,$(private-y))
all-y+=$(call objs_from_dir,common,$(common-y))
all-y+=$(call objs_from_dir,test,$($(PROJECT)-y))
+all-y+=$(call objs_from_dir,vboot,$(vboot-y))
dirs=core/$(CORE) chip/$(CHIP) board/$(BOARD) private common test util
include Makefile.rules
diff --git a/Makefile.rules b/Makefile.rules
index ea7a961777..5a94984813 100644
--- a/Makefile.rules
+++ b/Makefile.rules
@@ -1,3 +1,4 @@
+# -*- makefile -*-
# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -13,6 +14,8 @@ host-utils := $(foreach u,$(host-util-bin),$(out)/util/$(u))
# Create output directories if necessary
_dir_create := $(foreach d,$(dirs),$(shell [ -d $(out)/$(d) ] || \
mkdir -p $(out)/$(d)))
+_dir_y_create := $(foreach d,$(dirs-y),$(shell [ -d $(out)/$(d) ] || \
+ mkdir -p $(out)/$(d)))
section = $(subst .,,$(suffix $(1)))
section_is = $(subst .,,SECTION_IS_$(suffix $(1)))
@@ -38,6 +41,13 @@ cmd_c_to_host = $(HOSTCC) $(HOST_CFLAGS) -MMD -MF $@.d $< -o $@
cmd_qemu = ./util/run_qemu_test --image=build/$(BOARD)/$*/$*.bin test/$*.py \
$(silent)
cmd_version = ./util/getversion.sh > $@
+cmd_sign = vbutil_ec --sign $@ \
+ --version 1 \
+ --keyblock $(VBOOT_DEVKEYS)/ec.keyblock \
+ --signprivate $(VBOOT_DEVKEYS)/ec_data_key.vbprivk \
+ --signpubkey $(VBOOT_DEVKEYS)/ec_root_key.vbpubk \
+ $(silent)
+cmd_mv = mv $^ $@
.PHONY: all tests utils
@@ -66,8 +76,12 @@ $(out)/firmware_image.lds: common/firmware_image.lds.S
$(out)/%.lds: core/$(CORE)/ec.lds.S
$(call quiet,lds,LDS )
-$(out)/%.bin: $(out)/%.obj
+$(out)/%.bin: $(out)/%.bin.tmp
+ $(call quiet,mv,MV )
+
+$(out)/%.bin.tmp: $(out)/%.obj
$(call quiet,obj_to_bin,OBJCOPY)
+ $(if $(sign-y),$(call quiet,sign,SIGN ),)
$(out)/%.obj: common/firmware_image.S $(out)/firmware_image.lds \
$(out)/%.RO.flat $(out)/%.A.flat $(out)/%.B.flat
@@ -85,6 +99,9 @@ $(out)/%.elf: $(out)/%.lds $(objs)
$(out)/%.o:%.c
$(call quiet,c_to_o,CC )
+$(out)/vboot/%.o:$(VBOOT_SOURCE)/%.c
+ $(call quiet,c_to_o,CC )
+
$(out)/%.o:%.S
$(call quiet,c_to_o,AS )
diff --git a/Makefile.toolchain b/Makefile.toolchain
index 1b55247ff5..537d9a2b82 100644
--- a/Makefile.toolchain
+++ b/Makefile.toolchain
@@ -1,3 +1,4 @@
+# -*- makefile -*-
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -28,7 +29,7 @@ CFLAGS_DEFINE=-DOUTDIR=$(out) -DCHIP=$(CHIP) -DTASKFILE=$(PROJECT).tasklist \
-DBOARD=$(BOARD) -DBOARD_$(BOARD) -DCORE=$(CORE) -DCHIP_$(CHIP) \
-DCHIP_VARIANT=$(CHIP_VARIANT) -DCHIP_VARIANT_$(CHIP_VARIANT)
CPPFLAGS=$(CFLAGS_DEFINE) $(CFLAGS_INCLUDE)
-CFLAGS=$(CPPFLAGS) $(CFLAGS_CPU) $(CFLAGS_DEBUG) $(CFLAGS_WARN)
+CFLAGS=$(CPPFLAGS) $(CFLAGS_CPU) $(CFLAGS_DEBUG) $(CFLAGS_WARN) $(CFLAGS_y)
BUILD_CFLAGS=$(CPPFLAGS) -O3 $(CFLAGS_DEBUG) $(CFLAGS_WARN)
HOST_CFLAGS=$(CPPFLAGS) -O3 $(CFLAGS_DEBUG) $(CFLAGS_WARN)
LDFLAGS=-nostdlib -X
diff --git a/board/bds/build.mk b/board/bds/build.mk
index b8e0572b53..d53bdde96c 100644
--- a/board/bds/build.mk
+++ b/board/bds/build.mk
@@ -1,3 +1,4 @@
+# -*- makefile -*-
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
diff --git a/board/daisy/build.mk b/board/daisy/build.mk
index b09b1c7f4b..3fd1e94556 100644
--- a/board/daisy/build.mk
+++ b/board/daisy/build.mk
@@ -1,3 +1,4 @@
+# -*- makefile -*-
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
diff --git a/board/link/build.mk b/board/link/build.mk
index 7ddc9b4f32..e22d4573f7 100644
--- a/board/link/build.mk
+++ b/board/link/build.mk
@@ -1,3 +1,4 @@
+# -*- makefile -*-
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
diff --git a/board/snow/build.mk b/board/snow/build.mk
index 4732080d23..53d994e236 100644
--- a/board/snow/build.mk
+++ b/board/snow/build.mk
@@ -1,3 +1,4 @@
+# -*- makefile -*-
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
diff --git a/chip/lm4/build.mk b/chip/lm4/build.mk
index 56bf793582..b93cc7816e 100644
--- a/chip/lm4/build.mk
+++ b/chip/lm4/build.mk
@@ -1,3 +1,4 @@
+# -*- makefile -*-
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
diff --git a/chip/stm32/build.mk b/chip/stm32/build.mk
index 4d296f186e..03877cf6fe 100644
--- a/chip/stm32/build.mk
+++ b/chip/stm32/build.mk
@@ -1,3 +1,4 @@
+# -*- makefile -*-
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
diff --git a/common/build.mk b/common/build.mk
index 8c81d9866b..b5ecfa5a04 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -1,3 +1,4 @@
+# -*- makefile -*-
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -27,4 +28,32 @@ common-$(CONFIG_TASK_THERMAL)+=thermal.o thermal_commands.o
common-$(CONFIG_TASK_X86POWER)+=x86_power.o
common-$(CONFIG_TMP006)+=tmp006.o
common-$(CONFIG_USB_CHARGE)+=usb_charge.o usb_charge_commands.o
-common-$(CONFIG_VBOOT)+=vboot.o fmap.o
+
+# verified boot stuff
+VBOOT_SOURCE?=/usr/src/vboot
+VBOOT_DEVKEYS?=/usr/share/vboot/devkeys
+
+CFLAGS_$(CONFIG_VBOOT)+= -DCHROMEOS_ENVIRONMENT -DCHROMEOS_EC
+# CFLAGS_$(CONFIG_VBOOT)+= -DVBOOT_DEBUG
+
+common-$(CONFIG_VBOOT)+= fmap.o vboot.o vboot_stub.o
+
+includes-$(CONFIG_VBOOT)+= \
+ $(VBOOT_SOURCE)/include \
+ $(VBOOT_SOURCE)/lib/include \
+ $(VBOOT_SOURCE)/lib/cryptolib/include
+
+dirs-$(CONFIG_VBOOT)+= \
+ vboot/lib vboot/lib/cryptolib
+
+vboot-$(CONFIG_VBOOT)+= \
+ lib/vboot_common.o \
+ lib/utility.o \
+ lib/cryptolib/padding.o \
+ lib/cryptolib/rsa_utility.o \
+ lib/cryptolib/rsa.o \
+ lib/cryptolib/sha_utility.o \
+ lib/cryptolib/sha256.o \
+ lib/stateful_util.o
+
+sign-$(CONFIG_VBOOT)+=sign_image
diff --git a/common/fmap.c b/common/fmap.c
index 3f7baceb93..40524c21ef 100644
--- a/common/fmap.c
+++ b/common/fmap.c
@@ -83,7 +83,6 @@ const struct _ec_fmap {
.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
},
{
- /* FIXME(wfrichar): GBB != FMAP. Use the right terms */
.area_name = "FMAP",
.area_offset = (uint32_t)&ec_fmap,
.area_size = sizeof(ec_fmap),
diff --git a/common/uart_buffering.c b/common/uart_buffering.c
index d83b34ea40..5848a30f1d 100644
--- a/common/uart_buffering.c
+++ b/common/uart_buffering.c
@@ -549,6 +549,11 @@ int uart_printf(const char *format, ...)
va_end(args);
return rv;
}
+/* For use when debugging verified boot. We could wrap it with a real function,
+ * but it's rarely needed and this doesn't add any extra code. We have to
+ * declare it here in order for this trick to work. */
+void VbExDebug(const char *format, ...)
+ __attribute__((weak, alias("uart_printf")));
void uart_flush_output(void)
diff --git a/common/vboot.c b/common/vboot.c
index 80750faa7f..31baad9d82 100644
--- a/common/vboot.c
+++ b/common/vboot.c
@@ -6,16 +6,84 @@
/* Verified boot module for Chrome EC */
#include "console.h"
+#include "cryptolib.h"
#include "gpio.h"
#include "keyboard_scan.h"
#include "system.h"
+#include "timer.h"
#include "util.h"
#include "vboot.h"
+#include "vboot_api.h"
+#include "vboot_common.h"
+#include "vboot_struct.h"
+#include "watchdog.h"
/* Console output macros */
#define CPUTS(outstr) cputs(CC_VBOOT, outstr)
#define CPRINTF(format, args...) cprintf(CC_VBOOT, format, ## args)
+/****************************************************************************/
+
+enum howgood {
+ IMAGE_IS_BAD,
+ IMAGE_IS_GOOD,
+ IMAGE_IS_GOOD_BUT_USE_RO_ANYWAY,
+};
+
+static enum howgood good_image(uint8_t *key_data,
+ uint8_t *vblock_data, uint32_t vblock_size,
+ uint8_t *fv_data, uint32_t fv_size) {
+ VbPublicKey *sign_key;
+ VbKeyBlockHeader *key_block;
+ VbECPreambleHeader *preamble;
+ uint32_t now = 0;
+ RSAPublicKey *rsa;
+
+ key_block = (VbKeyBlockHeader *)vblock_data;
+ sign_key = (VbPublicKey *)key_data;
+
+ watchdog_reload();
+ if (0 != KeyBlockVerify(key_block, vblock_size, sign_key, 0)) {
+ CPRINTF("[Error verifying key block]\n");
+ return IMAGE_IS_BAD;
+ }
+
+ now += key_block->key_block_size;
+ rsa = PublicKeyToRSA(&key_block->data_key);
+ if (!rsa) {
+ CPRINTF("[Error parsing data key]\n");
+ return IMAGE_IS_BAD;
+ }
+
+ watchdog_reload();
+ preamble = (VbECPreambleHeader *)(vblock_data + now);
+ if (0 != VerifyECPreamble(preamble, vblock_size - now, rsa)) {
+ CPRINTF("[Error verifying preamble]\n");
+ RSAPublicKeyFree(rsa);
+ return IMAGE_IS_BAD;
+ }
+
+ if (preamble->flags & VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL) {
+ CPRINTF("[Flags says USE_RO_NORMAL]\n");
+ RSAPublicKeyFree(rsa);
+ return IMAGE_IS_GOOD_BUT_USE_RO_ANYWAY;
+ }
+
+ watchdog_reload();
+ if (0 != EqualData(fv_data, fv_size, &preamble->body_digest, rsa)) {
+ CPRINTF("Error verifying firmware body]\n");
+ RSAPublicKeyFree(rsa);
+ return IMAGE_IS_BAD;
+ }
+
+ RSAPublicKeyFree(rsa);
+
+ watchdog_reload();
+ CPRINTF("[Verified!]\n");
+ return IMAGE_IS_GOOD;
+}
+
+/****************************************************************************/
/* Might I want to jump to one of the RW images? */
static int maybe_jump_to_other_image(void)
@@ -68,27 +136,70 @@ int vboot_pre_init(void)
return EC_SUCCESS;
}
-
int vboot_init(void)
{
- /* nothing to do, so do nothing */
+ enum howgood r;
+ timestamp_t ts1, ts2;
+
+ CPRINTF("\n[--- %s() ---]\n", __func__);
+
if (!maybe_jump_to_other_image())
return EC_SUCCESS;
- /* FIXME(wfrichar): placeholder for full verified boot implementation.
- * TBD exactly how, but we may want to continue in RO firmware, jump
- * directly to one of the RW firmwares, etc. */
- CPRINTF("[ROOT_KEY is at 0x%x, size 0x%x]\n",
- CONFIG_VBOOT_ROOTKEY_OFF, CONFIG_VBOOT_ROOTKEY_SIZE);
- CPRINTF("[FW_MAIN_A is at 0x%x, size 0x%x]\n",
- CONFIG_FW_A_OFF, CONFIG_FW_A_SIZE);
- CPRINTF("[VBLOCK_A is at 0x%x, size 0x%x]\n",
- CONFIG_VBLOCK_A_OFF, CONFIG_VBLOCK_A_SIZE);
- CPRINTF("[FW_MAIN_B is at 0x%x, size 0x%x]\n",
- CONFIG_FW_B_OFF, CONFIG_FW_B_SIZE);
- CPRINTF("[VBLOCK_B is at 0x%x, size 0x%x]\n",
- CONFIG_VBLOCK_B_OFF, CONFIG_VBLOCK_B_SIZE);
-
- system_run_image_copy(SYSTEM_IMAGE_RW_A, 0);
- return EC_SUCCESS;
+ CPRINTF("[Check image A...]\n");
+
+ ts1 = get_time();
+ r = good_image((uint8_t *)CONFIG_VBOOT_ROOTKEY_OFF,
+ (uint8_t *)CONFIG_VBLOCK_A_OFF, CONFIG_VBLOCK_A_SIZE,
+ (uint8_t *)CONFIG_FW_A_OFF, CONFIG_FW_A_SIZE);
+ ts2 = get_time();
+
+ CPRINTF("[result=%d, elapsed time=%ld]\n", r, ts2.val - ts1.val);
+
+ switch (r) {
+ case IMAGE_IS_GOOD:
+ CPRINTF("[Image A verified at %T]\n");
+ system_run_image_copy(SYSTEM_IMAGE_RW_A, 0);
+ CPRINTF("[ERROR: Unable to jump to image A]\n");
+ goto bad;
+ case IMAGE_IS_GOOD_BUT_USE_RO_ANYWAY:
+ CPRINTF("[Image A verified at %T]\n");
+ CPRINTF("[Staying in RO mode]\n");
+ return EC_SUCCESS;
+ default:
+ CPRINTF("[Image A is invalid]\n");
+ }
+
+#ifdef CONFIG_NO_RW_B
+ CPRINTF("[No image B to check]\n");
+#else
+ CPRINTF("[Check image B...]\n");
+
+ ts1 = get_time();
+ r = good_image((uint8_t *)CONFIG_VBOOT_ROOTKEY_OFF,
+ (uint8_t *)CONFIG_VBLOCK_B_OFF, CONFIG_VBLOCK_B_SIZE,
+ (uint8_t *)CONFIG_FW_B_OFF, CONFIG_FW_B_SIZE);
+ ts2 = get_time();
+
+ CPRINTF("[result=%d, elapsed time=%ld]\n", r, ts2.val - ts1.val);
+
+ switch (r) {
+ case IMAGE_IS_GOOD:
+ CPRINTF("[Image B verified at %T]\n");
+ system_run_image_copy(SYSTEM_IMAGE_RW_B, 0);
+ CPRINTF("[ERROR: Unable to jump to image B]\n");
+ goto bad;
+ case IMAGE_IS_GOOD_BUT_USE_RO_ANYWAY:
+ CPRINTF("[Image B verified at %T]\n");
+ CPRINTF("[Staying in RO mode]\n");
+ return EC_SUCCESS;
+ default:
+ CPRINTF("[Image B is invalid]\n");
+ }
+#endif
+
+bad:
+ CPRINTF("[Staying in RO mode]\n");
+ CPRINTF("[FIXME: How to trigger recovery mode?]\n");
+ return EC_ERROR_UNKNOWN;
}
diff --git a/common/vboot_stub.c b/common/vboot_stub.c
new file mode 100644
index 0000000000..b9b6bed691
--- /dev/null
+++ b/common/vboot_stub.c
@@ -0,0 +1,168 @@
+/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Functions needed by vboot library */
+
+#define _STUB_IMPLEMENTATION_
+#include "console.h"
+#include "shared_mem.h"
+#include "util.h"
+#include "utility.h"
+
+/* Console output macros */
+#define CPUTS(outstr) cputs(CC_VBOOT, outstr)
+#define CPRINTF(format, args...) cprintf(CC_VBOOT, format, ## args)
+
+#if 0 /* change this to debug memory usage */
+#define DPRINTF CPRINTF
+#else
+#define DPRINTF(...)
+#endif
+
+
+/****************************************************************************/
+
+void *Memcpy(void *dest, const void *src, uint64_t n)
+{
+ return memcpy(dest, src, (size_t)n);
+}
+
+void *Memset(void *d, const uint8_t c, uint64_t n)
+{
+ return memset(d, c, n);
+}
+
+int Memcmp(const void *src1, const void *src2, size_t n)
+{
+ size_t i;
+ const uint8_t *a = src1;
+ const uint8_t *b = src2;
+ for (i = 0; i < n; i++) {
+ if (*a != *b)
+ return (*a < *b) ? -1 : 1;
+ a++;
+ b++;
+ }
+
+ return 0;
+}
+
+/****************************************************************************/
+/* The vboot_api library requires some dynamic memory, but we don't have
+ * malloc/free. Instead we have one chunk of shared RAM that we can gain
+ * exclusive access to for a time. We'll have to experiment with various
+ * algorithms to see what works best. This algorithm allocates and
+ * reuses blocks, but never actually frees anything until all memory has been
+ * reclaimed. */
+
+/* Since we only need this stuff to boot, don't waste run-time .bss */
+static struct {
+ int bucket_size; /* total RAM available */
+ uint8_t *out_base; /* malloc from here */
+ int out_count; /* number of active mallocs */
+ int out_size; /* high-water mark */
+
+ /* We have a limited number of active mallocs. We never free, but we
+ * do reuse slots. */
+#define MAX_SLOTS 8
+ struct {
+ int in_use; /* is this slot active? */
+ void *ptr; /* starts here */
+ size_t size; /* how big */
+ } slots[MAX_SLOTS];
+} *bucket;
+
+
+void *VbExMalloc(size_t size)
+{
+ int i, j;
+ void *ptr = 0;
+
+ if (!bucket) {
+ i = shared_mem_size();
+ if (EC_SUCCESS != shared_mem_acquire(i, 1, (char **)&bucket)) {
+ CPRINTF("FAILED at %s:%d\n", __FILE__, __LINE__);
+ ASSERT(0);
+ }
+ Memset(bucket, 0, sizeof(*bucket));
+ bucket->bucket_size = i;
+ bucket->out_base = (uint8_t *)(bucket + 1);
+ bucket->out_size = sizeof(*bucket);
+ DPRINTF("grab the bucket: at 0x%x, size 0x%x\n",
+ bucket, bucket->bucket_size);
+ }
+
+ if (size % 8) {
+ int tmp = (size + 8) & ~0x7ULL;
+ DPRINTF(" %d -> %d\n", size, tmp);
+ size = tmp;
+ }
+
+ for (i = 0; i < MAX_SLOTS; i++) {
+ if (!bucket->slots[i].in_use) {
+
+ /* Found an empty one, but reuse the same size if one
+ * already exists. */
+ for (j = i; j < MAX_SLOTS; j++) {
+ if (!bucket->slots[j].in_use &&
+ size == bucket->slots[j].size) {
+ /* empty AND same size */
+ bucket->slots[j].in_use = 1;
+ ptr = bucket->slots[j].ptr;
+ DPRINTF(" = %d (%d)\n", j, size);
+ goto out;
+ }
+ }
+
+ /* no exact matches, must allocate a new chunk */
+ ptr = bucket->out_base + bucket->out_size;
+ bucket->out_size += size;
+
+ bucket->slots[i].in_use = 1;
+ bucket->slots[i].ptr = ptr;
+ bucket->slots[i].size = size;
+ DPRINTF(" + %d (%d)\n", i, size);
+ goto out;
+ }
+ }
+
+ CPRINTF("FAILED: no empty slots (%d/%d)\n", i, MAX_SLOTS);
+ ASSERT(0);
+
+out:
+ bucket->out_count++;
+ if (bucket->out_size >= bucket->bucket_size) {
+ CPRINTF("FAILED: out of memory (%d/%d)\n",
+ bucket->out_size, bucket->bucket_size);
+ ASSERT(0);
+ }
+
+ return ptr;
+}
+
+
+void VbExFree(void *ptr)
+{
+ int i;
+
+ for (i = 0; i < MAX_SLOTS; i++) {
+ if (ptr == bucket->slots[i].ptr) {
+ bucket->slots[i].in_use = 0;
+ DPRINTF(" - %d (%d)\n", i, bucket->slots[i].size);
+ break;
+ }
+ }
+ if (MAX_SLOTS == i) {
+ CPRINTF("FAILED: can't find ptr %x!\n", ptr);
+ ASSERT(0);
+ }
+
+ bucket->out_count--;
+ if (!bucket->out_count) {
+ DPRINTF("dump the bucket: max used = %d\n", bucket->out_size);
+ shared_mem_release(bucket);
+ bucket = 0;
+ }
+}
diff --git a/core/cortex-m/build.mk b/core/cortex-m/build.mk
index 8f6225db76..5abd25ba08 100644
--- a/core/cortex-m/build.mk
+++ b/core/cortex-m/build.mk
@@ -1,3 +1,4 @@
+# -*- makefile -*-
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
diff --git a/include/util.h b/include/util.h
index 6f8fe1c581..3fb0657061 100644
--- a/include/util.h
+++ b/include/util.h
@@ -32,10 +32,18 @@
/* Standard macros / definitions */
+#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
+#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+#ifndef NULL
#define NULL ((void *)0)
+#endif
/**
* macros for integer division with various rounding variants
diff --git a/test/build.mk b/test/build.mk
index 7bc5731ac9..5cbbfbcd21 100644
--- a/test/build.mk
+++ b/test/build.mk
@@ -1,3 +1,7 @@
+# -*- makefile -*-
+# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
#
# on-board test binaries build
#
diff --git a/util/build.mk b/util/build.mk
index e8a930ed78..a3aa636b06 100644
--- a/util/build.mk
+++ b/util/build.mk
@@ -1,3 +1,4 @@
+# -*- makefile -*-
# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.