xref: /aosp_15_r20/external/vboot_reference/host/lib/host_misc.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2011 The ChromiumOS Authors
2*8617a60dSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
3*8617a60dSAndroid Build Coastguard Worker  * found in the LICENSE file.
4*8617a60dSAndroid Build Coastguard Worker  *
5*8617a60dSAndroid Build Coastguard Worker  * Host functions for verified boot.
6*8617a60dSAndroid Build Coastguard Worker  */
7*8617a60dSAndroid Build Coastguard Worker 
8*8617a60dSAndroid Build Coastguard Worker /* TODO: change all 'return 0', 'return 1' into meaningful return codes */
9*8617a60dSAndroid Build Coastguard Worker 
10*8617a60dSAndroid Build Coastguard Worker #include <stdio.h>
11*8617a60dSAndroid Build Coastguard Worker #include <stdlib.h>
12*8617a60dSAndroid Build Coastguard Worker #include <string.h>
13*8617a60dSAndroid Build Coastguard Worker #include <unistd.h>
14*8617a60dSAndroid Build Coastguard Worker 
15*8617a60dSAndroid Build Coastguard Worker #include "host_common.h"
16*8617a60dSAndroid Build Coastguard Worker 
StrCopy(char * dest,const char * src,int dest_size)17*8617a60dSAndroid Build Coastguard Worker char* StrCopy(char* dest, const char* src, int dest_size)
18*8617a60dSAndroid Build Coastguard Worker {
19*8617a60dSAndroid Build Coastguard Worker 	strncpy(dest, src, dest_size);
20*8617a60dSAndroid Build Coastguard Worker 	dest[dest_size - 1] = '\0';
21*8617a60dSAndroid Build Coastguard Worker 	return dest;
22*8617a60dSAndroid Build Coastguard Worker }
23*8617a60dSAndroid Build Coastguard Worker 
ReadFile(const char * filename,uint64_t * sizeptr)24*8617a60dSAndroid Build Coastguard Worker uint8_t* ReadFile(const char* filename, uint64_t* sizeptr)
25*8617a60dSAndroid Build Coastguard Worker {
26*8617a60dSAndroid Build Coastguard Worker 	FILE* f;
27*8617a60dSAndroid Build Coastguard Worker 	uint8_t* buf;
28*8617a60dSAndroid Build Coastguard Worker 	long size;
29*8617a60dSAndroid Build Coastguard Worker 
30*8617a60dSAndroid Build Coastguard Worker 	f = fopen(filename, "rb");
31*8617a60dSAndroid Build Coastguard Worker 	if (!f) {
32*8617a60dSAndroid Build Coastguard Worker 		fprintf(stderr, "Unable to open file %s\n", filename);
33*8617a60dSAndroid Build Coastguard Worker 		return NULL;
34*8617a60dSAndroid Build Coastguard Worker 	}
35*8617a60dSAndroid Build Coastguard Worker 
36*8617a60dSAndroid Build Coastguard Worker 	fseek(f, 0, SEEK_END);
37*8617a60dSAndroid Build Coastguard Worker 	size = ftell(f);
38*8617a60dSAndroid Build Coastguard Worker 	if (size < 0) {
39*8617a60dSAndroid Build Coastguard Worker 		fclose(f);
40*8617a60dSAndroid Build Coastguard Worker 		return NULL;
41*8617a60dSAndroid Build Coastguard Worker 	}
42*8617a60dSAndroid Build Coastguard Worker 	rewind(f);
43*8617a60dSAndroid Build Coastguard Worker 
44*8617a60dSAndroid Build Coastguard Worker 	buf = malloc(size);
45*8617a60dSAndroid Build Coastguard Worker 	if (!buf) {
46*8617a60dSAndroid Build Coastguard Worker 		fclose(f);
47*8617a60dSAndroid Build Coastguard Worker 		return NULL;
48*8617a60dSAndroid Build Coastguard Worker 	}
49*8617a60dSAndroid Build Coastguard Worker 
50*8617a60dSAndroid Build Coastguard Worker 	if (1 != fread(buf, size, 1, f)) {
51*8617a60dSAndroid Build Coastguard Worker 		fprintf(stderr, "Unable to read from file %s\n", filename);
52*8617a60dSAndroid Build Coastguard Worker 		fclose(f);
53*8617a60dSAndroid Build Coastguard Worker 		free(buf);
54*8617a60dSAndroid Build Coastguard Worker 		return NULL;
55*8617a60dSAndroid Build Coastguard Worker 	}
56*8617a60dSAndroid Build Coastguard Worker 
57*8617a60dSAndroid Build Coastguard Worker 	fclose(f);
58*8617a60dSAndroid Build Coastguard Worker 	if (sizeptr)
59*8617a60dSAndroid Build Coastguard Worker 		*sizeptr = size;
60*8617a60dSAndroid Build Coastguard Worker 	return buf;
61*8617a60dSAndroid Build Coastguard Worker }
62*8617a60dSAndroid Build Coastguard Worker 
ReadFileFirstLine(char * dest,int size,const char * filename)63*8617a60dSAndroid Build Coastguard Worker char* ReadFileFirstLine(char* dest, int size, const char* filename)
64*8617a60dSAndroid Build Coastguard Worker {
65*8617a60dSAndroid Build Coastguard Worker 	char* got;
66*8617a60dSAndroid Build Coastguard Worker 	FILE* f;
67*8617a60dSAndroid Build Coastguard Worker 
68*8617a60dSAndroid Build Coastguard Worker 	f = fopen(filename, "rt");
69*8617a60dSAndroid Build Coastguard Worker 	if (!f)
70*8617a60dSAndroid Build Coastguard Worker 		return NULL;
71*8617a60dSAndroid Build Coastguard Worker 
72*8617a60dSAndroid Build Coastguard Worker 	got = fgets(dest, size, f);
73*8617a60dSAndroid Build Coastguard Worker 	fclose(f);
74*8617a60dSAndroid Build Coastguard Worker 
75*8617a60dSAndroid Build Coastguard Worker 	/* chomp the trailing newline if any */
76*8617a60dSAndroid Build Coastguard Worker 	if (got)
77*8617a60dSAndroid Build Coastguard Worker 		dest[strcspn(dest, "\n")] = 0;
78*8617a60dSAndroid Build Coastguard Worker 	return got;
79*8617a60dSAndroid Build Coastguard Worker }
80*8617a60dSAndroid Build Coastguard Worker 
ReadFileInt(const char * filename,unsigned * value)81*8617a60dSAndroid Build Coastguard Worker int ReadFileInt(const char* filename, unsigned* value)
82*8617a60dSAndroid Build Coastguard Worker {
83*8617a60dSAndroid Build Coastguard Worker 	char buf[64];
84*8617a60dSAndroid Build Coastguard Worker 	char* e = NULL;
85*8617a60dSAndroid Build Coastguard Worker 
86*8617a60dSAndroid Build Coastguard Worker 	if (!ReadFileFirstLine(buf, sizeof(buf), filename))
87*8617a60dSAndroid Build Coastguard Worker 		return -1;
88*8617a60dSAndroid Build Coastguard Worker 
89*8617a60dSAndroid Build Coastguard Worker 	/* Convert to integer.  Allow characters after the int ("123 blah"). */
90*8617a60dSAndroid Build Coastguard Worker 	*value = (unsigned)strtoul(buf, &e, 0);
91*8617a60dSAndroid Build Coastguard Worker 	if (e == buf)
92*8617a60dSAndroid Build Coastguard Worker 		return -1;  /* No characters consumed, so conversion failed */
93*8617a60dSAndroid Build Coastguard Worker 
94*8617a60dSAndroid Build Coastguard Worker 	return 0;
95*8617a60dSAndroid Build Coastguard Worker }
96*8617a60dSAndroid Build Coastguard Worker 
ReadFileBit(const char * filename,int bitmask)97*8617a60dSAndroid Build Coastguard Worker int ReadFileBit(const char* filename, int bitmask)
98*8617a60dSAndroid Build Coastguard Worker {
99*8617a60dSAndroid Build Coastguard Worker 	unsigned value;
100*8617a60dSAndroid Build Coastguard Worker 	if (ReadFileInt(filename, &value) < 0)
101*8617a60dSAndroid Build Coastguard Worker 		return -1;
102*8617a60dSAndroid Build Coastguard Worker 	else return (value & bitmask ? 1 : 0);
103*8617a60dSAndroid Build Coastguard Worker }
104*8617a60dSAndroid Build Coastguard Worker 
WriteFile(const char * filename,const void * data,uint64_t size)105*8617a60dSAndroid Build Coastguard Worker vb2_error_t WriteFile(const char* filename, const void *data, uint64_t size)
106*8617a60dSAndroid Build Coastguard Worker {
107*8617a60dSAndroid Build Coastguard Worker 	FILE *f = fopen(filename, "wb");
108*8617a60dSAndroid Build Coastguard Worker 	if (!f) {
109*8617a60dSAndroid Build Coastguard Worker 		fprintf(stderr, "Unable to open file %s\n", filename);
110*8617a60dSAndroid Build Coastguard Worker 		return 1;
111*8617a60dSAndroid Build Coastguard Worker 	}
112*8617a60dSAndroid Build Coastguard Worker 
113*8617a60dSAndroid Build Coastguard Worker 	if (1 != fwrite(data, size, 1, f)) {
114*8617a60dSAndroid Build Coastguard Worker 		fprintf(stderr, "Unable to write to file %s\n", filename);
115*8617a60dSAndroid Build Coastguard Worker 		fclose(f);
116*8617a60dSAndroid Build Coastguard Worker 		unlink(filename);  /* Delete any partial file */
117*8617a60dSAndroid Build Coastguard Worker 		return 1;
118*8617a60dSAndroid Build Coastguard Worker 	}
119*8617a60dSAndroid Build Coastguard Worker 
120*8617a60dSAndroid Build Coastguard Worker 	fclose(f);
121*8617a60dSAndroid Build Coastguard Worker 	return 0;
122*8617a60dSAndroid Build Coastguard Worker }
123*8617a60dSAndroid Build Coastguard Worker 
parse_hex(uint8_t * val,const char * str)124*8617a60dSAndroid Build Coastguard Worker bool parse_hex(uint8_t *val, const char *str)
125*8617a60dSAndroid Build Coastguard Worker {
126*8617a60dSAndroid Build Coastguard Worker 	uint8_t v = 0;
127*8617a60dSAndroid Build Coastguard Worker 	char c;
128*8617a60dSAndroid Build Coastguard Worker 	int digit;
129*8617a60dSAndroid Build Coastguard Worker 
130*8617a60dSAndroid Build Coastguard Worker 	for (digit = 0; digit < 2; digit++) {
131*8617a60dSAndroid Build Coastguard Worker 		c = *str;
132*8617a60dSAndroid Build Coastguard Worker 		if (!c)
133*8617a60dSAndroid Build Coastguard Worker 			return false;
134*8617a60dSAndroid Build Coastguard Worker 		if (!isxdigit(c))
135*8617a60dSAndroid Build Coastguard Worker 			return false;
136*8617a60dSAndroid Build Coastguard Worker 		c = tolower(c);
137*8617a60dSAndroid Build Coastguard Worker 		if (c >= '0' && c <= '9')
138*8617a60dSAndroid Build Coastguard Worker 			v += c - '0';
139*8617a60dSAndroid Build Coastguard Worker 		else
140*8617a60dSAndroid Build Coastguard Worker 			v += 10 + c - 'a';
141*8617a60dSAndroid Build Coastguard Worker 		if (!digit)
142*8617a60dSAndroid Build Coastguard Worker 			v <<= 4;
143*8617a60dSAndroid Build Coastguard Worker 		str++;
144*8617a60dSAndroid Build Coastguard Worker 	}
145*8617a60dSAndroid Build Coastguard Worker 
146*8617a60dSAndroid Build Coastguard Worker 	*val = v;
147*8617a60dSAndroid Build Coastguard Worker 	return true;
148*8617a60dSAndroid Build Coastguard Worker }
149*8617a60dSAndroid Build Coastguard Worker 
parse_hash(uint8_t * buf,size_t len,const char * str)150*8617a60dSAndroid Build Coastguard Worker bool parse_hash(uint8_t *buf, size_t len, const char *str)
151*8617a60dSAndroid Build Coastguard Worker {
152*8617a60dSAndroid Build Coastguard Worker 	const char *s = str;
153*8617a60dSAndroid Build Coastguard Worker 	int i;
154*8617a60dSAndroid Build Coastguard Worker 
155*8617a60dSAndroid Build Coastguard Worker 	for (i = 0; i < len; i++) {
156*8617a60dSAndroid Build Coastguard Worker 		/* skip whitespace */
157*8617a60dSAndroid Build Coastguard Worker 		while (*s && isspace(*s))
158*8617a60dSAndroid Build Coastguard Worker 			s++;
159*8617a60dSAndroid Build Coastguard Worker 		if (!*s)
160*8617a60dSAndroid Build Coastguard Worker 			break;
161*8617a60dSAndroid Build Coastguard Worker 		if (!parse_hex(buf, s))
162*8617a60dSAndroid Build Coastguard Worker 			break;
163*8617a60dSAndroid Build Coastguard Worker 
164*8617a60dSAndroid Build Coastguard Worker 		/* on to the next byte */
165*8617a60dSAndroid Build Coastguard Worker 		s += 2;
166*8617a60dSAndroid Build Coastguard Worker 		buf++;
167*8617a60dSAndroid Build Coastguard Worker 	}
168*8617a60dSAndroid Build Coastguard Worker 
169*8617a60dSAndroid Build Coastguard Worker 	if (i != len || *s)
170*8617a60dSAndroid Build Coastguard Worker 		return false;
171*8617a60dSAndroid Build Coastguard Worker 	return true;
172*8617a60dSAndroid Build Coastguard Worker }
173