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