diff options
author | Gaurav Shah <gauravsh@chromium.org> | 2010-06-08 00:16:35 -0700 |
---|---|---|
committer | Gaurav Shah <gauravsh@chromium.org> | 2010-06-08 00:16:35 -0700 |
commit | 51734261006c8fc611b6efe6f74788b4065500ed (patch) | |
tree | e072a1d24aa816651fdc5884bd06f4ea1611dc4a | |
parent | a319ac9c33484381c9b6997389cfcd225a47035e (diff) | |
download | vboot-51734261006c8fc611b6efe6f74788b4065500ed.tar.gz |
Add option to specify a kernel subkey signing key to firmware signing utility.
If no kernel subkey signing key is specified, it reuses the firmware signing key.
Review URL: http://codereview.chromium.org/2696003
-rw-r--r-- | utility/Makefile | 1 | ||||
-rw-r--r-- | utility/firmware_utility.cc | 57 | ||||
-rw-r--r-- | utility/include/firmware_utility.h | 2 |
3 files changed, 55 insertions, 5 deletions
diff --git a/utility/Makefile b/utility/Makefile index 23a6e171..d116eb00 100644 --- a/utility/Makefile +++ b/utility/Makefile @@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +FWDIR ?= ../vboot_firmware/ TOP ?= ../ CC ?= gcc CXX ?= g++ diff --git a/utility/firmware_utility.cc b/utility/firmware_utility.cc index aaf936b2..f154010e 100644 --- a/utility/firmware_utility.cc +++ b/utility/firmware_utility.cc @@ -8,8 +8,8 @@ #include "firmware_utility.h" #include <getopt.h> -#include <stdio.h> #include <stdint.h> // Needed for UINT16_MAX. +#include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -36,6 +36,7 @@ FirmwareUtility::FirmwareUtility(): firmware_key_version_(-1), firmware_sign_algorithm_(-1), firmware_version_(-1), + kernel_subkey_sign_algorithm_(-1), is_generate_(false), is_verify_(false), is_describe_(false), @@ -74,6 +75,8 @@ void FirmwareUtility::PrintUsage(void) { " --out <outfile>\t\tOutput file for verified boot firmware image\n" "\n" "Optional:\n" + " --kernel_root_algorithm\tKernel subkey signing algorithm\n" + " --kernel_root_key_pub\t\tKernel subkey signing key to use\n" " --subkey_out\t\t\tJust output the subkey (key verification) header\n" " --vblock\t\t\tJust output the verification block\n" "\n" @@ -103,6 +106,8 @@ bool FirmwareUtility::ParseCmdLineOptions(int argc, char* argv[]) { OPT_DESCRIBE, OPT_VBLOCK, OPT_SUBKEY_OUT, + OPT_KERNEL_ROOT_KEY_PUB, + OPT_KERNEL_ROOT_ALGORITHM, }; static struct option long_options[] = { {"root_key", 1, 0, OPT_ROOT_KEY }, @@ -120,6 +125,8 @@ bool FirmwareUtility::ParseCmdLineOptions(int argc, char* argv[]) { {"describe", 0, 0, OPT_DESCRIBE }, {"vblock", 0, 0, OPT_VBLOCK }, {"subkey_out", 0, 0, OPT_SUBKEY_OUT }, + {"kernel_root_key_pub", 1, 0, OPT_KERNEL_ROOT_KEY_PUB }, + {"kernel_root_algorithm", 1, 0, OPT_KERNEL_ROOT_ALGORITHM }, {NULL, 0, 0, 0} }; while ((i = getopt_long(argc, argv, "", long_options, &option_index)) != -1) { @@ -190,6 +197,18 @@ bool FirmwareUtility::ParseCmdLineOptions(int argc, char* argv[]) { case OPT_SUBKEY_OUT: is_subkey_out_ = true; break; + case OPT_KERNEL_ROOT_ALGORITHM: + kernel_subkey_sign_algorithm_ = strtol(optarg, &e, 0); + if (!*optarg || (e && *e)) { + cerr << "Invalid argument to --" + << long_options[option_index].name + << ": " << optarg << "\n"; + return false; + } + break; + case OPT_KERNEL_ROOT_KEY_PUB: + kernel_subkey_sign_pub_file_ = optarg; + break; } } return CheckOptions(); @@ -239,9 +258,6 @@ bool FirmwareUtility::GenerateSignedImage(void) { // Calculate header checksum. CalculateFirmwareHeaderChecksum(image_, image_->header_checksum); - image_->firmware_version = firmware_version_; - image_->firmware_len = 0; - // Generate and add the key signatures. if (!AddFirmwareKeySignature(image_, root_key_file_.c_str())) { cerr << "Couldn't write key signature to verified boot image.\n"; @@ -314,12 +330,34 @@ bool FirmwareUtility::GenerateSignedImage(void) { Free(subkey_header_buf); if (st.overrun || st.remaining_len != 0) // Overrun or underrun. return false; - return true; } + image_->firmware_version = firmware_version_; + image_->firmware_len = 0; + if (!kernel_subkey_sign_pub_file_.empty()) { + uint64_t subkey_len; + image_->kernel_subkey_sign_algorithm = kernel_subkey_sign_algorithm_; + image_->kernel_subkey_sign_key = BufferFromFile( + kernel_subkey_sign_pub_file_.c_str(), &subkey_len); + if (static_cast<int>(subkey_len) != + RSAProcessedKeySize(kernel_subkey_sign_algorithm_)) { + cerr << "Invalid kernel subkey signing key." + << "\n"; + return false; + } + } else { + // Reuse firmware signing key as kernel subkey signing key. + image_->kernel_subkey_sign_algorithm = image_->firmware_sign_algorithm; + image_->kernel_subkey_sign_key = (uint8_t*) Malloc(RSAProcessedKeySize( + image_->firmware_sign_algorithm)); + Memcpy(image_->kernel_subkey_sign_key, + image_->firmware_sign_key, + RSAProcessedKeySize(image_->firmware_sign_algorithm)); + } // TODO(gauravsh): Populate this with the right bytes once we decide // what goes into the preamble. Memset(image_->preamble, 'P', FIRMWARE_PREAMBLE_SIZE); + image_->firmware_data = BufferFromFile(in_file_.c_str(), &image_->firmware_len); if (!image_->firmware_data) @@ -407,6 +445,15 @@ bool FirmwareUtility::CheckOptions(void) { cerr <<"No output file specified." << "\n"; return false; } + if (!kernel_subkey_sign_pub_file_.empty()) { + // kernel subkey signing algorithm must be valid. + if (kernel_subkey_sign_algorithm_ < 0 || + kernel_subkey_sign_algorithm_ >= kNumAlgorithms) { + cerr << "Invalid or no kernel subkey signing algorithm specified." + << "\n"; + return false; + } + } } return true; } diff --git a/utility/include/firmware_utility.h b/utility/include/firmware_utility.h index 663536a2..27c154fa 100644 --- a/utility/include/firmware_utility.h +++ b/utility/include/firmware_utility.h @@ -59,9 +59,11 @@ class FirmwareUtility { std::string subkey_in_file_; // Existing key signature header. std::string in_file_; std::string out_file_; + std::string kernel_subkey_sign_pub_file_; int firmware_key_version_; int firmware_sign_algorithm_; int firmware_version_; + int kernel_subkey_sign_algorithm_; bool is_generate_; // Are we generating a new image? bool is_verify_; // Are we just verifying an already signed image? bool is_describe_; // Should we print out description of the image? |