12559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson/* 22559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson * Copyright 2015 The Chromium OS Authors. All rights reserved. 32559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson * Use of this source code is governed by a BSD-style license that can be 42559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson * found in the LICENSE file. 52559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson */ 62559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson 72559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson#include <errno.h> 82559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson#include <fcntl.h> 92559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson#include <stdint.h> 102559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson#include <stdio.h> 112559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson#include <stdlib.h> 122559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson#include <string.h> 132559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson#include <sys/stat.h> 142559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson#include <sys/types.h> 152559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson#include <unistd.h> 162559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson 172559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson#include "file_type.h" 182559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson#include "futility.h" 192559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson#include "gbb_header.h" 202559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson 212559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson/* Human-readable strings */ 222559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardsonstatic const char * const type_strings[] = { 232559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson "unknown", 242559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson "VbPublicKey", 252559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson "VbKeyBlock", 262559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson "VbFirmwarePreamble", 272559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson "GBB", 282559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson "Chrome OS BIOS image", 292559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson "Cr-48 Chrome OS BIOS image", 302559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson "VbKernelPreamble", 312559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson "raw firmware", 322559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson "raw kernel", 332559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson "chromiumos disk image", 344805f1841de9d670aaed9bdaea21147ee1d59242Bill Richardson "VbPrivateKey", 352559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson}; 362559338dbdacbcbd3ae426337403196135bbc7e8Bill RichardsonBUILD_ASSERT(ARRAY_SIZE(type_strings) == NUM_FILE_TYPES); 372559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson 382559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardsonconst char * const futil_file_type_str(enum futil_file_type type) 392559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson{ 4005987b159acb9737707b9ef92b818ac434ef8c3dDavid Riley if ((int) type < 0 || type >= NUM_FILE_TYPES) 412559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson type = FILE_TYPE_UNKNOWN; 422559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson 432559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson return type_strings[type]; 442559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson} 452559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson 462559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson/* Try these in order so we recognize the larger objects first */ 472559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardsonenum futil_file_type (*recognizers[])(uint8_t *buf, uint32_t len) = { 482559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson &recognize_gpt, 492559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson &recognize_bios_image, 502559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson &recognize_gbb, 512559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson &recognize_vblock1, 524805f1841de9d670aaed9bdaea21147ee1d59242Bill Richardson &recognize_privkey, 532559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson}; 542559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson 552559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson/* Try to figure out what we're looking at */ 562559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardsonenum futil_file_type futil_file_type_buf(uint8_t *buf, uint32_t len) 572559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson{ 582559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson enum futil_file_type type; 592559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson int i; 602559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson 612559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson for (i = 0; i < ARRAY_SIZE(recognizers); i++) { 622559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson type = recognizers[i](buf, len); 632559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson if (type != FILE_TYPE_UNKNOWN) 642559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson return type; 652559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson } 662559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson 672559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson return FILE_TYPE_UNKNOWN; 682559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson} 692559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson 702559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardsonenum futil_file_err futil_file_type(const char *filename, 712559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson enum futil_file_type *type) 722559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson{ 732559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson int ifd; 742559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson uint8_t *buf; 752559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson uint32_t buf_len; 762559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson struct stat sb; 772559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson enum futil_file_err err = FILE_ERR_NONE; 782559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson 792559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson *type = FILE_TYPE_UNKNOWN; 802559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson 812559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson ifd = open(filename, O_RDONLY); 822559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson if (ifd < 0) { 832559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson fprintf(stderr, "Can't open %s: %s\n", 842559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson filename, strerror(errno)); 852559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson return FILE_ERR_OPEN; 862559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson } 872559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson 882559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson if (0 != fstat(ifd, &sb)) { 892559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson fprintf(stderr, "Can't stat input file: %s\n", 902559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson strerror(errno)); 912559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson return FILE_ERR_STAT; 922559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson } 932559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson 942559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson if (S_ISREG(sb.st_mode) || S_ISBLK(sb.st_mode)) { 952559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson err = futil_map_file(ifd, MAP_RO, &buf, &buf_len); 962559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson if (err) { 972559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson close(ifd); 982559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson return err; 992559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson } 1002559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson 1012559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson *type = futil_file_type_buf(buf, buf_len); 1022559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson 1032559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson err = futil_unmap_file(ifd, MAP_RO, buf, buf_len); 1042559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson if (err) { 1052559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson close(ifd); 1062559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson return err; 1072559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson } 1082559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson } else if (S_ISDIR(sb.st_mode)) { 1092559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson err = FILE_ERR_DIR; 1102559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson } else if (S_ISCHR(sb.st_mode)) { 1112559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson err = FILE_ERR_CHR; 1122559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson } else if (S_ISFIFO(sb.st_mode)) { 1132559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson err = FILE_ERR_FIFO; 1142559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson } else if (S_ISSOCK(sb.st_mode)) { 1152559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson err = FILE_ERR_SOCK; 1162559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson } 1172559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson 1182559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson if (close(ifd)) { 1192559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson fprintf(stderr, "Error when closing %s: %s\n", 1202559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson filename, strerror(errno)); 1212559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson return FILE_ERR_CLOSE; 1222559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson } 1232559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson 1242559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson return err; 1252559338dbdacbcbd3ae426337403196135bbc7e8Bill Richardson} 126