mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 02:05:01 +00:00
Ryu will store a hash of the GBB root key in a struct inside its boot
block. Add a vb2_ryu_root_key_hash struct for that.
If 'futility gbb_utility' is used to set the root key, also look for a
root key hash struct and fill it in. No error if not found, because
this needs to work on other platforms where the struct is not present.
This way, we don't need to change the signing scripts.
Added a --roothash option which can be used to check if the root key
hash is found, and if so, whether it's empty, valid, or invalid.
BUG=chromium:511405
BRANCH=ryu
TEST=manual
Take any existing image.bin.
cp image.bin image.orig
gbb_utility --roothash image.bin
- ryu root hash not found
Extract the root key
gbb_utility -k rootkey.bin image.bin
- exported root_key to file: rootkey.bin
Now, append a blank ryu root hash struct to it
echo '0000000: 5274 4b79 4861 7368 0100 0000 3000 0000' | xxd -r >> image.bin
echo '0000000: 0000 0000 0000 0000 0000 0000 0000 0000' | xxd -r >> image.bin
echo '0000000: 0000 0000 0000 0000 0000 0000 0000 0000' | xxd -r >> image.bin
Nothing is set yet
gbb_utility --roothash image.bin
- ryu root hash is unset
Setting the root key also sets the root hash
gbb_utility -s -k rootkey.bin image.bin
- import root_key from rootkey.bin: success
- calculate ryu root hash: success
successfully saved new image to: image.bin
See, it verifies
gbb_utility --roothash image.bin
- ryu root hash verified
Now, append a bad ryu root hash struct to it
cp image.orig image.bin
echo '0000000: 5274 4b79 4861 7368 0100 0000 3000 0000' | xxd -r >> image.bin
echo '0000000: 0001 0000 0000 0000 0000 0000 0000 0000' | xxd -r >> image.bin
echo '0000000: 0000 0000 0000 0000 0000 0000 0000 0000' | xxd -r >> image.bin
See, it fails
gbb_utility --roothash image.bin
- ryu root hash does not verify
Make sure the library doesn't contain the magic string
strings `which futility` | grep RtKyHash
(should be no output)
Change-Id: Ib46f93cac0f2b532bada4b187ae48efcf4926702
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/286237
Reviewed-by: Furquan Shaikh <furquan@chromium.org>
160 lines
4.4 KiB
C
160 lines
4.4 KiB
C
/*
|
|
* Copyright (c) 2013 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.
|
|
*/
|
|
#ifndef VBOOT_REFERENCE_FUTILITY_H_
|
|
#define VBOOT_REFERENCE_FUTILITY_H_
|
|
#include <stdint.h>
|
|
|
|
#include "vboot_common.h"
|
|
#include "gbb_header.h"
|
|
#include "host_key.h"
|
|
|
|
/* This program */
|
|
#define MYNAME "futility"
|
|
|
|
/* Version string (autogenerated) */
|
|
extern const char futility_version[];
|
|
|
|
/* Bitfields indicating the struct/format versions supported by a command */
|
|
enum vboot_version {
|
|
/*
|
|
* v1.0 is the original structs used since the dawn of time.
|
|
* v2.0 can verify the firmware in smaller chunks, but there's
|
|
* no difference in the on-device structs, so it's only
|
|
* meaningful for the firmware API. Futility doesn't care.
|
|
*/
|
|
VBOOT_VERSION_1_0 = 0x00000001,
|
|
|
|
/*
|
|
* v2.1 uses new and different structs, and is what v2.0 would have
|
|
* been if someone hadn't started using it before it was ready.
|
|
*/
|
|
VBOOT_VERSION_2_1 = 0x00000002,
|
|
|
|
/*
|
|
* Everything we know about to date.
|
|
*/
|
|
VBOOT_VERSION_ALL = 0x00000003,
|
|
};
|
|
|
|
/* What's our preferred API & data format? */
|
|
enum vboot_version vboot_version;
|
|
|
|
/* Here's a structure to define the commands that futility implements. */
|
|
struct futil_cmd_t {
|
|
/* String used to invoke this command */
|
|
const char *const name;
|
|
/* Function to do the work. Returns 0 on success.
|
|
* Called with argv[0] == "name".
|
|
* It should handle its own "--help" option. */
|
|
int (*const handler) (int argc, char **argv);
|
|
/* Supported ABIs */
|
|
enum vboot_version version;
|
|
/* One-line summary of what it does */
|
|
const char *const shorthelp;
|
|
};
|
|
|
|
/* Macro to define a command */
|
|
#define DECLARE_FUTIL_COMMAND(NAME, HANDLER, VERSION, SHORTHELP) \
|
|
const struct futil_cmd_t __cmd_##NAME = { \
|
|
.name = #NAME, \
|
|
.handler = HANDLER, \
|
|
.version = VERSION, \
|
|
.shorthelp = SHORTHELP, \
|
|
}
|
|
|
|
/* This is the list of pointers to all commands. */
|
|
extern const struct futil_cmd_t *const futil_cmds[];
|
|
|
|
/* Size of an array */
|
|
#ifndef ARRAY_SIZE
|
|
#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
|
|
#endif
|
|
|
|
/* Test an important condition at compile time, not run time */
|
|
#ifndef BUILD_ASSERT
|
|
#define _BA1_(cond, line) \
|
|
extern int __build_assertion_ ## line[1 - 2*!(cond)] \
|
|
__attribute__ ((unused))
|
|
#define _BA0_(c, x) _BA1_(c, x)
|
|
#define BUILD_ASSERT(cond) _BA0_(cond, __LINE__)
|
|
#endif
|
|
|
|
/* Fatal internal stupidness */
|
|
#ifndef DIE
|
|
#define DIE do { \
|
|
fprintf(stderr, MYNAME ": internal error at %s:%d\n", \
|
|
__FILE__, __LINE__); \
|
|
exit(1); \
|
|
} while (0)
|
|
#endif
|
|
|
|
/* Debug output (off by default) */
|
|
extern int debugging_enabled;
|
|
void Debug(const char *format, ...);
|
|
|
|
/* Returns true if this looks enough like a GBB header to proceed. */
|
|
int futil_looks_like_gbb(GoogleBinaryBlockHeader *gbb, uint32_t len);
|
|
|
|
/*
|
|
* Returns true if the gbb header is valid (and optionally updates *maxlen).
|
|
* This doesn't verify the contents, though.
|
|
*/
|
|
int futil_valid_gbb_header(GoogleBinaryBlockHeader *gbb, uint32_t len,
|
|
uint32_t *maxlen);
|
|
|
|
/* For GBB v1.2 and later, update the hwid_digest */
|
|
void update_hwid_digest(GoogleBinaryBlockHeader *gbb);
|
|
|
|
/* For GBB v1.2 and later, print the stored digest of the HWID (and whether
|
|
* it's correct). Return true if it is correct. */
|
|
int print_hwid_digest(GoogleBinaryBlockHeader *gbb,
|
|
const char *banner, const char *footer);
|
|
|
|
/* Copies a file or dies with an error message */
|
|
void futil_copy_file_or_die(const char *infile, const char *outfile);
|
|
|
|
/* Update ryu root key header in the image */
|
|
int fill_ryu_root_header(uint8_t *ptr, size_t size,
|
|
const GoogleBinaryBlockHeader *gbb);
|
|
|
|
/* Verify ryu root key header */
|
|
int verify_ryu_root_header(uint8_t *ptr, size_t size,
|
|
const GoogleBinaryBlockHeader *gbb);
|
|
|
|
/* Possible file operation errors */
|
|
enum futil_file_err {
|
|
FILE_ERR_NONE,
|
|
FILE_ERR_STAT,
|
|
FILE_ERR_SIZE,
|
|
FILE_ERR_MMAP,
|
|
FILE_ERR_MSYNC,
|
|
FILE_ERR_MUNMAP,
|
|
FILE_ERR_OPEN,
|
|
FILE_ERR_CLOSE,
|
|
FILE_ERR_DIR,
|
|
FILE_ERR_CHR,
|
|
FILE_ERR_FIFO,
|
|
FILE_ERR_SOCK,
|
|
};
|
|
|
|
/* Wrapper for mmap/munmap. Skips stupidly large files. */
|
|
#define MAP_RO 0
|
|
#define MAP_RW 1
|
|
enum futil_file_err futil_map_file(int fd, int writeable,
|
|
uint8_t **buf, uint32_t *len);
|
|
enum futil_file_err futil_unmap_file(int fd, int writeable,
|
|
uint8_t *buf, uint32_t len);
|
|
|
|
/* The CPU architecture is occasionally important */
|
|
enum arch_t {
|
|
ARCH_UNSPECIFIED,
|
|
ARCH_X86,
|
|
ARCH_ARM,
|
|
ARCH_MIPS
|
|
};
|
|
|
|
#endif /* VBOOT_REFERENCE_FUTILITY_H_ */
|