diff options
-rw-r--r-- | futility/cmd_gscvd.c | 57 | ||||
-rw-r--r-- | futility/cmd_load_fmap.c | 26 | ||||
-rw-r--r-- | futility/cmd_show.c | 135 | ||||
-rw-r--r-- | futility/cmd_sign.c | 145 | ||||
-rw-r--r-- | futility/cmd_validate_rec_mrc.c | 26 | ||||
-rw-r--r-- | futility/file_type.c | 63 | ||||
-rw-r--r-- | futility/file_type.h | 21 | ||||
-rw-r--r-- | futility/file_type_bios.c | 49 | ||||
-rw-r--r-- | futility/file_type_rwsig.c | 72 | ||||
-rw-r--r-- | futility/file_type_usbpd1.c | 42 | ||||
-rw-r--r-- | futility/futility.h | 25 | ||||
-rw-r--r-- | futility/futility_options.h | 3 | ||||
-rw-r--r-- | futility/misc.c | 75 | ||||
-rw-r--r-- | futility/vb2_helper.c | 52 |
14 files changed, 469 insertions, 322 deletions
diff --git a/futility/cmd_gscvd.c b/futility/cmd_gscvd.c index e8b2fae1..d6187c9f 100644 --- a/futility/cmd_gscvd.c +++ b/futility/cmd_gscvd.c @@ -143,35 +143,22 @@ struct gscvd_ro_ranges { static int load_ap_firmware(const char *file_name, struct file_buf *file, int mode) { - int fd; - int rv; + if (futil_open_and_map_file(file_name, &file->fd, mode, &file->data, + &file->len)) + return 1; - fd = open(file_name, mode); - if (fd < 0) { - ERROR("Can't open %s: %s\n", file_name, - strerror(errno)); + if (!fmap_find_by_name(file->data, file->len, NULL, "RO_GSCVD", + &file->ro_gscvd)) { + ERROR("Could not find RO_GSCVD in the FMAP\n"); + futil_unmap_and_close_file(file->fd, mode, file->data, + file->len); + file->fd = -1; + file->data = NULL; + file->len = 0; return 1; } - file->fd = fd; - do { - rv = 1; - - if (futil_map_file(fd, mode == O_RDWR ? MAP_RW : MAP_RO, - &file->data, &file->len)) { - file->data = NULL; - break; - } - - if (!fmap_find_by_name(file->data, file->len, NULL, "RO_GSCVD", - &file->ro_gscvd)) { - ERROR("Could not find RO_GSCVD in the FMAP\n"); - break; - } - rv = 0; - } while (false); - - return rv; + return 0; } /** @@ -809,7 +796,7 @@ static int validate_gscvd(int argc, char *argv[]) rv = -1; /* Speculative, will be cleared on success. */ - if (load_ap_firmware(file_name, &ap_firmware_file, O_RDONLY)) + if (load_ap_firmware(file_name, &ap_firmware_file, FILE_RO)) break; /* Copy ranges from gscvd to local structure. */ @@ -857,6 +844,11 @@ static int validate_gscvd(int argc, char *argv[]) rv = 0; } while (false); + if (ap_firmware_file.fd != -1) + futil_unmap_and_close_file(ap_firmware_file.fd, FILE_RO, + ap_firmware_file.data, + ap_firmware_file.len); + return rv; } @@ -1014,7 +1006,7 @@ static int do_gscvd(int argc, char *argv[]) if (validate_privk(kblock, plat_privk)) break; - if (load_ap_firmware(work_file, &ap_firmware_file, O_RDWR)) + if (load_ap_firmware(work_file, &ap_firmware_file, FILE_RW)) break; if (verify_ranges(&ranges, &ap_firmware_file)) @@ -1038,15 +1030,10 @@ static int do_gscvd(int argc, char *argv[]) free(kblock); vb2_private_key_free(plat_privk); - /* Now flush the file. */ - if (ap_firmware_file.data) { - rv |= futil_unmap_file(ap_firmware_file.fd, true, - ap_firmware_file.data, - ap_firmware_file.len); - } - if (ap_firmware_file.fd != -1) - close(ap_firmware_file.fd); + futil_unmap_and_close_file(ap_firmware_file.fd, FILE_RW, + ap_firmware_file.data, + ap_firmware_file.len); return rv; } diff --git a/futility/cmd_load_fmap.c b/futility/cmd_load_fmap.c index 818fda85..4ab194e1 100644 --- a/futility/cmd_load_fmap.c +++ b/futility/cmd_load_fmap.c @@ -149,22 +149,16 @@ static int do_load_fmap(int argc, char *argv[]) else outfile = infile; - fd = open(outfile, O_RDWR); - if (fd < 0) { - fprintf(stderr, "Can't open %s: %s\n", - outfile, strerror(errno)); - return 1; - } + errorcnt |= futil_open_and_map_file(outfile, &fd, FILE_RW, &buf, &len); - errorcnt |= futil_map_file(fd, MAP_RW, &buf, &len); if (errorcnt) - goto done_file; + goto done; fmap = fmap_find(buf, len); if (!fmap) { fprintf(stderr, "Can't find an FMAP in %s\n", infile); errorcnt++; - goto done_map; + goto done; } for (i = optind; i < argc; i++) { @@ -190,20 +184,10 @@ static int do_load_fmap(int argc, char *argv[]) } } -done_map: - errorcnt |= futil_unmap_file(fd, 1, buf, len); - -done_file: - - if (0 != close(fd)) { - fprintf(stderr, "Error closing %s: %s\n", - outfile, strerror(errno)); - errorcnt++; - } - +done: + errorcnt |= futil_unmap_and_close_file(fd, FILE_RW, buf, len); return !!errorcnt; } DECLARE_FUTIL_COMMAND(load_fmap, do_load_fmap, VBOOT_VERSION_ALL, "Replace the contents of specified FMAP areas"); - diff --git a/futility/cmd_show.c b/futility/cmd_show.c index 08974e4c..9816106a 100644 --- a/futility/cmd_show.c +++ b/futility/cmd_show.c @@ -86,31 +86,49 @@ static void show_keyblock(struct vb2_keyblock *keyblock, const char *name, packed_key_sha1_string(data_key)); } -int ft_show_pubkey(const char *name, uint8_t *buf, uint32_t len, void *data) +int ft_show_pubkey(const char *name, void *data) { - struct vb2_packed_key *pubkey = (struct vb2_packed_key *)buf; + int fd = -1; + struct vb2_packed_key *pubkey; + uint32_t len; + int rv = 0; + + if (futil_open_and_map_file(name, &fd, FILE_RO, (uint8_t **)&pubkey, + &len)) + return 1; if (vb2_packed_key_looks_ok(pubkey, len)) { printf("%s looks bogus\n", name); - return 1; + rv = 1; + goto done; } printf("Public Key file: %s\n", name); show_pubkey(pubkey, " "); - return 0; +done: + futil_unmap_and_close_file(fd, FILE_RO, (uint8_t *)pubkey, len); + return rv; } -int ft_show_privkey(const char *name, uint8_t *buf, uint32_t len, void *data) +int ft_show_privkey(const char *name, void *data) { - struct vb2_packed_private_key *pkey = - (struct vb2_packed_private_key *)buf; + int fd = -1; + int rv = 0; + struct vb2_packed_private_key *pkey = NULL; + uint32_t len; struct vb2_private_key key; - const unsigned char *start = pkey->key_data; + const unsigned char *start; + if (futil_open_and_map_file(name, &fd, FILE_RO, (uint8_t **)&pkey, + &len)) + return 1; + + start = pkey->key_data; if (len <= sizeof(*pkey)) { printf("%s looks bogus\n", name); - return 1; + rv = 1; + goto done; } len -= sizeof(*pkey); key.rsa_private_key = d2i_RSAPrivateKey(NULL, &start, len); @@ -122,20 +140,30 @@ int ft_show_privkey(const char *name, uint8_t *buf, uint32_t len, void *data) printf(" Key sha1sum: %s\n", private_key_sha1_string(&key)); - return 0; +done: + futil_unmap_and_close_file(fd, FILE_RO, (uint8_t *)pkey, len); + return rv; } -int ft_show_keyblock(const char *name, uint8_t *buf, uint32_t len, void *data) +int ft_show_keyblock(const char *name, void *data) { - struct vb2_keyblock *block = (struct vb2_keyblock *)buf; + struct vb2_keyblock *block; struct vb2_public_key *sign_key = show_option.k; int good_sig = 0; int retval = 0; + int fd = -1; + uint32_t len; + + retval = futil_open_and_map_file(name, &fd, FILE_RO, (uint8_t **)&block, + &len); + if (retval) + return 1; /* Check the hash only first */ if (0 != vb2_verify_keyblock_hash(block, len, &wb)) { printf("%s is invalid\n", name); - return 1; + retval = 1; + goto done; } /* Check the signature if we have one */ @@ -148,11 +176,13 @@ int ft_show_keyblock(const char *name, uint8_t *buf, uint32_t len, void *data) show_keyblock(block, name, !!sign_key, good_sig); +done: + futil_unmap_and_close_file(fd, FILE_RO, (uint8_t *)block, len); return retval; } -int ft_show_fw_preamble(const char *name, uint8_t *buf, uint32_t len, - void *data) +int show_fw_preamble_buf(const char *name, uint8_t *buf, uint32_t len, + void *data) { struct vb2_keyblock *keyblock = (struct vb2_keyblock *)buf; struct bios_state_s *state = (struct bios_state_s *)data; @@ -282,17 +312,40 @@ done: return retval; } -int ft_show_kernel_preamble(const char *name, uint8_t *buf, uint32_t len, - void *data) +int ft_show_fw_preamble(const char *name, void *data) { - struct vb2_keyblock *keyblock = (struct vb2_keyblock *)buf; + int rv = 0; + int fd = -1; + uint8_t *buf; + uint32_t len; + + if (futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len)) + return 1; + + rv = show_fw_preamble_buf(name, buf, len, data); + + futil_unmap_and_close_file(fd, FILE_RO, buf, len); + return rv; +} + +int ft_show_kernel_preamble(const char *name, void *data) +{ + struct vb2_keyblock *keyblock; struct vb2_public_key *sign_key = show_option.k; - int retval = 0; + int retval = 1; + int fd = -1; + uint8_t *buf; + uint32_t len; + + if (futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len)) + return 1; + + keyblock = (struct vb2_keyblock *)buf; /* Check the hash... */ if (VB2_SUCCESS != vb2_verify_keyblock_hash(keyblock, len, &wb)) { printf("%s keyblock component is invalid\n", name); - return 1; + goto done; } /* If we have a key, check the signature too */ @@ -304,13 +357,10 @@ int ft_show_kernel_preamble(const char *name, uint8_t *buf, uint32_t len, printf("Kernel partition: %s\n", name); show_keyblock(keyblock, NULL, !!sign_key, good_sig); - if (show_option.strict && (!sign_key || !good_sig)) - retval = 1; - struct vb2_public_key data_key; if (VB2_SUCCESS != vb2_unpack_key(&data_key, &keyblock->data_key)) { fprintf(stderr, "Error parsing data key in %s\n", name); - return 1; + goto done; } uint32_t more = keyblock->keyblock_size; @@ -320,7 +370,7 @@ int ft_show_kernel_preamble(const char *name, uint8_t *buf, uint32_t len, if (VB2_SUCCESS != vb2_verify_kernel_preamble(pre2, len - more, &data_key, &wb)) { printf("%s is invalid\n", name); - return 1; + goto done; } printf("Kernel Preamble:\n"); @@ -367,20 +417,24 @@ int ft_show_kernel_preamble(const char *name, uint8_t *buf, uint32_t len, if (!kernel_blob) { /* TODO: Is this always a failure? The preamble is okay. */ fprintf(stderr, "No kernel blob available to verify.\n"); - return 1; + goto done; } if (VB2_SUCCESS != vb2_verify_data(kernel_blob, kernel_size, &pre2->body_signature, &data_key, &wb)) { fprintf(stderr, "Error verifying kernel body.\n"); - return 1; + goto done; } printf("Body verification succeeded.\n"); printf("Config:\n%s\n", kernel_blob + kernel_cmd_line_offset(pre2)); + if (!show_option.strict || (sign_key && good_sig)) + retval = 0; +done: + futil_unmap_and_close_file(fd, FILE_RO, buf, len); return retval; } @@ -476,9 +530,8 @@ static int do_show(int argc, char *argv[]) uint8_t *pubkbuf = NULL; struct vb2_public_key pubk2; char *infile = 0; - int ifd, i; + int i; int errorcnt = 0; - uint8_t *buf; uint32_t len; char *e = 0; int type_override = 0; @@ -585,34 +638,14 @@ static int do_show(int argc, char *argv[]) for (i = optind; i < argc; i++) { infile = argv[i]; - ifd = open(infile, O_RDONLY); - if (ifd < 0) { - errorcnt++; - fprintf(stderr, "Can't open %s: %s\n", - infile, strerror(errno)); - continue; - } - - if (0 != futil_map_file(ifd, MAP_RO, &buf, &len)) { - errorcnt++; - goto boo; - } /* Allow the user to override the type */ if (type_override) type = show_option.type; else - type = futil_file_type_buf(buf, len); + futil_file_type(infile, &type); - errorcnt += futil_file_type_show(type, infile, buf, len); - - errorcnt += futil_unmap_file(ifd, MAP_RO, buf, len); -boo: - if (close(ifd)) { - errorcnt++; - fprintf(stderr, "Error when closing %s: %s\n", - infile, strerror(errno)); - } + errorcnt += futil_file_type_show(type, infile); } done: diff --git a/futility/cmd_sign.c b/futility/cmd_sign.c index a08238eb..59999977 100644 --- a/futility/cmd_sign.c +++ b/futility/cmd_sign.c @@ -55,14 +55,21 @@ static int no_opt_if(int expr, const char *optname) } /* This wraps/signs a public key, producing a keyblock. */ -int ft_sign_pubkey(const char *name, uint8_t *buf, uint32_t len, void *data) +int ft_sign_pubkey(const char *name, void *data) { - struct vb2_packed_key *data_key = (struct vb2_packed_key *)buf; + struct vb2_packed_key *data_key; + uint32_t data_len; struct vb2_keyblock *block; + int rv = 1; + int fd = -1; - if (vb2_packed_key_looks_ok(data_key, len)) { - fprintf(stderr, "Public key looks bad.\n"); + if (futil_open_and_map_file(name, &fd, FILE_MODE_SIGN(sign_option), + (uint8_t **)&data_key, &data_len)) return 1; + + if (vb2_packed_key_looks_ok(data_key, data_len)) { + fprintf(stderr, "Public key looks bad.\n"); + goto done; } if (sign_option.pem_signpriv) { @@ -82,7 +89,7 @@ int ft_sign_pubkey(const char *name, uint8_t *buf, uint32_t len, void *data) fprintf(stderr, "Unable to read PEM signing key: %s\n", strerror(errno)); - return 1; + goto done; } block = vb2_create_keyblock(data_key, sign_option.signprivate, @@ -95,20 +102,24 @@ int ft_sign_pubkey(const char *name, uint8_t *buf, uint32_t len, void *data) } /* Write it out */ - return WriteSomeParts(sign_option.outfile, - block, block->keyblock_size, - NULL, 0); + rv = WriteSomeParts(sign_option.outfile, block, block->keyblock_size, + NULL, 0); +done: + futil_unmap_and_close_file(fd, FILE_MODE_SIGN(sign_option), + (uint8_t *)data_key, data_len); + return rv; } -int ft_sign_raw_kernel(const char *name, uint8_t *buf, uint32_t len, - void *data) +int ft_sign_raw_kernel(const char *name, void *data) { - uint8_t *vmlinuz_data, *kblob_data, *vblock_data; + uint8_t *vmlinuz_data = NULL, *kblob_data = NULL, *vblock_data = NULL; uint32_t vmlinuz_size, kblob_size, vblock_size; - int rv; + int rv = 1; + int fd = -1; - vmlinuz_data = buf; - vmlinuz_size = len; + if (futil_open_and_map_file(name, &fd, FILE_MODE_SIGN(sign_option), + &vmlinuz_data, &vmlinuz_size)) + return 1; kblob_data = CreateKernelBlob( vmlinuz_data, vmlinuz_size, @@ -118,7 +129,7 @@ int ft_sign_raw_kernel(const char *name, uint8_t *buf, uint32_t len, &kblob_size); if (!kblob_data) { fprintf(stderr, "Unable to create kernel blob\n"); - return 1; + goto done; } VB2_DEBUG("kblob_size = %#x\n", kblob_size); @@ -131,8 +142,7 @@ int ft_sign_raw_kernel(const char *name, uint8_t *buf, uint32_t len, sign_option.flags, &vblock_size); if (!vblock_data) { fprintf(stderr, "Unable to sign kernel blob\n"); - free(kblob_data); - return 1; + goto done; } VB2_DEBUG("vblock_size = %#x\n", vblock_size); @@ -150,22 +160,26 @@ int ft_sign_raw_kernel(const char *name, uint8_t *buf, uint32_t len, vblock_data, vblock_size, kblob_data, kblob_size); +done: + futil_unmap_and_close_file(fd, FILE_MODE_SIGN(sign_option), + vmlinuz_data, vmlinuz_size); free(vblock_data); free(kblob_data); return rv; } -int ft_sign_kern_preamble(const char *name, uint8_t *buf, uint32_t len, - void *data) +int ft_sign_kern_preamble(const char *name, void *data) { - uint8_t *kpart_data, *kblob_data, *vblock_data; + uint8_t *kpart_data = NULL, *kblob_data = NULL, *vblock_data = NULL; uint32_t kpart_size, kblob_size, vblock_size; struct vb2_keyblock *keyblock = NULL; struct vb2_kernel_preamble *preamble = NULL; - int rv = 0; + int rv = 1; + int fd = -1; - kpart_data = buf; - kpart_size = len; + if (futil_open_and_map_file(name, &fd, FILE_MODE_SIGN(sign_option), + &kpart_data, &kpart_size)) + return 1; /* Note: This just sets some static pointers. It doesn't malloc. */ kblob_data = unpack_kernel_partition(kpart_data, kpart_size, @@ -174,7 +188,7 @@ int ft_sign_kern_preamble(const char *name, uint8_t *buf, uint32_t len, if (!kblob_data) { fprintf(stderr, "Unable to unpack kernel partition\n"); - return 1; + goto done; } /* @@ -192,7 +206,7 @@ int ft_sign_kern_preamble(const char *name, uint8_t *buf, uint32_t len, sign_option.config_data, sign_option.config_size)) { fprintf(stderr, "Unable to update config\n"); - return 1; + goto done; } /* Preserve the version unless a new one is given */ @@ -219,7 +233,7 @@ int ft_sign_kern_preamble(const char *name, uint8_t *buf, uint32_t len, &vblock_size); if (!vblock_data) { fprintf(stderr, "Unable to sign kernel blob\n"); - return 1; + goto done; } VB2_DEBUG("vblock_size = %#x\n", vblock_size); @@ -238,24 +252,33 @@ int ft_sign_kern_preamble(const char *name, uint8_t *buf, uint32_t len, * all our modifications to the buffer will get flushed to * disk when we close it. */ memcpy(kpart_data, vblock_data, vblock_size); + rv = 0; } - +done: + futil_unmap_and_close_file(fd, FILE_MODE_SIGN(sign_option), kpart_data, + kpart_size); free(vblock_data); return rv; } -int ft_sign_raw_firmware(const char *name, uint8_t *buf, uint32_t len, - void *data) +int ft_sign_raw_firmware(const char *name, void *data) { - struct vb2_signature *body_sig; - struct vb2_fw_preamble *preamble; - int rv; + struct vb2_signature *body_sig = NULL; + struct vb2_fw_preamble *preamble = NULL; + uint8_t *buf; + uint32_t len; + int rv = 1; + int fd = -1; + + if (futil_open_and_map_file(name, &fd, FILE_MODE_SIGN(sign_option), + &buf, &len)) + return 1; body_sig = vb2_calculate_signature(buf, len, sign_option.signprivate); if (!body_sig) { fprintf(stderr, "Error calculating body signature\n"); - return 1; + goto done; } preamble = vb2_create_fw_preamble( @@ -267,7 +290,7 @@ int ft_sign_raw_firmware(const char *name, uint8_t *buf, uint32_t len, if (!preamble) { fprintf(stderr, "Error creating firmware preamble.\n"); free(body_sig); - return 1; + goto done; } rv = WriteSomeParts(sign_option.outfile, @@ -275,6 +298,8 @@ int ft_sign_raw_firmware(const char *name, uint8_t *buf, uint32_t len, sign_option.keyblock->keyblock_size, preamble, preamble->preamble_size); +done: + futil_unmap_and_close_file(fd, FILE_MODE_SIGN(sign_option), buf, len); free(preamble); free(body_sig); @@ -648,12 +673,8 @@ static int do_sign(int argc, char *argv[]) { char *infile = 0; int i; - int ifd = -1; int errorcnt = 0; - uint8_t *buf; - uint32_t buf_len; char *e = 0; - int mapping; int helpind = 0; int longindex; @@ -1009,56 +1030,18 @@ static int do_sign(int argc, char *argv[]) if (errorcnt) goto done; - if (sign_option.create_new_outfile) { - /* The input is read-only, the output is write-only. */ - mapping = MAP_RO; - VB2_DEBUG("open RO %s\n", infile); - ifd = open(infile, O_RDONLY); - if (ifd < 0) { - errorcnt++; - fprintf(stderr, "Can't open %s for reading: %s\n", - infile, strerror(errno)); - goto done; - } - } else { + if (!sign_option.create_new_outfile) { /* We'll read-modify-write the output file */ - mapping = MAP_RW; if (sign_option.inout_file_count > 1) futil_copy_file_or_die(infile, sign_option.outfile); - VB2_DEBUG("open RW %s\n", sign_option.outfile); infile = sign_option.outfile; - ifd = open(sign_option.outfile, O_RDWR); - if (ifd < 0) { - errorcnt++; - fprintf(stderr, "Can't open %s for writing: %s\n", - sign_option.outfile, strerror(errno)); - goto done; - } - } - - if (0 != futil_map_file(ifd, mapping, &buf, &buf_len)) { - errorcnt++; - goto done; } - errorcnt += futil_file_type_sign(sign_option.type, infile, - buf, buf_len); - - errorcnt += futil_unmap_file(ifd, mapping, buf, buf_len); - + errorcnt += futil_file_type_sign(sign_option.type, infile); done: - if (ifd >= 0 && close(ifd)) { - errorcnt++; - fprintf(stderr, "Error when closing ifd: %s\n", - strerror(errno)); - } - - if (sign_option.signprivate) - free(sign_option.signprivate); - if (sign_option.keyblock) - free(sign_option.keyblock); - if (sign_option.kernel_subkey) - free(sign_option.kernel_subkey); + free(sign_option.signprivate); + free(sign_option.keyblock); + free(sign_option.kernel_subkey); if (sign_option.prikey) vb2_private_key_free(sign_option.prikey); diff --git a/futility/cmd_validate_rec_mrc.c b/futility/cmd_validate_rec_mrc.c index 1d35bed4..7ba59317 100644 --- a/futility/cmd_validate_rec_mrc.c +++ b/futility/cmd_validate_rec_mrc.c @@ -222,31 +222,21 @@ static int do_validate_rec_mrc(int argc, char *argv[]) infile = argv[optind++]; - fd = open(infile, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "Cannot open %s:%s\n", infile, strerror(errno)); + if (futil_open_and_map_file(infile, &fd, FILE_RO, &buff, &file_size) != + FILE_ERR_NONE) return 1; - } - - if (futil_map_file(fd, MAP_RO, &buff, &file_size) != FILE_ERR_NONE) { - fprintf(stderr, "Cannot map file %s\n", infile); - close(fd); - return 1; - } if (offset > file_size) { fprintf(stderr, "File size(%#x) smaller than offset(%#x)\n", file_size, offset); - futil_unmap_file(fd, MAP_RO, buff, file_size); - close(fd); + futil_unmap_and_close_file(fd, FILE_RO, buff, file_size); return 1; } if (get_mrc_data_slot((uint16_t *)(buff + offset), &data_offset, &data_size)) { fprintf(stderr, "Metadata block error\n"); - futil_unmap_file(fd, MAP_RO, buff, file_size); - close(fd); + futil_unmap_and_close_file(fd, FILE_RO, buff, file_size); return 1; } offset += data_offset; @@ -259,12 +249,10 @@ static int do_validate_rec_mrc(int argc, char *argv[]) "offset=%#x, file size=%#x, data_size=%#x\n", offset, file_size, data_size); - if (futil_unmap_file(fd, MAP_RO, buff, file_size) != FILE_ERR_NONE) { - fprintf(stderr, "Failed to unmap file %s\n", infile); - ret = 1; - } + if (futil_unmap_and_close_file(fd, FILE_RO, buff, file_size) != + FILE_ERR_NONE) + return 1; - close(fd); return ret; } diff --git a/futility/file_type.c b/futility/file_type.c index b55d13f1..29c4667e 100644 --- a/futility/file_type.c +++ b/futility/file_type.c @@ -24,8 +24,8 @@ struct futil_file_type_s { const char *desc; /* Functions to identify, display, and sign this type of file. */ enum futil_file_type (*recognize)(uint8_t *buf, uint32_t len); - int (*show)(const char *name, uint8_t *buf, uint32_t len, void *data); - int (*sign)(const char *name, uint8_t *buf, uint32_t len, void *data); + int (*show)(const char *name, void *data); + int (*sign)(const char *name, void *data); }; /* Populate a list of file types and operator functions. */ @@ -99,42 +99,29 @@ enum futil_file_type futil_file_type_buf(uint8_t *buf, uint32_t len) enum futil_file_err futil_file_type(const char *filename, enum futil_file_type *type) { - int ifd; - uint8_t *buf; - uint32_t buf_len; + int ifd = -1; + uint8_t *buf = NULL; + uint32_t buf_len = 0; struct stat sb; enum futil_file_err err = FILE_ERR_NONE; *type = FILE_TYPE_UNKNOWN; - ifd = open(filename, O_RDONLY); - if (ifd < 0) { - fprintf(stderr, "Can't open %s: %s\n", - filename, strerror(errno)); - return FILE_ERR_OPEN; - } + err = futil_open_file(filename, &ifd, FILE_RO); + if (err != FILE_ERR_NONE) + goto done; if (0 != fstat(ifd, &sb)) { - fprintf(stderr, "Can't stat input file: %s\n", - strerror(errno)); - close(ifd); - return FILE_ERR_STAT; + fprintf(stderr, "Can't stat input file: %s\n", strerror(errno)); + err = FILE_ERR_STAT; + goto done; } if (S_ISREG(sb.st_mode) || S_ISBLK(sb.st_mode)) { - err = futil_map_file(ifd, MAP_RO, &buf, &buf_len); - if (err) { - close(ifd); - return err; - } - + err = futil_map_file(ifd, FILE_RO, &buf, &buf_len); + if (err) + goto done; *type = futil_file_type_buf(buf, buf_len); - - err = futil_unmap_file(ifd, MAP_RO, buf, buf_len); - if (err) { - close(ifd); - return err; - } } else if (S_ISDIR(sb.st_mode)) { err = FILE_ERR_DIR; } else if (S_ISCHR(sb.st_mode)) { @@ -144,37 +131,27 @@ enum futil_file_err futil_file_type(const char *filename, } else if (S_ISSOCK(sb.st_mode)) { err = FILE_ERR_SOCK; } - - if (close(ifd)) { - fprintf(stderr, "Error when closing %s: %s\n", - filename, strerror(errno)); - return FILE_ERR_CLOSE; - } - +done: + futil_unmap_and_close_file(ifd, FILE_RO, buf, buf_len); return err; } -int futil_file_type_show(enum futil_file_type type, - const char *filename, - uint8_t *buf, uint32_t len) +int futil_file_type_show(enum futil_file_type type, const char *filename) { if (futil_file_types[type].show) - return futil_file_types[type].show(filename, buf, len, 0); + return futil_file_types[type].show(filename, 0); fprintf(stderr, "Don't know how to show %s (type %s)\n", filename, futil_file_type_name(type)); return 1; } -int futil_file_type_sign(enum futil_file_type type, - const char *filename, - uint8_t *buf, uint32_t len) +int futil_file_type_sign(enum futil_file_type type, const char *filename) { if (futil_file_types[type].sign) - return futil_file_types[type].sign(filename, buf, len, 0); + return futil_file_types[type].sign(filename, 0); fprintf(stderr, "Don't know how to sign %s (type %s)\n", filename, futil_file_type_name(type)); return 1; } - diff --git a/futility/file_type.h b/futility/file_type.h index e1efe760..5a074b3e 100644 --- a/futility/file_type.h +++ b/futility/file_type.h @@ -40,22 +40,18 @@ enum futil_file_err futil_file_type(const char *filename, enum futil_file_type *type); /* - * Call the show() method on a buffer containing a specific file type. + * Call the show() method on a file containing a specific file type. * Returns zero on success. It's up to the caller to ensure that only valid * file types are invoked. */ -int futil_file_type_show(enum futil_file_type type, - const char *filename, - uint8_t *buf, uint32_t len); +int futil_file_type_show(enum futil_file_type type, const char *filename); /* - * Call the sign() method on a buffer containing a specific file type. + * Call the sign() method on a file with specific file type. * Returns zero on success. It's up to the caller to ensure that only valid * file types are invoked. */ -int futil_file_type_sign(enum futil_file_type type, - const char *filename, - uint8_t *buf, uint32_t len); +int futil_file_type_sign(enum futil_file_type type, const char *filename); /* * Declare the file_type functions. Certain functions are reused for more than @@ -66,14 +62,21 @@ int futil_file_type_sign(enum futil_file_type type, #define R_(FOO) \ enum futil_file_type FOO(uint8_t *buf, uint32_t len); #define S_(FOO) \ - int FOO(const char *name, uint8_t *buf, uint32_t len, void *data); + int FOO(const char *name, void *data); #define NONE #define FILE_TYPE(A, B, C, D, E, F) D E F #include "file_type.inc" #undef FILE_TYPE #undef NONE +#undef SG_ #undef S_ #undef R_ #pragma GCC diagnostic pop +/* Declared for use inside other show functions. */ +int show_fw_preamble_buf(const char *name, uint8_t *buf, uint32_t len, + void *data); +int show_vb21_pubkey_buf(const char *name, uint8_t *buf, uint32_t len, + void *data); + #endif /* VBOOT_REFERENCE_FILE_TYPE_H_ */ diff --git a/futility/file_type_bios.c b/futility/file_type_bios.c index 6427201b..17efddec 100644 --- a/futility/file_type_bios.c +++ b/futility/file_type_bios.c @@ -40,7 +40,8 @@ static void fmap_limit_area(FmapAreaHeader *ah, uint32_t len) /** Show functions **/ -int ft_show_gbb(const char *name, uint8_t *buf, uint32_t len, void *data) +static int show_gbb_buf(const char *name, uint8_t *buf, uint32_t len, + void *data) { struct vb2_gbb_header *gbb = (struct vb2_gbb_header *)buf; struct bios_state_s *state = (struct bios_state_s *)data; @@ -75,7 +76,7 @@ int ft_show_gbb(const char *name, uint8_t *buf, uint32_t len, void *data) if (retval) { printf("GBB header is invalid, ignoring content\n"); - return 1; + return retval; } printf("GBB content:\n"); @@ -125,6 +126,23 @@ int ft_show_gbb(const char *name, uint8_t *buf, uint32_t len, void *data) return retval; } +int ft_show_gbb(const char *name, void *data) +{ + int retval = 0; + int fd = -1; + uint8_t *buf; + uint32_t len; + + retval = futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len); + if (retval) + return 1; + + retval = show_gbb_buf(name, buf, len, data); + + futil_unmap_and_close_file(fd, FILE_RO, buf, len); + return retval; +} + /* * This handles FW_MAIN_A and FW_MAIN_B while processing a BIOS image. * @@ -155,16 +173,16 @@ static int fmap_show_fw_main(const char *name, uint8_t *buf, uint32_t len, /* Functions to call to show the bios components */ static int (*fmap_show_fn[])(const char *name, uint8_t *buf, uint32_t len, void *data) = { - ft_show_gbb, + show_gbb_buf, fmap_show_fw_main, fmap_show_fw_main, - ft_show_fw_preamble, - ft_show_fw_preamble, + show_fw_preamble_buf, + show_fw_preamble_buf, }; _Static_assert(ARRAY_SIZE(fmap_show_fn) == NUM_BIOS_COMPONENTS, "Size of fmap_show_fn[] should match NUM_BIOS_COMPONENTS"); -int ft_show_bios(const char *name, uint8_t *buf, uint32_t len, void *data) +int ft_show_bios(const char *name, void *data) { FmapHeader *fmap; FmapAreaHeader *ah = 0; @@ -172,6 +190,13 @@ int ft_show_bios(const char *name, uint8_t *buf, uint32_t len, void *data) enum bios_component c; int retval = 0; struct bios_state_s state; + int fd = -1; + uint8_t *buf; + uint32_t len; + + retval = futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len); + if (retval) + return 1; memset(&state, 0, sizeof(state)); @@ -206,6 +231,7 @@ int ft_show_bios(const char *name, uint8_t *buf, uint32_t len, void *data) } } + futil_unmap_and_close_file(fd, FILE_RO, buf, len); return retval; } @@ -428,7 +454,7 @@ static int (*fmap_sign_fn[])(const char *name, uint8_t *buf, uint32_t len, _Static_assert(ARRAY_SIZE(fmap_sign_fn) == NUM_BIOS_COMPONENTS, "Size of fmap_sign_fn[] should match NUM_BIOS_COMPONENTS"); -int ft_sign_bios(const char *name, uint8_t *buf, uint32_t len, void *data) +int ft_sign_bios(const char *name, void *data) { FmapHeader *fmap; FmapAreaHeader *ah = 0; @@ -436,6 +462,14 @@ int ft_sign_bios(const char *name, uint8_t *buf, uint32_t len, void *data) enum bios_component c; int retval = 0; struct bios_state_s state; + int fd = -1; + uint8_t *buf = NULL; + uint32_t len = 0; + + retval = futil_open_and_map_file(name, &fd, FILE_MODE_SIGN(sign_option), + &buf, &len); + if (retval) + return 1; memset(&state, 0, sizeof(state)); @@ -469,6 +503,7 @@ int ft_sign_bios(const char *name, uint8_t *buf, uint32_t len, void *data) retval += sign_bios_at_end(&state); + futil_unmap_and_close_file(fd, FILE_MODE_SIGN(sign_option), buf, len); return retval; } diff --git a/futility/file_type_rwsig.c b/futility/file_type_rwsig.c index a09782ce..b595e250 100644 --- a/futility/file_type_rwsig.c +++ b/futility/file_type_rwsig.c @@ -58,7 +58,7 @@ static void show_sig(const char *name, const struct vb21_signature *sig) sig->data_size); } -int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin) +int ft_show_rwsig(const char *name, void *nuthin) { const struct vb21_signature *sig = 0; const struct vb21_packed_key *pkey = show_option.pkey; @@ -71,6 +71,15 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin) uint8_t *data; FmapHeader *fmap; int i; + int fd = -1; + uint8_t *buf; + uint32_t len; + int rv; + + if (futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len)) + return 1; + + rv = 1; VB2_DEBUG("name %s len 0x%08x (%d)\n", name, len, len); @@ -81,7 +90,8 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin) show_sig(name, sig); if (!show_option.fv) { printf("No data available to verify\n"); - return show_option.strict; + rv = show_option.strict; + goto done; } data = show_option.fv; data_size = show_option.fv_size; @@ -99,15 +109,15 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin) fmap_find_by_name(buf, len, fmap, "KEY_RO", 0); if (pkey) - ft_show_vb21_pubkey(name, (uint8_t *)pkey, - pkey->c.total_size, NULL); + show_vb21_pubkey_buf(name, (uint8_t *)pkey, + pkey->c.total_size, NULL); } sig = (const struct vb21_signature *) fmap_find_by_name(buf, len, fmap, "SIG_RW", &fmaparea); if (!sig) { VB2_DEBUG("No SIG_RW in FMAP.\n"); - return 1; + goto done; } sig_size = fmaparea->area_size; @@ -116,7 +126,7 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin) (uint8_t*)sig - buf, sig_size); if (VB2_SUCCESS != vb21_verify_signature(sig, sig_size)) - return 1; + goto done; show_sig(name, sig); data = fmap_find_by_name(buf, len, fmap, "EC_RW", &fmaparea); @@ -129,7 +139,7 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin) if (!data) { VB2_DEBUG("No EC_RW in FMAP.\n"); - return 1; + goto done; } } else { /* Or maybe this is just the RW portion, that does not @@ -141,7 +151,7 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin) if (len < sig_size) { VB2_DEBUG("File is too small\n"); - return 1; + goto done; } sig = (const struct vb21_signature *)(buf + len - sig_size); @@ -151,13 +161,14 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin) data_size = sig->data_size; total_data_size = len - sig_size; } else { - return 1; + goto done; } } if (!pkey) { printf("No public key available to verify with\n"); - return show_option.strict; + rv = show_option.strict; + goto done; } /* We already did this once, so it should work again */ @@ -165,12 +176,12 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin) (const uint8_t *)pkey, pkey->c.total_size)) { VB2_DEBUG("Can't unpack pubkey\n"); - return 1; + goto done; } if (data_size > total_data_size) { VB2_DEBUG("Invalid signature data_size: bigger than total area size.\n"); - return 1; + goto done; } /* The sig is destroyed by the verify operation, so make a copy */ @@ -185,7 +196,7 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin) (const struct vb2_public_key *)&key, &wb)) { fprintf(stderr, "Signature verification failed\n"); - return 1; + goto done; } } @@ -193,33 +204,46 @@ int ft_show_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin) for (i = data_size; i < total_data_size; i++) { if (data[i] != 0xff) { fprintf(stderr, "Padding verification failed\n"); - return 1; + goto done; } } printf("Signature verification succeeded.\n"); - return 0; + rv = 0; +done: + futil_unmap_and_close_file(fd, FILE_RO, buf, len); + return rv; } -int ft_sign_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin) +int ft_sign_rwsig(const char *name, void *nuthin) { struct vb21_signature *tmp_sig = 0; struct vb2_public_key *pubkey = 0; struct vb21_packed_key *packedkey = 0; uint8_t *keyb_data = 0; uint32_t keyb_size; - uint8_t* data = buf; /* data to be signed */ - uint32_t r, data_size = len, sig_size = SIGNATURE_RSVD_SIZE; + uint8_t *data; /* data to be signed */ + uint32_t r, data_size, sig_size = SIGNATURE_RSVD_SIZE; int retval = 1; FmapHeader *fmap = NULL; FmapAreaHeader *fmaparea; struct vb21_signature *old_sig = 0; + uint8_t *buf = NULL; + uint32_t len; + int fd = -1; + + if (futil_open_and_map_file(name, &fd, FILE_MODE_SIGN(sign_option), + &buf, &len)) + return 1; + + data = buf; + data_size = len; VB2_DEBUG("name %s len 0x%08x (%d)\n", name, len, len); /* If we don't have a distinct OUTFILE, look for an existing sig */ if (sign_option.inout_file_count < 2) { - fmap = fmap_find(buf, len); + fmap = fmap_find(data, len); if (fmap) { /* This looks like a full image. */ @@ -395,14 +419,12 @@ int ft_sign_rwsig(const char *name, uint8_t *buf, uint32_t len, void *nuthin) /* Finally */ retval = 0; done: - if (tmp_sig) - free(tmp_sig); + futil_unmap_and_close_file(fd, FILE_MODE_SIGN(sign_option), buf, len); + free(tmp_sig); if (pubkey) vb2_public_key_free(pubkey); - if (packedkey) - free(packedkey); - if (keyb_data) - free(keyb_data); + free(packedkey); + free(keyb_data); return retval; } diff --git a/futility/file_type_usbpd1.c b/futility/file_type_usbpd1.c index 93791883..a128a996 100644 --- a/futility/file_type_usbpd1.c +++ b/futility/file_type_usbpd1.c @@ -78,7 +78,7 @@ static int parse_size_opts(uint32_t len, return 1; } -int ft_sign_usbpd1(const char *name, uint8_t *buf, uint32_t len, void *data) +int ft_sign_usbpd1(const char *name, void *data) { struct vb2_private_key *key_ptr = 0; struct vb21_signature *sig_ptr = 0; @@ -94,6 +94,13 @@ int ft_sign_usbpd1(const char *name, uint8_t *buf, uint32_t len, void *data) uint32_t ro_offset; uint32_t rw_offset; uint32_t r; + uint8_t *buf = NULL; + uint32_t len; + int fd = -1; + + if (futil_open_and_map_file(name, &fd, FILE_MODE_SIGN(sign_option), + &buf, &len)) + return 1; VB2_DEBUG("name %s len %#.8x (%d)\n", name, len, len); @@ -237,6 +244,7 @@ int ft_sign_usbpd1(const char *name, uint8_t *buf, uint32_t len, void *data) /* Finally */ retval = 0; done: + futil_unmap_and_close_file(fd, FILE_MODE_SIGN(sign_option), buf, len); if (key_ptr) vb2_private_key_free(key_ptr); if (keyb_data) @@ -425,35 +433,47 @@ static vb2_error_t check_self_consistency(const uint8_t *buf, const char *name, } -int ft_show_usbpd1(const char *name, uint8_t *buf, uint32_t len, void *data) +int ft_show_usbpd1(const char *name, void *data) { uint32_t ro_size, rw_size, ro_offset, rw_offset; int s, h; + int fd = -1; + uint8_t *buf; + uint32_t len; + int rv = 1; + + if (futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len)) + return 1; VB2_DEBUG("name %s len 0x%08x (%d)\n", name, len, len); /* Get image locations */ if (!parse_size_opts(len, &ro_size, &rw_size, &ro_offset, &rw_offset)) - return 1; + goto done; /* TODO: If we don't have a RO image, ask for a public key * TODO: If we're given an external public key, use it (and its alg) */ if (!ro_size) { printf("Can't find the public key\n"); - return 1; + goto done; } /* TODO: Only loop through the numbers we haven't been given */ - for (s = 0; s < ARRAY_SIZE(sigs); s++) - for (h = 0; h < ARRAY_SIZE(hashes); h++) - if (!check_self_consistency(buf, name, - ro_size, rw_size, + for (s = 0; s < ARRAY_SIZE(sigs); s++) { + for (h = 0; h < ARRAY_SIZE(hashes); h++) { + if (!check_self_consistency(buf, name, ro_size, rw_size, ro_offset, rw_offset, - sigs[s], hashes[h])) - return 0; + sigs[s], hashes[h])) { + rv = 0; + goto done; + } + } + } printf("This doesn't appear to be a complete usbpd1 image\n"); - return 1; +done: + futil_unmap_and_close_file(fd, FILE_RO, buf, len); + return rv; } enum futil_file_type ft_recognize_usbpd1(uint8_t *buf, uint32_t len) diff --git a/futility/futility.h b/futility/futility.h index 9d40ba7e..fa4d3de2 100644 --- a/futility/futility.h +++ b/futility/futility.h @@ -132,13 +132,26 @@ enum futil_file_err { FILE_ERR_SOCK, }; +enum file_mode { + FILE_RO, + FILE_RW, +}; + +enum futil_file_err futil_open_file(const char *infile, int *fd, + enum file_mode mode); +enum futil_file_err futil_close_file(int fd); + /* Wrapper for mmap/munmap. Skips stupidly large files. */ -#define MAP_RO 0 -#define MAP_RW 1 -enum futil_file_err futil_map_file(int fd, int writeable, - uint8_t **buf, uint32_t *len); -enum futil_file_err futil_unmap_file(int fd, int writeable, - uint8_t *buf, uint32_t len); +enum futil_file_err futil_map_file(int fd, enum file_mode mode, uint8_t **buf, + uint32_t *len); +enum futil_file_err futil_unmap_file(int fd, enum file_mode mode, uint8_t *buf, + uint32_t len); + +enum futil_file_err futil_open_and_map_file(const char *infile, int *fd, + enum file_mode mode, uint8_t **buf, + uint32_t *len); +enum futil_file_err futil_unmap_and_close_file(int fd, enum file_mode mode, + uint8_t *buf, uint32_t len); /* * Parse input string as a hex representation of size len, exit with error if diff --git a/futility/futility_options.h b/futility/futility_options.h index a79505c3..9c99bba1 100644 --- a/futility/futility_options.h +++ b/futility/futility_options.h @@ -67,4 +67,7 @@ struct sign_option_s { }; extern struct sign_option_s sign_option; +#define FILE_MODE_SIGN(sign_options) \ + (sign_options.create_new_outfile ? FILE_RO : FILE_RW) + #endif /* VBOOT_REFERENCE_FUTILITY_OPTIONS_H_ */ diff --git a/futility/misc.c b/futility/misc.c index 76b8ad1e..4aec13a3 100644 --- a/futility/misc.c +++ b/futility/misc.c @@ -5,6 +5,7 @@ #include <assert.h> #include <errno.h> +#include <fcntl.h> #if !defined(HAVE_MACOS) && !defined(__FreeBSD__) && !defined(__OpenBSD__) #include <linux/fs.h> /* For BLKGETSIZE64 */ #endif @@ -258,8 +259,40 @@ void futil_copy_file_or_die(const char *infile, const char *outfile) exit(1); } +enum futil_file_err futil_open_file(const char *infile, int *fd, + enum file_mode mode) +{ + if (mode == FILE_RW) { + VB2_DEBUG("open RW %s\n", infile); + *fd = open(infile, O_RDWR); + if (*fd < 0) { + fprintf(stderr, "Can't open %s for writing: %s\n", + infile, strerror(errno)); + return FILE_ERR_OPEN; + } + } else { + VB2_DEBUG("open RO %s\n", infile); + *fd = open(infile, O_RDONLY); + if (*fd < 0) { + fprintf(stderr, "Can't open %s for reading: %s\n", + infile, strerror(errno)); + return FILE_ERR_OPEN; + } + } + return FILE_ERR_NONE; +} + +enum futil_file_err futil_close_file(int fd) +{ + if (fd >= 0 && close(fd)) { + fprintf(stderr, "Error when closing ifd: %s\n", + strerror(errno)); + return FILE_ERR_CLOSE; + } + return FILE_ERR_NONE; +} -enum futil_file_err futil_map_file(int fd, int writeable, +enum futil_file_err futil_map_file(int fd, enum file_mode mode, uint8_t **buf, uint32_t *len) { struct stat sb; @@ -284,7 +317,7 @@ enum futil_file_err futil_map_file(int fd, int writeable, } reasonable_len = (uint32_t)sb.st_size; - if (writeable) + if (mode == FILE_RW) mmap_ptr = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); else @@ -293,7 +326,7 @@ enum futil_file_err futil_map_file(int fd, int writeable, if (mmap_ptr == (void *)-1) { fprintf(stderr, "Can't mmap %s file: %s\n", - writeable ? "output" : "input", + mode == FILE_RW ? "output" : "input", strerror(errno)); return FILE_ERR_MMAP; } @@ -303,14 +336,14 @@ enum futil_file_err futil_map_file(int fd, int writeable, return FILE_ERR_NONE; } -enum futil_file_err futil_unmap_file(int fd, int writeable, +enum futil_file_err futil_unmap_file(int fd, enum file_mode mode, uint8_t *buf, uint32_t len) { void *mmap_ptr = buf; enum futil_file_err err = FILE_ERR_NONE; - if (writeable && - (0 != msync(mmap_ptr, len, MS_SYNC|MS_INVALIDATE))) { + if (mode == FILE_RW && + (0 != msync(mmap_ptr, len, MS_SYNC | MS_INVALIDATE))) { fprintf(stderr, "msync failed: %s\n", strerror(errno)); err = FILE_ERR_MSYNC; } @@ -325,6 +358,36 @@ enum futil_file_err futil_unmap_file(int fd, int writeable, return err; } +enum futil_file_err futil_open_and_map_file(const char *infile, int *fd, + enum file_mode mode, uint8_t **buf, + uint32_t *len) +{ + enum futil_file_err rv = futil_open_file(infile, fd, mode); + if (rv != FILE_ERR_NONE) + return rv; + + rv = futil_map_file(*fd, mode, buf, len); + if (rv != FILE_ERR_NONE) + futil_close_file(*fd); + + return rv; +} + +enum futil_file_err futil_unmap_and_close_file(int fd, enum file_mode mode, + uint8_t *buf, uint32_t len) +{ + enum futil_file_err rv = FILE_ERR_NONE; + + if (buf) + rv = futil_unmap_file(fd, mode, buf, len); + if (rv != FILE_ERR_NONE) + return rv; + + if (fd != -1) + return futil_close_file(fd); + else + return FILE_ERR_NONE; +} #define DISK_SECTOR_SIZE 512 enum futil_file_type ft_recognize_gpt(uint8_t *buf, uint32_t len) diff --git a/futility/vb2_helper.c b/futility/vb2_helper.c index 4d676a68..a8452db6 100644 --- a/futility/vb2_helper.c +++ b/futility/vb2_helper.c @@ -60,7 +60,7 @@ static int vb2_public_key_sha1sum(struct vb2_public_key *key, uint8_t *digest) return 1; } -int ft_show_vb21_pubkey(const char *name, uint8_t *buf, uint32_t len, +int show_vb21_pubkey_buf(const char *name, uint8_t *buf, uint32_t len, void *data) { struct vb2_public_key key; @@ -91,6 +91,22 @@ int ft_show_vb21_pubkey(const char *name, uint8_t *buf, uint32_t len, return 0; } +int ft_show_vb21_pubkey(const char *name, void *data) +{ + int fd = -1; + uint8_t *buf; + uint32_t len; + int rv; + + if (futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len)) + return 1; + + rv = show_vb21_pubkey_buf(name, buf, len, data); + + futil_unmap_and_close_file(fd, FILE_RO, buf, len); + return rv; +} + static int vb2_private_key_sha1sum(struct vb2_private_key *key, uint8_t *digest) { uint8_t *buf; @@ -106,15 +122,23 @@ static int vb2_private_key_sha1sum(struct vb2_private_key *key, uint8_t *digest) return 1; } -int ft_show_vb21_privkey(const char *name, uint8_t *buf, uint32_t len, - void *data) +int ft_show_vb21_privkey(const char *name, void *data) { struct vb2_private_key *key = 0; uint8_t sha1sum[VB2_SHA1_DIGEST_SIZE]; + int fd = -1; + uint8_t *buf; + uint32_t len; + int rv = 0; - if (VB2_SUCCESS != vb21_private_key_unpack(&key, buf, len)) + if (futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len)) return 1; + if (VB2_SUCCESS != vb21_private_key_unpack(&key, buf, len)) { + rv = 1; + goto done; + } + printf("Private key file: %s\n", name); printf(" Vboot API: 2.1\n"); printf(" Desc: \"%s\"\n", key->desc ? key->desc : ""); @@ -132,7 +156,9 @@ int ft_show_vb21_privkey(const char *name, uint8_t *buf, uint32_t len, printf("\n"); } vb2_private_key_free(key); - return 0; +done: + futil_unmap_and_close_file(fd, FILE_RO, buf, len); + return rv; } static RSA *rsa_from_buffer(uint8_t *buf, uint32_t len) @@ -172,7 +198,7 @@ enum futil_file_type ft_recognize_pem(uint8_t *buf, uint32_t len) return FILE_TYPE_UNKNOWN; } -int ft_show_pem(const char *name, uint8_t *buf, uint32_t len, void *data) +int ft_show_pem(const char *name, void *data) { RSA *rsa_key; uint8_t *keyb; @@ -180,6 +206,13 @@ int ft_show_pem(const char *name, uint8_t *buf, uint32_t len, void *data) uint32_t keyb_len; int i, bits; const BIGNUM *rsa_key_n, *rsa_key_d; + int fd = -1; + uint8_t *buf; + uint32_t len; + int rv = 0; + + if (futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len)) + return 1; /* We're called only after ft_recognize_pem, so this should work. */ rsa_key = rsa_from_buffer(buf, len); @@ -197,7 +230,8 @@ int ft_show_pem(const char *name, uint8_t *buf, uint32_t len, void *data) if (vb_keyb_from_rsa(rsa_key, &keyb, &keyb_len)) { printf(" Key sha1sum: <error>"); RSA_free(rsa_key); - return 1; + rv = 1; + goto done; } printf(" Key sha1sum: "); @@ -209,5 +243,7 @@ int ft_show_pem(const char *name, uint8_t *buf, uint32_t len, void *data) free(keyb); RSA_free(rsa_key); - return 0; +done: + futil_unmap_and_close_file(fd, FILE_RO, buf, len); + return rv; } |