summaryrefslogtreecommitdiff
path: root/futility/futility.h
blob: 2bf3d7f4f1997e3dd7b0ab972418a033d870882c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/* Copyright 2013 The ChromiumOS Authors
 * 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 "2common.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? */
extern 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

/* Fatal error (print error message and exit). */
#define FATAL(format, ...) do { \
		fprintf(stderr, "FATAL: %s: " format, __func__, \
			##__VA_ARGS__ ); \
		exit(1); \
	} while (0)

/* Print error messages (won't exit). */
#define ERROR(format, ...) fprintf(stderr, "ERROR: %s: " format, __func__, \
				   ##__VA_ARGS__ )
#define WARN(format, ...) fprintf(stderr, "WARNING: %s: " format, __func__, \
				  ##__VA_ARGS__ )
#define INFO(format, ...) fprintf(stderr, "INFO: %s: " format, __func__, \
				  ##__VA_ARGS__ )
#define STATUS(format, ...) fprintf(stderr, ">> " format, ##__VA_ARGS__ )

/* Debug output (off by default) */
extern int debugging_enabled;

/* Returns true if this looks enough like a GBB header to proceed. */
int futil_looks_like_gbb(struct vb2_gbb_header *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(struct vb2_gbb_header *gbb, uint32_t len,
			   uint32_t *maxlen);

/* Sets the HWID string field inside a GBB header. */
int futil_set_gbb_hwid(struct vb2_gbb_header *gbb, const char *hwid);

/* For GBB v1.2 and later, update the hwid_digest */
void update_hwid_digest(struct vb2_gbb_header *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(struct vb2_gbb_header *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);

/* 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,
};

enum file_mode {
	FILE_RO,
	FILE_RW,
};

enum futil_file_err futil_open_file(const char *infile, int *fd,
				    enum file_mode mode);
enum futil_file_err futil_close_file(int fd);

/* Wrapper for mmap/munmap. Skips stupidly large files. */
enum futil_file_err futil_map_file(int fd, enum file_mode mode, uint8_t **buf,
				   uint32_t *len);
enum futil_file_err futil_unmap_file(int fd, enum file_mode mode, uint8_t *buf,
				     uint32_t len);

enum futil_file_err futil_open_and_map_file(const char *infile, int *fd,
					    enum file_mode mode, uint8_t **buf,
					    uint32_t *len);
enum futil_file_err futil_unmap_and_close_file(int fd, enum file_mode mode,
					       uint8_t *buf, uint32_t len);

/*
 * Parse input string as a hex representation of size len, exit with error if
 *  the string is not a valid hex string or is of a wrongs size.
 */
void parse_digest_or_die(uint8_t *buf, int len, const char *str);

/*
 * Print provided buffer as hex string
 */
void print_bytes(const void *ptr, size_t len);

/* The CPU architecture is occasionally important */
enum arch_t {
	ARCH_UNSPECIFIED,
	ARCH_X86,
	ARCH_ARM,
	ARCH_MIPS
};

#endif  /* VBOOT_REFERENCE_FUTILITY_H_ */