blob: 51628e3143ad9aebe46e5302cc33eace7e2c49fc [file] [log] [blame]
/* 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#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 <fw_version> <fw_key_block> <signing_key> "
"<kernel_public_key> <firmware_file> <output_file>\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;
}