132a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler * Use of this source code is governed by a BSD-style license that can be
3d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler * found in the LICENSE file.
4d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler *
5d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler * Host functions for verified boot.
6d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler */
7d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
8d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler/* TODO: change all 'return 0', 'return 1' into meaningful return codes */
9d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
10d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler#include <stdio.h>
11d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler#include <stdlib.h>
12eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler#include <string.h>
136a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler#include <unistd.h>
14d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
15d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler#include "cryptolib.h"
1632a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler#include "host_common.h"
17d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler#include "vboot_common.h"
18d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
19d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
20eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spanglerchar* StrCopy(char* dest, const char* src, int dest_size) {
21eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  strncpy(dest, src, dest_size);
22eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  dest[dest_size - 1] = '\0';
23eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  return dest;
24eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler}
25eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler
26eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler
2772e344d5cdc67e4eb129bb1308ce0e5cca503d2dBill Richardsonuint8_t* ReadFile(const char* filename, uint64_t* sizeptr) {
28d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  FILE* f;
29d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  uint8_t* buf;
3072e344d5cdc67e4eb129bb1308ce0e5cca503d2dBill Richardson  uint64_t size;
31d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
32d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  f = fopen(filename, "rb");
33d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  if (!f) {
34abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    VBDEBUG(("Unable to open file %s\n", filename));
35d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    return NULL;
36d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  }
37d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
38d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  fseek(f, 0, SEEK_END);
3972e344d5cdc67e4eb129bb1308ce0e5cca503d2dBill Richardson  size = ftell(f);
40d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  rewind(f);
41d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
4272e344d5cdc67e4eb129bb1308ce0e5cca503d2dBill Richardson  buf = malloc(size);
43d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  if (!buf) {
44d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    fclose(f);
45d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    return NULL;
46d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  }
47d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
4872e344d5cdc67e4eb129bb1308ce0e5cca503d2dBill Richardson  if(1 != fread(buf, size, 1, f)) {
49abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    VBDEBUG(("Unable to read from file %s\n", filename));
50d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    fclose(f);
5132a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler    free(buf);
52d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler    return NULL;
53d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  }
54d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler
55d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  fclose(f);
5672e344d5cdc67e4eb129bb1308ce0e5cca503d2dBill Richardson  if (sizeptr)
5772e344d5cdc67e4eb129bb1308ce0e5cca503d2dBill Richardson    *sizeptr = size;
58d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler  return buf;
59d55c64537245abca67a66fde5874b7f4a6cdc556Randall Spangler}
606a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler
616a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler
62eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spanglerchar* ReadFileString(char* dest, int size, const char* filename) {
63eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  char* got;
64eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  FILE* f;
65eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler
66eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  f = fopen(filename, "rt");
67eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  if (!f)
68eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler    return NULL;
69eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler
70eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  got = fgets(dest, size, f);
71eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  fclose(f);
72eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  return got;
73eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler}
74eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler
75eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler
76d241fff54c982f2764e6d126a024ab71fa6dd84aDuncan Laurieint ReadFileInt(const char* filename, unsigned* value) {
77eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  char buf[64];
78eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  char* e = NULL;
79eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler
80eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  if (!ReadFileString(buf, sizeof(buf), filename))
81eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler    return -1;
82eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler
83eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  /* Convert to integer.  Allow characters after the int ("123 blah"). */
84d241fff54c982f2764e6d126a024ab71fa6dd84aDuncan Laurie  *value = (unsigned)strtoul(buf, &e, 0);
85eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  if (e == buf)
86eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler    return -1;  /* No characters consumed, so conversion failed */
87eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler
88d241fff54c982f2764e6d126a024ab71fa6dd84aDuncan Laurie  return 0;
89eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler}
90eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler
91eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler
92eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spanglerint ReadFileBit(const char* filename, int bitmask) {
93d241fff54c982f2764e6d126a024ab71fa6dd84aDuncan Laurie  unsigned value;
94d241fff54c982f2764e6d126a024ab71fa6dd84aDuncan Laurie  if (ReadFileInt(filename, &value) < 0)
95eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler    return -1;
96eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  else return (value & bitmask ? 1 : 0);
97eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler}
98eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler
99eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler
1006a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spanglerint WriteFile(const char* filename, const void *data, uint64_t size) {
1016a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler  FILE *f = fopen(filename, "wb");
1026a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler  if (!f) {
103abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    VBDEBUG(("Unable to open file %s\n", filename));
1046a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler    return 1;
1056a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler  }
1066a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler
1076a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler  if (1 != fwrite(data, size, 1, f)) {
108abf055045802cb06c57ff2d7b187736bdcb3b138Bill Richardson    VBDEBUG(("Unable to write to file %s\n", filename));
1096a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler    fclose(f);
1106a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler    unlink(filename);  /* Delete any partial file */
11102e11b323b819140590d99b6af440d36c12d161bRandall Spangler    return 1;
1126a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler  }
1136a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler
1146a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler  fclose(f);
1156a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler  return 0;
1166a97b3e2a1bee35bf3c00f2fb0faafde4aaab9e2Randall Spangler}
117