1 /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
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 <stdio.h>
9 #include <unistd.h>
10 
11 #include "2sysincludes.h"
12 #include "2common.h"
13 #include "2sha.h"
14 #include "vb2_common.h"
15 #include "host_common.h"
16 #include "host_misc2.h"
17 
vb2_read_file(const char * filename,uint8_t ** data_ptr,uint32_t * size_ptr)18 int vb2_read_file(const char *filename, uint8_t **data_ptr, uint32_t *size_ptr)
19 {
20 	FILE *f;
21 	uint8_t *buf;
22 	long size;
23 
24 	*data_ptr = NULL;
25 	*size_ptr = 0;
26 
27 	f = fopen(filename, "rb");
28 	if (!f) {
29 		VB2_DEBUG("Unable to open file %s\n", filename);
30 		return VB2_ERROR_READ_FILE_OPEN;
31 	}
32 
33 	fseek(f, 0, SEEK_END);
34 	size = ftell(f);
35 	rewind(f);
36 
37 	if (size < 0 || size > UINT32_MAX) {
38 		fclose(f);
39 		return VB2_ERROR_READ_FILE_SIZE;
40 	}
41 
42 	buf = malloc(size);
43 	if (!buf) {
44 		fclose(f);
45 		return VB2_ERROR_READ_FILE_ALLOC;
46 	}
47 
48 	if(1 != fread(buf, size, 1, f)) {
49 		VB2_DEBUG("Unable to read file %s\n", filename);
50 		fclose(f);
51 		free(buf);
52 		return VB2_ERROR_READ_FILE_DATA;
53 	}
54 
55 	fclose(f);
56 
57 	*data_ptr = buf;
58 	*size_ptr = size;
59 	return VB2_SUCCESS;
60 }
61 
vb2_write_file(const char * filename,const void * buf,uint32_t size)62 int vb2_write_file(const char *filename, const void *buf, uint32_t size)
63 {
64 	FILE *f = fopen(filename, "wb");
65 
66 	if (!f) {
67 		VB2_DEBUG("Unable to open file %s\n", filename);
68 		return VB2_ERROR_WRITE_FILE_OPEN;
69 	}
70 
71 	if (1 != fwrite(buf, size, 1, f)) {
72 		VB2_DEBUG("Unable to write to file %s\n", filename);
73 		fclose(f);
74 		unlink(filename);  /* Delete any partial file */
75 		return VB2_ERROR_WRITE_FILE_DATA;
76 	}
77 
78 	fclose(f);
79 	return VB2_SUCCESS;
80 }
81 
vb2_write_object(const char * filename,const void * buf)82 int vb2_write_object(const char *filename, const void *buf)
83 {
84 	const struct vb2_struct_common *cptr = buf;
85 
86 	return vb2_write_file(filename, buf, cptr->total_size);
87 }
88 
vb2_desc_size(const char * desc)89 uint32_t vb2_desc_size(const char *desc)
90 {
91 	if (!desc || !*desc)
92 		return 0;
93 
94 	return roundup32(strlen(desc) + 1);
95 }
96 
vb2_str_to_guid(const char * str,struct vb2_guid * guid)97 int vb2_str_to_guid(const char *str, struct vb2_guid *guid)
98 {
99 	uint32_t time_low;
100 	uint16_t time_mid;
101 	uint16_t time_high_and_version;
102 	unsigned int chunk[11];
103 
104 	if (!str ||
105 	    11 != sscanf(str,
106 			 "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
107 			 chunk+0,
108 			 chunk+1,
109 			 chunk+2,
110 			 chunk+3,
111 			 chunk+4,
112 			 chunk+5,
113 			 chunk+6,
114 			 chunk+7,
115 			 chunk+8,
116 			 chunk+9,
117 			 chunk+10)) {
118 		return VB2_ERROR_STR_TO_GUID;
119 	}
120 
121 	time_low = chunk[0] & 0xffffffff;
122 	time_mid = chunk[1] & 0xffff;
123 	time_high_and_version = chunk[2] & 0xffff;
124 
125 	guid->uuid.time_low = htole32(time_low);
126 	guid->uuid.time_mid = htole16(time_mid);
127 	guid->uuid.time_high_and_version = htole16(time_high_and_version);
128 
129 	guid->uuid.clock_seq_high_and_reserved = chunk[3] & 0xff;
130 	guid->uuid.clock_seq_low = chunk[4] & 0xff;
131 	guid->uuid.node[0] = chunk[5] & 0xff;
132 	guid->uuid.node[1] = chunk[6] & 0xff;
133 	guid->uuid.node[2] = chunk[7] & 0xff;
134 	guid->uuid.node[3] = chunk[8] & 0xff;
135 	guid->uuid.node[4] = chunk[9] & 0xff;
136 	guid->uuid.node[5] = chunk[10] & 0xff;
137 
138 	return VB2_SUCCESS;
139 }
140 
vb2_guid_to_str(const struct vb2_guid * guid,char * buf,unsigned int buflen)141 int vb2_guid_to_str(const struct vb2_guid *guid,
142 		    char *buf, unsigned int buflen)
143 {
144 	int n;
145 
146 	if (!buf || buflen < VB2_GUID_MIN_STRLEN)
147 		return VB2_ERROR_GUID_TO_STR;
148 
149 	n = snprintf(buf, buflen,
150 		     "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
151 		     le32toh(guid->uuid.time_low),
152 		     le16toh(guid->uuid.time_mid),
153 		     le16toh(guid->uuid.time_high_and_version),
154 		     guid->uuid.clock_seq_high_and_reserved,
155 		     guid->uuid.clock_seq_low,
156 		     guid->uuid.node[0], guid->uuid.node[1],
157 		     guid->uuid.node[2], guid->uuid.node[3],
158 		     guid->uuid.node[4], guid->uuid.node[5]);
159 
160 	if (n != VB2_GUID_MIN_STRLEN - 1)
161 		return VB2_ERROR_GUID_TO_STR;
162 
163 	return VB2_SUCCESS;
164 }
165