/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * * Utility for signing boot firmware images. */ #include #include #include #include "file_keys.h" #include "utility.h" #include "host_key.h" #include "host_signature.h" #include "host_common.h" static void usage() { static char* help_mesg = "Usage: sign_image " " \n"; printf(help_mesg); } int SignAndWriteImage(uint64_t fw_version, VbKeyBlockHeader* wrapper_kb, VbPrivateKey* signing_key, VbPublicKey* nested_pubkey, uint8_t* image, uint64_t image_size, FILE* out_file) { VbFirmwarePreambleHeader* fw_preamble = NULL; int rv = 1; do { /* to be able to bail out anywhere */ VbSignature* firmware_sig; /* sign the firmware first */ firmware_sig = CalculateSignature(image, image_size, signing_key); /* write the original keyblock */ if (fwrite(wrapper_kb, wrapper_kb->key_block_size, 1, out_file) != 1) { debug("failed writing key block\n"); break; } fw_preamble = CreateFirmwarePreamble(fw_version, nested_pubkey, firmware_sig, signing_key); if (!fw_preamble) { debug("failed creating preamble\n"); break; } /* write the preamble */ if (fwrite(fw_preamble, fw_preamble->preamble_size, 1, out_file) != 1) { debug("failed writing fw preamble\n"); break; } /* write the image */ if (fwrite(image, image_size, 1, out_file) != 1) { debug("failed writing image\n"); break; } rv = 0; } while(0); if (fw_preamble) { Free(fw_preamble); } return rv; } int main(int argc, char* argv[]) { VbKeyBlockHeader* firmware_kb; VbPublicKey* kernel_pubk; uint8_t* firmware; uint64_t fw_size; uint64_t version; VbPrivateKey* signing_key = NULL; FILE* out_file; int rv; if (argc != 7) { usage(); exit(1); } version = strtoul(argv[1], 0, 0); firmware_kb = KeyBlockRead(argv[2]); kernel_pubk = PublicKeyRead(argv[4]); firmware = BufferFromFile(argv[5], &fw_size); if (firmware_kb) { signing_key = PrivateKeyRead(argv[3], firmware_kb->data_key.algorithm); } if (!firmware_kb || !kernel_pubk || !firmware || ! signing_key) { return 1; } out_file = fopen(argv[6], "wb"); if (!out_file) { debug("could not open %s for writing\n"); return 1; } rv = SignAndWriteImage(version, firmware_kb, signing_key, kernel_pubk, firmware, fw_size, out_file); fclose(out_file); if (rv) { unlink(argv[6]); } return rv; }