mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 18:25:10 +00:00
vboot2: Add host library functions to read/write files and objects
And unit tests for them. Move roundup32() into hostlib. Fix WriteFile() returning success even if it failed to write to the file. BUG=chromium:423882 BRANCH=none TEST=VBOOT2=1 make runtests Change-Id: I8a115335c088dc5c66c88423d1ccbda7eaca1996 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/230844
This commit is contained in:
committed by
chrome-internal-fetch
parent
8577b5360c
commit
02e11b323b
8
Makefile
8
Makefile
@@ -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
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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);
|
||||
|
||||
84
host/lib/host_misc2.c
Normal file
84
host/lib/host_misc2.c
Normal file
@@ -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);
|
||||
}
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -9,14 +9,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.
|
||||
*
|
||||
|
||||
71
tests/vb2_host_misc_tests.c
Normal file
71
tests/vb2_host_misc_tests.c
Normal file
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user