| /* Copyright 2011 The ChromiumOS Authors | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| * | |
| * Host functions for verified boot. | |
| */ | |
| /* TODO: change all 'return 0', 'return 1' into meaningful return codes */ | |
| #include <ctype.h> | |
| #include <errno.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include "host_common.h" | |
| char* StrCopy(char* dest, const char* src, int dest_size) | |
| { | |
| strncpy(dest, src, dest_size); | |
| dest[dest_size - 1] = '\0'; | |
| return dest; | |
| } | |
| uint8_t* ReadFile(const char* filename, uint64_t* sizeptr) | |
| { | |
| uint8_t *buf; | |
| uint32_t size; | |
| if (vb2_read_file(filename, &buf, &size) != VB2_SUCCESS) { | |
| fprintf(stderr, "Unable to read from file %s\n", filename); | |
| return NULL; | |
| } | |
| if (sizeptr) | |
| *sizeptr = size; | |
| return buf; | |
| } | |
| char* ReadFileFirstLine(char* dest, int size, const char* filename) | |
| { | |
| char* got; | |
| FILE* f; | |
| f = fopen(filename, "rt"); | |
| if (!f) { | |
| /* Crossystem uses file reading calls to also check for the file existence. | |
| * Missing file means falling back to the generic non-arch dependent | |
| * implementation. */ | |
| if (errno != ENOENT) | |
| fprintf(stderr, "ERROR: %s: Failed to open %s: %s\n", __func__, | |
| filename, strerror(errno)); | |
| return NULL; | |
| } | |
| got = fgets(dest, size, f); | |
| fclose(f); | |
| /* chomp the trailing newline if any */ | |
| if (got) | |
| dest[strcspn(dest, "\r\n")] = 0; | |
| return got; | |
| } | |
| int ReadFileInt(const char* filename, unsigned* value) | |
| { | |
| char buf[64]; | |
| char* e = NULL; | |
| if (!ReadFileFirstLine(buf, sizeof(buf), filename)) | |
| return -1; | |
| /* Convert to integer. Allow characters after the int ("123 blah"). */ | |
| *value = (unsigned)strtoul(buf, &e, 0); | |
| if (e == buf) | |
| return -1; /* No characters consumed, so conversion failed */ | |
| return 0; | |
| } | |
| int ReadFileBit(const char* filename, int bitmask) | |
| { | |
| unsigned value; | |
| if (ReadFileInt(filename, &value) < 0) | |
| return -1; | |
| else return (value & bitmask ? 1 : 0); | |
| } | |
| vb2_error_t WriteFile(const char* filename, const void *data, uint64_t size) | |
| { | |
| if (size > UINT32_MAX || | |
| vb2_write_file(filename, data, size) != VB2_SUCCESS) { | |
| fprintf(stderr, "Unable to write to file %s\n", filename); | |
| return 1; | |
| } | |
| return 0; | |
| } | |
| bool parse_hash(uint8_t *buf, size_t len, const char *str) | |
| { | |
| for (size_t i = 0; i < len; i++) { | |
| while (isspace(*str)) | |
| str++; | |
| if (!isxdigit(str[0]) || !isxdigit(str[1]) || | |
| sscanf(str, "%2hhx", &buf[i]) != 1) | |
| return false; | |
| str += 2; | |
| } | |
| return *str == '\0'; | |
| } | |
| bool is_valid_property_string(const char *str) | |
| { | |
| if (!str) | |
| return false; | |
| for (const char *p = str; *p; p++) { | |
| if (*p < 0x20 || *p >= 0x7f) | |
| return false; | |
| if (*p == '=' || *p == '\\' || *p == '\'' || *p == '"') | |
| return false; | |
| } | |
| return true; | |
| } |