summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGaurav Shah <gauravsh@chromium.org>2010-05-29 01:58:07 -0700
committerGaurav Shah <gauravsh@chromium.org>2010-05-29 01:58:07 -0700
commit67660cda7aa45c8546910b95c194fe17dd6c888b (patch)
treea07b4932607d126ef5d43daa205463b15a956042
parent6bcaa107fbd42edf0ba6ad3dee6275bb220bc2d8 (diff)
downloadvboot-67660cda7aa45c8546910b95c194fe17dd6c888b.tar.gz
Add --subkey_in and --subkey_out options to firmware signing utility.
With this change, just like the kernel signing utility, the firmware signing utility now supports outputting the key signature (subkey) header and reusing it to generate new signed firmware images without requiring the root key (assuming the firmware signing key doesn't change). Also, some minor comment fixes I missed the last time around. Review URL: http://codereview.chromium.org/2366004
-rw-r--r--utility/firmware_utility.cc212
-rw-r--r--utility/include/firmware_utility.h8
-rw-r--r--utility/kernel_utility.cc24
-rw-r--r--vfirmware/firmware_image.c24
-rw-r--r--vfirmware/include/firmware_image.h10
-rw-r--r--vkernel/include/kernel_image.h6
6 files changed, 208 insertions, 76 deletions
diff --git a/utility/firmware_utility.cc b/utility/firmware_utility.cc
index b152ee1c..aaf936b2 100644
--- a/utility/firmware_utility.cc
+++ b/utility/firmware_utility.cc
@@ -19,23 +19,28 @@ extern "C" {
#include "cryptolib.h"
#include "file_keys.h"
#include "firmware_image.h"
-#include "utility.h"
+#include "stateful_util.h"
}
using std::cerr;
+// Macro to determine the size of a field structure in the FirmwareImage
+// structure.
+#define FIELD_LEN(field) (sizeof(((FirmwareImage*)0)->field))
+
namespace vboot_reference {
FirmwareUtility::FirmwareUtility():
image_(NULL),
root_key_pub_(NULL),
- firmware_version_(-1),
firmware_key_version_(-1),
firmware_sign_algorithm_(-1),
+ firmware_version_(-1),
is_generate_(false),
is_verify_(false),
is_describe_(false),
- is_only_vblock_(false) {
+ is_only_vblock_(false),
+ is_subkey_out_(false) {
}
FirmwareUtility::~FirmwareUtility() {
@@ -50,23 +55,27 @@ void FirmwareUtility::PrintUsage(void) {
"Usage: firmware_utility <--generate|--verify> [OPTIONS]\n"
"\n"
"For \"--verify\", required OPTIONS are:\n"
- "--in <infile>\t\t\tVerified boot firmware image to verify.\n"
- "--root_key_pub <pubkeyfile>\tPre-processed public root key "
+ " --in <infile>\t\t\tVerified boot firmware image to verify.\n"
+ " --root_key_pub <pubkeyfile>\tPre-processed public root key "
"to use for verification.\n"
"\n"
"For \"--generate\", required OPTIONS are:\n"
- "--root_key <privkeyfile>\tPrivate root key file\n"
- "--firmware_sign_key <privkeyfile>\tPrivate signing key file\n"
- "--firmware_sign_key_pub <pubkeyfile>\tPre-processed public signing"
+ " --root_key <privkeyfile>\t\tPrivate root key file\n"
+ " --firmware_key_pub <pubkeyfile>\tPre-processed public signing"
" key\n"
- "--firmware_sign_algorithm <algoid>\tSigning algorithm to use\n"
- "--firmware_key_version <version#>\tSigning Key Version#\n"
- "--firmware_version <version#>\tFirmware Version#\n"
- "--in <infile>\t\t\tFirmware Image to sign\n"
- "--out <outfile>\t\t\tOutput file for verified boot firmware image\n"
+ " --firmware_sign_algorithm <algoid>\tSigning algorithm to use\n"
+ " --firmware_key_version <version#>\tSigning Key Version#\n"
+ "OR\n"
+ " --subkey_in <subkeyfile>\t\tExisting key signature header\n"
+ "\n"
+ " --firmware_key <privkeyfile>\tPrivate signing key file\n"
+ " --firmware_version <version#>\tFirmware Version#\n"
+ " --in <infile>\t\t\tFirmware Image to sign\n"
+ " --out <outfile>\t\tOutput file for verified boot firmware image\n"
"\n"
"Optional:\n"
- " --vblock\t\t\tJust output the verification block\n"
+ " --subkey_out\t\t\tJust output the subkey (key verification) header\n"
+ " --vblock\t\t\tJust output the verification block\n"
"\n"
"<algoid> (for --sign-algorithm) is one of the following:\n";
for (int i = 0; i < kNumAlgorithms; i++) {
@@ -83,6 +92,7 @@ bool FirmwareUtility::ParseCmdLineOptions(int argc, char* argv[]) {
OPT_ROOT_KEY_PUB,
OPT_FIRMWARE_KEY,
OPT_FIRMWARE_KEY_PUB,
+ OPT_SUBKEY_IN,
OPT_FIRMWARE_SIGN_ALGORITHM,
OPT_FIRMWARE_KEY_VERSION,
OPT_FIRMWARE_VERSION,
@@ -92,12 +102,14 @@ bool FirmwareUtility::ParseCmdLineOptions(int argc, char* argv[]) {
OPT_VERIFY,
OPT_DESCRIBE,
OPT_VBLOCK,
+ OPT_SUBKEY_OUT,
};
static struct option long_options[] = {
{"root_key", 1, 0, OPT_ROOT_KEY },
{"root_key_pub", 1, 0, OPT_ROOT_KEY_PUB },
{"firmware_key", 1, 0, OPT_FIRMWARE_KEY },
{"firmware_key_pub", 1, 0, OPT_FIRMWARE_KEY_PUB },
+ {"subkey_in", 1, 0, OPT_SUBKEY_IN },
{"firmware_sign_algorithm", 1, 0, OPT_FIRMWARE_SIGN_ALGORITHM },
{"firmware_key_version", 1, 0, OPT_FIRMWARE_KEY_VERSION },
{"firmware_version", 1, 0, OPT_FIRMWARE_VERSION },
@@ -107,6 +119,7 @@ bool FirmwareUtility::ParseCmdLineOptions(int argc, char* argv[]) {
{"verify", 0, 0, OPT_VERIFY },
{"describe", 0, 0, OPT_DESCRIBE },
{"vblock", 0, 0, OPT_VBLOCK },
+ {"subkey_out", 0, 0, OPT_SUBKEY_OUT },
{NULL, 0, 0, 0}
};
while ((i = getopt_long(argc, argv, "", long_options, &option_index)) != -1) {
@@ -126,6 +139,9 @@ bool FirmwareUtility::ParseCmdLineOptions(int argc, char* argv[]) {
case OPT_FIRMWARE_KEY_PUB:
firmware_key_pub_file_ = optarg;
break;
+ case OPT_SUBKEY_IN:
+ subkey_in_file_ = optarg;
+ break;
case OPT_FIRMWARE_SIGN_ALGORITHM:
firmware_sign_algorithm_ = strtol(optarg, &e, 0);
if (!*optarg || (e && *e)) {
@@ -171,6 +187,9 @@ bool FirmwareUtility::ParseCmdLineOptions(int argc, char* argv[]) {
case OPT_VBLOCK:
is_only_vblock_ = true;
break;
+ case OPT_SUBKEY_OUT:
+ is_subkey_out_ = true;
+ break;
}
}
return CheckOptions();
@@ -179,7 +198,9 @@ bool FirmwareUtility::ParseCmdLineOptions(int argc, char* argv[]) {
void FirmwareUtility::OutputSignedImage(void) {
if (image_) {
- if (!WriteFirmwareImage(out_file_.c_str(), image_, is_only_vblock_)) {
+ if (!WriteFirmwareImage(out_file_.c_str(), image_,
+ is_only_vblock_,
+ is_subkey_out_)) {
cerr << "Couldn't write verified boot image to file "
<< out_file_ <<".\n";
}
@@ -196,27 +217,106 @@ void FirmwareUtility::DescribeSignedImage(void) {
bool FirmwareUtility::GenerateSignedImage(void) {
uint64_t firmware_sign_key_pub_len;
- image_ = FirmwareImageNew();
+ image_ = FirmwareImageNew();
Memcpy(image_->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE);
- // Copy pre-processed public signing key.
- image_->firmware_sign_algorithm = (uint16_t) firmware_sign_algorithm_;
- image_->firmware_sign_key = BufferFromFile(
- firmware_key_pub_file_.c_str(),
- &firmware_sign_key_pub_len);
- if (!image_->firmware_sign_key)
- return false;
- image_->firmware_key_version = firmware_key_version_;
+ if (subkey_in_file_.empty()) {
+ // We muse generate the firmware key signature header (subkey header)
+ // ourselves.
+ // Copy pre-processed public signing key.
+ image_->firmware_sign_algorithm = (uint16_t) firmware_sign_algorithm_;
+ image_->firmware_sign_key = BufferFromFile(
+ firmware_key_pub_file_.c_str(),
+ &firmware_sign_key_pub_len);
+ if (!image_->firmware_sign_key)
+ return false;
+ image_->firmware_key_version = firmware_key_version_;
+
+ // Update header length.
+ image_->header_len = GetFirmwareHeaderLen(image_);
- // Update header length.
- image_->header_len = GetFirmwareHeaderLen(image_);
+ // Calculate header checksum.
+ CalculateFirmwareHeaderChecksum(image_, image_->header_checksum);
- // 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";
+ return false;
+ }
+ } else {
+ // Use existing subkey header.
+ MemcpyState st;
+ uint8_t* subkey_header_buf = NULL;
+ uint64_t subkey_len;
+ int header_len;
+ int firmware_sign_key_len;
+ uint8_t header_checksum[FIELD_LEN(header_checksum)];
+
+ subkey_header_buf = BufferFromFile(subkey_in_file_.c_str(), &subkey_len);
+ if (!subkey_header_buf) {
+ cerr << "Couldn't read subkey header from file %s\n"
+ << subkey_in_file_.c_str();
+ return false;
+ }
+ st.remaining_len = subkey_len;
+ st.remaining_buf = subkey_header_buf;
+ st.overrun = 0;
+
+ // TODO(gauravsh): This is basically the same code as the first half of
+ // of ReadFirmwareImage(). Refactor to eliminate code duplication.
+
+ StatefulMemcpy(&st, &image_->header_len, FIELD_LEN(header_len));
+ StatefulMemcpy(&st, &image_->firmware_sign_algorithm,
+ FIELD_LEN(firmware_sign_algorithm));
+
+ // Valid Algorithm?
+ if (image_->firmware_sign_algorithm >= kNumAlgorithms) {
+ Free(subkey_header_buf);
+ return NULL;
+ }
+
+ // Compute size of pre-processed RSA public key and signature.
+ firmware_sign_key_len = RSAProcessedKeySize(image_->firmware_sign_algorithm);
+
+ // Check whether the header length is correct.
+ header_len = GetFirmwareHeaderLen(image_);
+ if (header_len != image_->header_len) {
+ debug("Header length mismatch. Got: %d Expected: %d\n",
+ image_->header_len, header_len);
+ Free(subkey_header_buf);
+ return NULL;
+ }
+
+ // Read pre-processed public half of the sign key.
+ StatefulMemcpy(&st, &image_->firmware_key_version,
+ FIELD_LEN(firmware_key_version));
+ image_->firmware_sign_key = (uint8_t*) Malloc(firmware_sign_key_len);
+ StatefulMemcpy(&st, image_->firmware_sign_key, firmware_sign_key_len);
+ StatefulMemcpy(&st, image_->header_checksum, FIELD_LEN(header_checksum));
+
+ // Check whether the header checksum matches.
+ CalculateFirmwareHeaderChecksum(image_, header_checksum);
+ if (SafeMemcmp(header_checksum, image_->header_checksum,
+ FIELD_LEN(header_checksum))) {
+ debug("Invalid firmware header checksum!\n");
+ Free(subkey_header_buf);
+ return NULL;
+ }
+
+ // Read key signature.
+ StatefulMemcpy(&st, image_->firmware_key_signature,
+ FIELD_LEN(firmware_key_signature));
+
+ 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;
// TODO(gauravsh): Populate this with the right bytes once we decide
// what goes into the preamble.
Memset(image_->preamble, 'P', FIRMWARE_PREAMBLE_SIZE);
@@ -224,11 +324,6 @@ bool FirmwareUtility::GenerateSignedImage(void) {
&image_->firmware_len);
if (!image_->firmware_data)
return false;
- // Generate and add the signatures.
- if (!AddFirmwareKeySignature(image_, root_key_file_.c_str())) {
- cerr << "Couldn't write key signature to verified boot image.\n";
- return false;
- }
if (!AddFirmwareSignature(image_, firmware_key_file_.c_str())) {
cerr << "Couldn't write firmware signature to verified boot image.\n";
@@ -279,30 +374,34 @@ bool FirmwareUtility::CheckOptions(void) {
}
// Required options for --generate.
if (is_generate_) {
- if (root_key_file_.empty()) {
- cerr << "No root key file specified." << "\n";
- return false;
- }
- if (firmware_version_ <= 0 || firmware_version_ > UINT16_MAX) {
- cerr << "Invalid or no firmware version specified." << "\n";
- return false;
+ if (subkey_in_file_.empty()) {
+ // Root key, kernel signing public key, and firmware signing
+ // algorithm are required to generate the key signature header.
+ if (root_key_file_.empty()) {
+ cerr << "No root key file specified." << "\n";
+ return false;
+ }
+ if (firmware_key_pub_file_.empty()) {
+ cerr << "No pre-processed public signing key file specified." << "\n";
+ return false;
+ }
+ if (firmware_key_version_ <= 0 || firmware_key_version_ > UINT16_MAX) {
+ cerr << "Invalid or no key version specified." << "\n";
+ return false;
+ }
+ if (firmware_sign_algorithm_ < 0 ||
+ firmware_sign_algorithm_ >= kNumAlgorithms) {
+ cerr << "Invalid or no signing key algorithm specified." << "\n";
+ return false;
+ }
}
if (firmware_key_file_.empty()) {
cerr << "No signing key file specified." << "\n";
- return false;
- }
- if (firmware_key_pub_file_.empty()) {
- cerr << "No pre-processed public signing key file specified." << "\n";
- return false;
- }
- if (firmware_key_version_ <= 0 || firmware_key_version_ > UINT16_MAX) {
- cerr << "Invalid or no key version specified." << "\n";
- return false;
- }
- if (firmware_sign_algorithm_ < 0 ||
- firmware_sign_algorithm_ >= kNumAlgorithms) {
- cerr << "Invalid or no signing key algorithm specified." << "\n";
- return false;
+ return false;
+ }
+ if (firmware_version_ <= 0 || firmware_version_ > UINT16_MAX) {
+ cerr << "Invalid or no firmware version specified." << "\n";
+ return false;
}
if (out_file_.empty()) {
cerr <<"No output file specified." << "\n";
@@ -312,7 +411,6 @@ bool FirmwareUtility::CheckOptions(void) {
return true;
}
-
} // namespace vboot_reference
int main(int argc, char* argv[]) {
diff --git a/utility/include/firmware_utility.h b/utility/include/firmware_utility.h
index 9e668e0a..663536a2 100644
--- a/utility/include/firmware_utility.h
+++ b/utility/include/firmware_utility.h
@@ -54,17 +54,19 @@ class FirmwareUtility {
RSAPublicKey* root_key_pub_;
std::string root_key_file_;
std::string root_key_pub_file_;
- int firmware_version_;
std::string firmware_key_file_;
std::string firmware_key_pub_file_;
- int firmware_key_version_;
- int firmware_sign_algorithm_;
+ std::string subkey_in_file_; // Existing key signature header.
std::string in_file_;
std::string out_file_;
+ int firmware_key_version_;
+ int firmware_sign_algorithm_;
+ int firmware_version_;
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?
bool is_only_vblock_; // Should we just output the verification block?
+ bool is_subkey_out_; // Should we just output the subkey header?
};
} // namespace vboot_reference
diff --git a/utility/kernel_utility.cc b/utility/kernel_utility.cc
index edc3eb6c..00922b7e 100644
--- a/utility/kernel_utility.cc
+++ b/utility/kernel_utility.cc
@@ -114,7 +114,7 @@ bool KernelUtility::ParseCmdLineOptions(int argc, char* argv[]) {
OPT_VMLINUZ,
OPT_CONFIG,
OPT_PADDING,
- OPT_SUBKEY,
+ OPT_SUBKEY_OUT,
};
static struct option long_options[] = {
{"firmware_key", 1, 0, OPT_FIRMWARE_KEY },
@@ -136,7 +136,7 @@ bool KernelUtility::ParseCmdLineOptions(int argc, char* argv[]) {
{"vmlinuz", 1, 0, OPT_VMLINUZ },
{"config", 1, 0, OPT_CONFIG },
{"padding", 1, 0, OPT_PADDING },
- {"subkey_out", 0, 0, OPT_SUBKEY },
+ {"subkey_out", 0, 0, OPT_SUBKEY_OUT },
{NULL, 0, 0, 0}
};
while ((i = getopt_long(argc, argv, "", long_options, &option_index)) != -1) {
@@ -231,7 +231,7 @@ bool KernelUtility::ParseCmdLineOptions(int argc, char* argv[]) {
return false;
}
break;
- case OPT_SUBKEY:
+ case OPT_SUBKEY_OUT:
is_subkey_out_ = true;
break;
}
@@ -283,7 +283,7 @@ bool KernelUtility::GenerateSignedImage(void) {
// Calculate header checksum.
CalculateKernelHeaderChecksum(image_, image_->header_checksum);
- // Generate and add the signatures.
+ // Generate and add the key signatures.
if (!AddKernelKeySignature(image_, firmware_key_file_.c_str())) {
cerr << "Couldn't write key signature to verified boot kernel image.\n";
return false;
@@ -318,23 +318,23 @@ bool KernelUtility::GenerateSignedImage(void) {
StatefulMemcpy(&st, &image_->kernel_sign_algorithm,
FIELD_LEN(kernel_sign_algorithm));
- /* Valid Kernel Key signing algorithm. */
+ // Valid Kernel Key signing algorithm.
if (image_->firmware_sign_algorithm >= kNumAlgorithms) {
Free(subkey_header_buf);
return NULL;
}
- /* Valid Kernel Signing Algorithm? */
+ // Valid Kernel Signing Algorithm?
if (image_->kernel_sign_algorithm >= kNumAlgorithms) {
Free(subkey_header_buf);
return NULL;
}
- /* Compute size of pre-processed RSA public keys and signatures. */
+ // Compute size of pre-processed RSA public keys and signatures.
kernel_key_signature_len = siglen_map[image_->firmware_sign_algorithm];
kernel_sign_key_len = RSAProcessedKeySize(image_->kernel_sign_algorithm);
- /* Check whether key header length is correct. */
+ // Check whether key header length is correct.
header_len = GetKernelHeaderLen(image_);
if (header_len != image_->header_len) {
debug("Header length mismatch. Got: %d, Expected: %d\n",
@@ -343,14 +343,14 @@ bool KernelUtility::GenerateSignedImage(void) {
return NULL;
}
- /* Read pre-processed public half of the kernel signing key. */
+ // Read pre-processed public half of the kernel signing key.
StatefulMemcpy(&st, &image_->kernel_key_version,
FIELD_LEN(kernel_key_version));
image_->kernel_sign_key = (uint8_t*) Malloc(kernel_sign_key_len);
StatefulMemcpy(&st, image_->kernel_sign_key, kernel_sign_key_len);
StatefulMemcpy(&st, image_->header_checksum, FIELD_LEN(header_checksum));
- /* Check whether the header checksum matches. */
+ // Check whether the header checksum matches.
CalculateKernelHeaderChecksum(image_, header_checksum);
if (SafeMemcmp(header_checksum, image_->header_checksum,
FIELD_LEN(header_checksum))) {
@@ -359,10 +359,11 @@ bool KernelUtility::GenerateSignedImage(void) {
return NULL;
}
- /* Read key signature. */
+ // Read key signature.
image_->kernel_key_signature = (uint8_t*) Malloc(kernel_key_signature_len);
StatefulMemcpy(&st, image_->kernel_key_signature,
kernel_key_signature_len);
+
Free(subkey_header_buf);
if (st.overrun || st.remaining_len != 0) /* Overrun or underrun. */
return false;
@@ -382,6 +383,7 @@ bool KernelUtility::GenerateSignedImage(void) {
if (!image_->kernel_data)
return false;
+ // Generate and add the preamble and data signatures.
if (!AddKernelSignature(image_, kernel_key_file_.c_str())) {
cerr << "Couldn't write firmware signature to verified boot kernel image.\n";
return false;
diff --git a/vfirmware/firmware_image.c b/vfirmware/firmware_image.c
index ba55d0a1..d16a1fc7 100644
--- a/vfirmware/firmware_image.c
+++ b/vfirmware/firmware_image.c
@@ -259,10 +259,13 @@ uint8_t* GetFirmwareBlob(const FirmwareImage* image, uint64_t* blob_len) {
int WriteFirmwareImage(const char* output_file,
const FirmwareImage* image,
- int is_only_vblock) {
+ int is_only_vblock,
+ int is_subkey_out) {
int fd;
int success = 1;
uint8_t* firmware_blob;
+ uint8_t* subkey_out_buf = NULL;
+ uint8_t* subkey_header = NULL;
uint64_t blob_len;
if (!image)
@@ -271,6 +274,25 @@ int WriteFirmwareImage(const char* output_file,
debug("Couldn't open file for writing.\n");
return 0;
}
+ if (is_subkey_out) {
+ blob_len = GetFirmwareHeaderLen(image) +
+ siglen_map[ROOT_SIGNATURE_ALGORITHM];
+ subkey_out_buf = (uint8_t*) Malloc(blob_len);
+ subkey_header = GetFirmwareHeaderBlob(image);
+ Memcpy(subkey_out_buf, subkey_header, GetFirmwareHeaderLen(image));
+ Memcpy(subkey_out_buf + GetFirmwareHeaderLen(image),
+ image->firmware_key_signature,
+ siglen_map[ROOT_SIGNATURE_ALGORITHM]);
+ if (blob_len != write(fd, subkey_out_buf, blob_len)) {
+ debug("Couldn't write kernel subkey header to file: %s\n",
+ output_file);
+ success = 0;
+ }
+ Free(subkey_header);
+ Free(subkey_out_buf);
+ close(fd);
+ return success;
+ }
firmware_blob = GetFirmwareBlob(image, &blob_len);
if (!firmware_blob) {
diff --git a/vfirmware/include/firmware_image.h b/vfirmware/include/firmware_image.h
index fcd66f77..7bf53604 100644
--- a/vfirmware/include/firmware_image.h
+++ b/vfirmware/include/firmware_image.h
@@ -56,13 +56,17 @@ uint8_t* GetFirmwareBlob(const FirmwareImage* image, uint64_t* blob_len);
/* Write firmware data from [image] into a file named [input_file].
*
- * If [is_just_vblock] is 1, only the verification block (excluding the
- * actual firmware_data) is written.
+ * If [is_just_vblock] is non-zero, only the verification block (excluding the
+ * actual firmware_data) is output.
+ * if [is_subkey_out] is non-zero, only the firmware key verification (subkey)
+ * header is output.
+ *
* Return 1 on success, 0 on failure.
*/
int WriteFirmwareImage(const char* input_file,
const FirmwareImage* image,
- int is_only_vblock);
+ int is_only_vblock,
+ int is_subkey_out);
/* Pretty print the contents of [image]. Only headers and metadata information
* is printed.
diff --git a/vkernel/include/kernel_image.h b/vkernel/include/kernel_image.h
index 73ed3a56..09343ea1 100644
--- a/vkernel/include/kernel_image.h
+++ b/vkernel/include/kernel_image.h
@@ -56,7 +56,11 @@ uint8_t* GetKernelBlob(const KernelImage* image, uint64_t* blob_len);
/* Write kernel data from [image] to a file named [input_file].
- * If [is_only_vblock] is non-zero, only the verification block is output.
+ *
+ * If [is_only_vblock] is non-zero, only the verification block (excluding the
+ * actual kernel data) is output.
+ * If [is_subkey_out] is non-zero, only the kernel key verification (subkey)
+ * header is output.
*
* Return 1 on success, 0 on error.
*/