xref: /aosp_15_r20/external/vboot_reference/host/lib21/host_misc.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
1 /* Copyright 2014 The ChromiumOS Authors
2  * Use of this source code is governed by a BSD-style license that can be
3  * found in the LICENSE file.
4  *
5  * Host functions for verified boot.
6  */
7 
8 #include <ctype.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <unistd.h>
12 
13 #include "2common.h"
14 #include "2sha.h"
15 #include "2sysincludes.h"
16 #include "host_common.h"
17 #include "host_common21.h"
18 #include "host_misc21.h"
19 
vb2_read_file(const char * filename,uint8_t ** data_ptr,uint32_t * size_ptr)20 vb2_error_t vb2_read_file(const char *filename, uint8_t **data_ptr,
21 			  uint32_t *size_ptr)
22 {
23 	FILE *f;
24 	uint8_t *buf;
25 	long size;
26 
27 	*data_ptr = NULL;
28 	*size_ptr = 0;
29 
30 	f = fopen(filename, "rb");
31 	if (!f) {
32 		VB2_DEBUG("Unable to open file %s\n", filename);
33 		return VB2_ERROR_READ_FILE_OPEN;
34 	}
35 
36 	fseek(f, 0, SEEK_END);
37 	size = ftell(f);
38 	rewind(f);
39 
40 	if (size < 0 || size > UINT32_MAX) {
41 		fclose(f);
42 		return VB2_ERROR_READ_FILE_SIZE;
43 	}
44 
45 	buf = malloc(size + 1);
46 	if (!buf) {
47 		fclose(f);
48 		return VB2_ERROR_READ_FILE_ALLOC;
49 	}
50 	buf[size] = '\0';
51 
52 	if (1 != fread(buf, size, 1, f)) {
53 		VB2_DEBUG("Unable to read file %s\n", filename);
54 		fclose(f);
55 		free(buf);
56 		return VB2_ERROR_READ_FILE_DATA;
57 	}
58 
59 	fclose(f);
60 
61 	*data_ptr = buf;
62 	*size_ptr = size;
63 	return VB2_SUCCESS;
64 }
65 
vb2_write_file(const char * filename,const void * buf,uint32_t size)66 vb2_error_t vb2_write_file(const char *filename, const void *buf, uint32_t size)
67 {
68 	FILE *f = fopen(filename, "wb");
69 
70 	if (!f) {
71 		VB2_DEBUG("Unable to open file %s\n", filename);
72 		return VB2_ERROR_WRITE_FILE_OPEN;
73 	}
74 
75 	if (1 != fwrite(buf, size, 1, f)) {
76 		VB2_DEBUG("Unable to write to file %s\n", filename);
77 		fclose(f);
78 		unlink(filename);  /* Delete any partial file */
79 		return VB2_ERROR_WRITE_FILE_DATA;
80 	}
81 
82 	fclose(f);
83 	return VB2_SUCCESS;
84 }
85 
vb21_write_object(const char * filename,const void * buf)86 vb2_error_t vb21_write_object(const char *filename, const void *buf)
87 {
88 	const struct vb21_struct_common *cptr = buf;
89 
90 	return vb2_write_file(filename, buf, cptr->total_size);
91 }
92 
vb2_desc_size(const char * desc)93 uint32_t vb2_desc_size(const char *desc)
94 {
95 	if (!desc || !*desc)
96 		return 0;
97 
98 	return roundup32(strlen(desc) + 1);
99 }
100 
onedigit(const char * str,uint8_t * vptr)101 static const char *onedigit(const char *str, uint8_t *vptr)
102 {
103 	uint8_t val = 0;
104 	char c;
105 
106 	for (; (c = *str++) && !isxdigit(c);)
107 		;
108 	if (!c)
109 		return 0;
110 
111 	if (c >= '0' && c <= '9')
112 		val = c - '0';
113 	else if (c >= 'A' && c <= 'F')
114 		val = 10 + c - 'A';
115 	else if (c >= 'a' && c <= 'f')
116 		val = 10 + c - 'a';
117 
118 	*vptr = val;
119 	return str;
120 }
121 
onebyte(const char * str,uint8_t * vptr)122 static const char *onebyte(const char *str, uint8_t *vptr)
123 {
124 	uint8_t val;
125 	uint8_t digit;
126 
127 	str = onedigit(str, &digit);
128 	if (!str)
129 		return 0;
130 	val = digit << 4;
131 
132 	str = onedigit(str, &digit);
133 	if (!str)
134 		return 0;
135 	val |= digit;
136 
137 	*vptr = val;
138 	return str;
139 }
140 
vb2_str_to_id(const char * str,struct vb2_id * id)141 vb2_error_t vb2_str_to_id(const char *str, struct vb2_id *id)
142 {
143 	uint8_t val = 0;
144 	int i;
145 
146 	if (!str)
147 		return VB2_ERROR_STR_TO_ID;
148 
149 	memset(id, 0, sizeof(*id));
150 
151 	for (i = 0; i < VB2_ID_NUM_BYTES; i++) {
152 
153 		str = onebyte(str, &val);
154 		if (!str)
155 			break;
156 		id->raw[i] = val;
157 	}
158 
159 	/* If we get at least one valid byte, that's good enough. */
160 	return i ? VB2_SUCCESS : VB2_ERROR_STR_TO_ID;
161 }
162