diff options
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | firmware/2lib/include/2return_codes.h | 33 | ||||
-rw-r--r-- | host/lib/host_misc.c | 1 | ||||
-rw-r--r-- | host/lib/host_misc2.c | 84 | ||||
-rw-r--r-- | host/lib/include/host_misc.h | 41 | ||||
-rw-r--r-- | tests/vb2_convert_structs.c | 2 | ||||
-rw-r--r-- | tests/vb2_convert_structs.h | 8 | ||||
-rw-r--r-- | tests/vb2_host_misc_tests.c | 71 |
8 files changed, 238 insertions, 10 deletions
@@ -374,6 +374,12 @@ UTILLIB_SRCS = \ host/lib/host_signature.c \ host/lib/signature_digest.c +ifneq (${VBOOT2},) +UTILLIB_SRCS += \ + host/lib/host_misc2.c \ + +endif + UTILLIB_OBJS = ${UTILLIB_SRCS:%.c=${BUILD}/%.o} ALL_OBJS += ${UTILLIB_OBJS} @@ -626,6 +632,7 @@ TEST_NAMES += \ tests/vb2_common_tests \ tests/vb2_common2_tests \ tests/vb2_common3_tests \ + tests/vb2_host_misc_tests \ tests/vb2_misc_tests \ tests/vb2_misc2_tests \ tests/vb2_misc3_tests \ @@ -1160,6 +1167,7 @@ run2tests: test_setup ${RUNTEST} ${BUILD_RUN}/tests/vb2_common_tests ${RUNTEST} ${BUILD_RUN}/tests/vb2_common2_tests ${TEST_KEYS} ${RUNTEST} ${BUILD_RUN}/tests/vb2_common3_tests ${TEST_KEYS} + ${RUNTEST} ${BUILD_RUN}/tests/vb2_host_misc_tests ${RUNTEST} ${BUILD_RUN}/tests/vb2_misc_tests ${RUNTEST} ${BUILD_RUN}/tests/vb2_misc2_tests ${RUNTEST} ${BUILD_RUN}/tests/vb2_misc3_tests diff --git a/firmware/2lib/include/2return_codes.h b/firmware/2lib/include/2return_codes.h index fa7437e0..69a9494f 100644 --- a/firmware/2lib/include/2return_codes.h +++ b/firmware/2lib/include/2return_codes.h @@ -20,7 +20,7 @@ enum vb2_return_code { * All vboot2 error codes start at a large offset from zero, to reduce * the risk of overlap with other error codes (TPM, etc.). */ - VB2_ERROR_BASE = 0x0100000, + VB2_ERROR_BASE = 0x10000000, /* Unknown / unspecified error */ VB2_ERROR_UNKNOWN = VB2_ERROR_BASE + 1, @@ -443,12 +443,41 @@ enum vb2_return_code { /* TPM clear owner not implemented */ VB2_ERROR_EX_TPM_CLEAR_OWNER_UNIMPLEMENTED, + + /********************************************************************** + * Errors generated by host library (non-firmware) start here. + */ + VB2_ERROR_HOST_BASE = 0x20000000, + + /********************************************************************** + * Errors generated by host library misc functions + */ + VB2_ERROR_HOST_MISC = VB2_ERROR_HOST_BASE + 0x010000, + + /* Unable to open file in read_file() */ + VB2_ERROR_READ_FILE_OPEN, + + /* Bad size in read_file() */ + VB2_ERROR_READ_FILE_SIZE, + + /* Unable to allocate buffer in read_file() */ + VB2_ERROR_READ_FILE_ALLOC, + + /* Unable to read data in read_file() */ + VB2_ERROR_READ_FILE_DATA, + + /* Unable to open file in write_file() */ + VB2_ERROR_WRITE_FILE_OPEN, + + /* Unable to write data in write_file() */ + VB2_ERROR_WRITE_FILE_DATA, + /********************************************************************** * Highest non-zero error generated inside vboot library. Note that * error codes passed through vboot when it calls external APIs may * still be outside this range. */ - VB2_ERROR_MAX = VB2_ERROR_BASE + 0xffffff, + VB2_ERROR_MAX = VB2_ERROR_BASE + 0x1fffffff, }; #endif /* VBOOT_2_RETURN_CODES_H_ */ diff --git a/host/lib/host_misc.c b/host/lib/host_misc.c index adc39420..3fb9b24e 100644 --- a/host/lib/host_misc.c +++ b/host/lib/host_misc.c @@ -108,6 +108,7 @@ int WriteFile(const char* filename, const void *data, uint64_t size) { VBDEBUG(("Unable to write to file %s\n", filename)); fclose(f); unlink(filename); /* Delete any partial file */ + return 1; } fclose(f); diff --git a/host/lib/host_misc2.c b/host/lib/host_misc2.c new file mode 100644 index 00000000..88b58f5b --- /dev/null +++ b/host/lib/host_misc2.c @@ -0,0 +1,84 @@ +/* Copyright (c) 2014 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. + * + * Host functions for verified boot. + */ + +#include <stdio.h> +#include <unistd.h> + +#include "2sysincludes.h" +#include "2common.h" +#include "host_common.h" + +int vb2_read_file(const char *filename, uint8_t **data_ptr, uint32_t *size_ptr) +{ + FILE *f; + uint8_t *buf; + long size; + + *data_ptr = NULL; + *size_ptr = 0; + + f = fopen(filename, "rb"); + if (!f) { + VB2_DEBUG("Unable to open file %s\n", filename); + return VB2_ERROR_READ_FILE_OPEN; + } + + fseek(f, 0, SEEK_END); + size = ftell(f); + rewind(f); + + if (size < 0 || size > UINT32_MAX) { + fclose(f); + return VB2_ERROR_READ_FILE_SIZE; + } + + buf = malloc(size); + if (!buf) { + fclose(f); + return VB2_ERROR_READ_FILE_ALLOC; + } + + if(1 != fread(buf, size, 1, f)) { + VB2_DEBUG("Unable to read file %s\n", filename); + fclose(f); + free(buf); + return VB2_ERROR_READ_FILE_DATA; + } + + fclose(f); + + *data_ptr = buf; + *size_ptr = size; + return VB2_SUCCESS; +} + +int vb2_write_file(const char *filename, const void *buf, uint32_t size) +{ + FILE *f = fopen(filename, "wb"); + + if (!f) { + VB2_DEBUG("Unable to open file %s\n", filename); + return VB2_ERROR_WRITE_FILE_OPEN; + } + + if (1 != fwrite(buf, size, 1, f)) { + VB2_DEBUG("Unable to write to file %s\n", filename); + fclose(f); + unlink(filename); /* Delete any partial file */ + return VB2_ERROR_WRITE_FILE_DATA; + } + + fclose(f); + return VB2_SUCCESS; +} + +int vb2_write_object(const char *filename, const void *buf) +{ + const struct vb2_struct_common *cptr = buf; + + return vb2_write_file(filename, buf, cptr->total_size); +} diff --git a/host/lib/include/host_misc.h b/host/lib/include/host_misc.h index b2b4fb94..2e18d90b 100644 --- a/host/lib/include/host_misc.h +++ b/host/lib/include/host_misc.h @@ -43,4 +43,45 @@ int ReadFileBit(const char* filename, int bitmask); * Returns 0 if success, 1 if error. */ int WriteFile(const char* filename, const void *data, uint64_t size); +/** + * Read data from a file into a newly allocated buffer. + * + * @param filename Name of file to read from + * @param data_ptr On exit, pointer to newly allocated buffer with data + * will be stored here. Caller must free() the buffer + * when done with it. + * @param size_ptr On exit, size of data will be stored here. + * @return VB2_SUCCESS, or non-zero if error. + */ +int vb2_read_file(const char *filename, uint8_t **data_ptr, uint32_t *size_ptr); + +/** + * Write data to a file from a buffer. + * + * @param filename Name of file to write to + * @param buf Buffer to write + * @param size Number of bytes of data to write + * @return VB2_SUCCESS, or non-zero if error. + */ +int vb2_write_file(const char *filename, const void *buf, uint32_t size); + +/** + * Write a buffer which starts with a standard vb2_struct_common header. + * + * Determines the buffer size from the common header total size field. + * + * @param filename Name of file to write to + * @param buf Buffer to write + * @return VB2_SUCCESS, or non-zero if error. + */ +int vb2_write_object(const char *filename, const void *buf); + +/** + * Round up a size to a multiple of 32 bits (4 bytes). + */ +static __inline const uint32_t roundup32(uint32_t v) +{ + return (v + 3) & ~3; +} + #endif /* VBOOT_REFERENCE_HOST_MISC_H_ */ diff --git a/tests/vb2_convert_structs.c b/tests/vb2_convert_structs.c index 0c4a7ec3..d30b337f 100644 --- a/tests/vb2_convert_structs.c +++ b/tests/vb2_convert_structs.c @@ -8,6 +8,8 @@ #include "2sysincludes.h" #include "2common.h" #include "2rsa.h" +#include "host_common.h" +#include "host_misc.h" #include "vb2_convert_structs.h" #include "vboot_struct.h" /* For old struct sizes */ diff --git a/tests/vb2_convert_structs.h b/tests/vb2_convert_structs.h index 032b5bfb..0ba1ca3a 100644 --- a/tests/vb2_convert_structs.h +++ b/tests/vb2_convert_structs.h @@ -10,14 +10,6 @@ #include "2struct.h" /** - * Round up a size to a multiple of 32 bits (4 bytes). - */ -static __inline const uint32_t roundup32(uint32_t v) -{ - return (v + 3) & ~3; -} - -/** * Convert a packed key from vboot data format to vboot2 data format. * * Intended for use by unit tests. Does NOT validate the original struct diff --git a/tests/vb2_host_misc_tests.c b/tests/vb2_host_misc_tests.c new file mode 100644 index 00000000..e8c2a588 --- /dev/null +++ b/tests/vb2_host_misc_tests.c @@ -0,0 +1,71 @@ +/* Copyright (c) 2014 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. + * + * Tests for host misc library vboot2 functions + */ + +#include <unistd.h> + +#include "2sysincludes.h" +#include "2common.h" +#include "host_common.h" +#include "host_misc.h" + +#include "test_common.h" + +static void misc_tests(void) +{ + TEST_EQ(roundup32(0), 0, "roundup32(0)"); + TEST_EQ(roundup32(15), 16, "roundup32(15)"); + TEST_EQ(roundup32(16), 16, "roundup32(16)"); +} + +static void file_tests(void) +{ + const char *testfile = "file_tests.dat"; + const uint8_t test_data[] = "Some test data"; + uint8_t *read_data; + uint32_t read_size; + + uint8_t cbuf[sizeof(struct vb2_struct_common) + 12]; + struct vb2_struct_common *c = (struct vb2_struct_common *)cbuf; + + unlink(testfile); + + TEST_EQ(vb2_read_file(testfile, &read_data, &read_size), + VB2_ERROR_READ_FILE_OPEN, "vb2_read_file() missing"); + TEST_EQ(vb2_write_file("no/such/dir", test_data, sizeof(test_data)), + VB2_ERROR_WRITE_FILE_OPEN, "vb2_write_file() open"); + + TEST_SUCC(vb2_write_file(testfile, test_data, sizeof(test_data)), + "vb2_write_file() good"); + TEST_SUCC(vb2_read_file(testfile, &read_data, &read_size), + "vb2_read_file() good"); + TEST_EQ(read_size, sizeof(test_data), " data size"); + TEST_EQ(memcmp(read_data, test_data, read_size), 0, " data"); + free(read_data); + unlink(testfile); + + memset(cbuf, 0, sizeof(cbuf)); + c->fixed_size = sizeof(*c); + c->total_size = sizeof(cbuf); + c->magic = 0x1234; + cbuf[sizeof(cbuf) - 1] = 0xed; /* Some non-zero data at the end */ + TEST_SUCC(vb2_write_object(testfile, c), "vb2_write_object() good"); + TEST_SUCC(vb2_read_file(testfile, &read_data, &read_size), + "vb2_read_file() object"); + TEST_EQ(read_size, c->total_size, " data size"); + /* Compare the entire buffer, including the non-zero data at the end */ + TEST_EQ(memcmp(read_data, c, read_size), 0, " data"); + free(read_data); + unlink(testfile); +} + +int main(int argc, char* argv[]) +{ + misc_tests(); + file_tests(); + + return gTestSuccess ? 0 : 255; +} |