| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // Utility for manipulating verified boot kernel images. | 5 // Utility for manipulating verified boot kernel images. |
| 6 // | 6 // |
| 7 | 7 |
| 8 #include "kernel_utility.h" | 8 #include "kernel_utility.h" |
| 9 | 9 |
| 10 #include <errno.h> | 10 #include <errno.h> |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 | 28 |
| 29 namespace vboot_reference { | 29 namespace vboot_reference { |
| 30 | 30 |
| 31 KernelUtility::KernelUtility(): image_(NULL), | 31 KernelUtility::KernelUtility(): image_(NULL), |
| 32 firmware_key_pub_(NULL), | 32 firmware_key_pub_(NULL), |
| 33 header_version_(1), | 33 header_version_(1), |
| 34 firmware_sign_algorithm_(-1), | 34 firmware_sign_algorithm_(-1), |
| 35 kernel_sign_algorithm_(-1), | 35 kernel_sign_algorithm_(-1), |
| 36 kernel_key_version_(-1), | 36 kernel_key_version_(-1), |
| 37 kernel_version_(-1), | 37 kernel_version_(-1), |
| 38 cmd_line_(NULL), | 38 kernel_len_(0), |
| 39 kernel_config_(NULL), |
| 39 is_generate_(false), | 40 is_generate_(false), |
| 40 is_verify_(false), | 41 is_verify_(false), |
| 41 is_describe_(false), | 42 is_describe_(false), |
| 42 is_only_vblock_(false) { | 43 is_only_vblock_(false) { |
| 43 // Populate kernel config options with defaults. | |
| 44 options_.version[0] = 1; | |
| 45 options_.version[1] = 0; | |
| 46 options_.kernel_len = 0; | |
| 47 options_.kernel_load_addr = 0; | |
| 48 options_.kernel_entry_addr = 0; | |
| 49 } | 44 } |
| 50 | 45 |
| 51 KernelUtility::~KernelUtility() { | 46 KernelUtility::~KernelUtility() { |
| 52 Free(cmd_line_); | 47 Free(kernel_config_); |
| 53 RSAPublicKeyFree(firmware_key_pub_); | 48 RSAPublicKeyFree(firmware_key_pub_); |
| 54 KernelImageFree(image_); | 49 KernelImageFree(image_); |
| 55 } | 50 } |
| 56 | 51 |
| 57 void KernelUtility::PrintUsage(void) { | 52 void KernelUtility::PrintUsage(void) { |
| 58 cerr << | 53 cerr << |
| 59 "Utility to generate/verify/describe a verified boot kernel image\n\n" | 54 "Utility to generate/verify/describe a verified boot kernel image\n\n" |
| 60 "Usage: kernel_utility <--generate|--verify|--describe> [OPTIONS]\n\n" | 55 "Usage: kernel_utility <--generate|--verify|--describe> [OPTIONS]\n\n" |
| 61 "For \"--verify\", required OPTIONS are:\n" | 56 "For \"--verify\", required OPTIONS are:\n" |
| 62 "--in <infile>\t\t\tVerified boot kernel image to verify.\n" | 57 "--in <infile>\t\t\tVerified boot kernel image to verify.\n" |
| 63 "--firmware_key_pub <pubkeyfile>\tPre-processed public firmware key " | 58 "--firmware_key_pub <pubkeyfile>\tPre-processed public firmware key " |
| 64 "to use for verification.\n\n" | 59 "to use for verification.\n\n" |
| 65 "For \"--generate\", required OPTIONS are:\n" | 60 "For \"--generate\", required OPTIONS are:\n" |
| 66 "--firmware_key <privkeyfile>\tPrivate firmware signing key file\n" | 61 "--firmware_key <privkeyfile>\tPrivate firmware signing key file\n" |
| 67 "--kernel_key <privkeyfile>\tPrivate kernel signing key file\n" | 62 "--kernel_key <privkeyfile>\tPrivate kernel signing key file\n" |
| 68 "--kernel_key_pub <pubkeyfile>\tPre-processed public kernel signing" | 63 "--kernel_key_pub <pubkeyfile>\tPre-processed public kernel signing" |
| 69 " key\n" | 64 " key\n" |
| 70 "--firmware_sign_algorithm <algoid>\tSigning algorithm used by " | 65 "--firmware_sign_algorithm <algoid>\tSigning algorithm used by " |
| 71 "the firmware\n" | 66 "the firmware\n" |
| 72 "--kernel_sign_algorithm <algoid>\tSigning algorithm to use for kernel\n" | 67 "--kernel_sign_algorithm <algoid>\tSigning algorithm to use for kernel\n" |
| 73 "--kernel_key_version <version#>\tKernel signing Key Version#\n" | 68 "--kernel_key_version <version#>\tKernel signing Key Version#\n" |
| 74 "--kernel_version <version#>\tKernel Version#\n" | 69 "--kernel_version <version#>\tKernel Version#\n" |
| 75 "--in <infile>\t\tKernel Image to sign\n" | 70 "--in <infile>\t\tKernel Image to sign\n" |
| 76 "--out <outfile>\t\tOutput file for verified boot Kernel image\n\n" | 71 "--out <outfile>\t\tOutput file for verified boot Kernel image\n\n" |
| 77 "Optional arguments for \"--generate\" include:\n" | 72 "Optional arguments for \"--generate\" include:\n" |
| 78 "--config <file>\t\t\tPopulate contents of kernel config from a file\n" | 73 "--config <file>\t\t\tPopulate contents of kernel config from a file\n" |
| 79 "--config_version <version>\n" | |
| 80 "--kernel_load_addr <addr>\n" | |
| 81 "--kernel_entry_addr <addr>\n" | |
| 82 "--vblock\t\t\tJust output the verification block\n\n" | 74 "--vblock\t\t\tJust output the verification block\n\n" |
| 83 "<algoid> (for --*_sign_algorithm) is one of the following:\n"; | 75 "<algoid> (for --*_sign_algorithm) is one of the following:\n"; |
| 84 for (int i = 0; i < kNumAlgorithms; i++) { | 76 for (int i = 0; i < kNumAlgorithms; i++) { |
| 85 cerr << i << " for " << algo_strings[i] << "\n"; | 77 cerr << i << " for " << algo_strings[i] << "\n"; |
| 86 } | 78 } |
| 87 cerr << "\n\n"; | 79 cerr << "\n\n"; |
| 88 } | 80 } |
| 89 | 81 |
| 90 bool KernelUtility::ParseCmdLineOptions(int argc, char* argv[]) { | 82 bool KernelUtility::ParseCmdLineOptions(int argc, char* argv[]) { |
| 91 int option_index; | 83 int option_index; |
| 92 static struct option long_options[] = { | 84 static struct option long_options[] = { |
| 93 {"firmware_key", 1, 0, 0}, | 85 {"firmware_key", 1, 0, 0}, |
| 94 {"firmware_key_pub", 1, 0, 0}, | 86 {"firmware_key_pub", 1, 0, 0}, |
| 95 {"kernel_key", 1, 0, 0}, | 87 {"kernel_key", 1, 0, 0}, |
| 96 {"kernel_key_pub", 1, 0, 0}, | 88 {"kernel_key_pub", 1, 0, 0}, |
| 97 {"firmware_sign_algorithm", 1, 0, 0}, | 89 {"firmware_sign_algorithm", 1, 0, 0}, |
| 98 {"kernel_sign_algorithm", 1, 0, 0}, | 90 {"kernel_sign_algorithm", 1, 0, 0}, |
| 99 {"kernel_key_version", 1, 0, 0}, | 91 {"kernel_key_version", 1, 0, 0}, |
| 100 {"kernel_version", 1, 0, 0}, | 92 {"kernel_version", 1, 0, 0}, |
| 101 {"in", 1, 0, 0}, | 93 {"in", 1, 0, 0}, |
| 102 {"out", 1, 0, 0}, | 94 {"out", 1, 0, 0}, |
| 103 {"generate", 0, 0, 0}, | 95 {"generate", 0, 0, 0}, |
| 104 {"verify", 0, 0, 0}, | 96 {"verify", 0, 0, 0}, |
| 105 {"config_version", 1, 0, 0}, | |
| 106 {"kernel_load_addr", 1, 0, 0}, | |
| 107 {"kernel_entry_addr", 1, 0, 0}, | |
| 108 {"describe", 0, 0, 0}, | 97 {"describe", 0, 0, 0}, |
| 109 {"config", 1, 0, 0}, | 98 {"config", 1, 0, 0}, |
| 110 {"vblock", 0, 0, 0}, | 99 {"vblock", 0, 0, 0}, |
| 111 {NULL, 0, 0, 0} | 100 {NULL, 0, 0, 0} |
| 112 }; | 101 }; |
| 113 while (1) { | 102 while (1) { |
| 114 int i = getopt_long(argc, argv, "", long_options, &option_index); | 103 int i = getopt_long(argc, argv, "", long_options, &option_index); |
| 115 if (-1 == i) // Done with option processing. | 104 if (-1 == i) // Done with option processing. |
| 116 break; | 105 break; |
| 117 if ('?' == i) // Invalid option found. | 106 if ('?' == i) // Invalid option found. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 break; | 153 break; |
| 165 case 9: // out | 154 case 9: // out |
| 166 out_file_ = optarg; | 155 out_file_ = optarg; |
| 167 break; | 156 break; |
| 168 case 10: // generate | 157 case 10: // generate |
| 169 is_generate_ = true; | 158 is_generate_ = true; |
| 170 break; | 159 break; |
| 171 case 11: // verify | 160 case 11: // verify |
| 172 is_verify_ = true; | 161 is_verify_ = true; |
| 173 break; | 162 break; |
| 174 case 12: // config_version | 163 case 12: // describe |
| 175 if (2 != sscanf(optarg, "%d.%d", &options_.version[0], | |
| 176 &options_.version[1])) | |
| 177 return false; | |
| 178 break; | |
| 179 case 13: // kernel_load_addr | |
| 180 errno = 0; | |
| 181 options_.kernel_load_addr = | |
| 182 strtol(optarg, reinterpret_cast<char**>(NULL), 10); | |
| 183 if (errno) | |
| 184 return false; | |
| 185 break; | |
| 186 case 14: // kernel_entry_addr | |
| 187 errno = 0; | |
| 188 options_.kernel_entry_addr = | |
| 189 strtol(optarg, reinterpret_cast<char**>(NULL), 10); | |
| 190 if (errno) | |
| 191 return false; | |
| 192 break; | |
| 193 case 15: // describe | |
| 194 is_describe_ = true; | 164 is_describe_ = true; |
| 195 break; | 165 break; |
| 196 case 16: // config | 166 case 13: // config |
| 197 config_file_ = optarg; | 167 config_file_ = optarg; |
| 198 break; | 168 break; |
| 199 case 17: // vblock | 169 case 14: // vblock |
| 200 is_only_vblock_ = true; | 170 is_only_vblock_ = true; |
| 201 break; | 171 break; |
| 202 } | 172 } |
| 203 } | 173 } |
| 204 } | 174 } |
| 205 return CheckOptions(); | 175 return CheckOptions(); |
| 206 } | 176 } |
| 207 | 177 |
| 208 void KernelUtility::OutputSignedImage(void) { | 178 void KernelUtility::OutputSignedImage(void) { |
| 209 if (image_) { | 179 if (image_) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 return false; | 211 return false; |
| 242 image_->kernel_key_version = kernel_key_version_; | 212 image_->kernel_key_version = kernel_key_version_; |
| 243 | 213 |
| 244 // Update header length. | 214 // Update header length. |
| 245 image_->header_len = GetKernelHeaderLen(image_); | 215 image_->header_len = GetKernelHeaderLen(image_); |
| 246 | 216 |
| 247 // Calculate header checksum. | 217 // Calculate header checksum. |
| 248 CalculateKernelHeaderChecksum(image_, image_->header_checksum); | 218 CalculateKernelHeaderChecksum(image_, image_->header_checksum); |
| 249 | 219 |
| 250 image_->kernel_version = kernel_version_; | 220 image_->kernel_version = kernel_version_; |
| 251 image_->options.version[0] = options_.version[0]; | |
| 252 image_->options.version[1] = options_.version[1]; | |
| 253 if (!config_file_.empty()) { | 221 if (!config_file_.empty()) { |
| 254 cmd_line_ = BufferFromFile(config_file_.c_str(), &len); | 222 kernel_config_ = BufferFromFile(config_file_.c_str(), &len); |
| 255 if (len >= sizeof(image_->options.cmd_line)) { | 223 if (len >= sizeof(image_->kernel_config)) { |
| 256 cerr << "Input kernel config file is too big!"; | 224 cerr << "Input kernel config file is too big!"; |
| 257 return false; | 225 return false; |
| 258 } | 226 } |
| 259 Memcpy(image_->options.cmd_line, cmd_line_, len); | 227 Memcpy(image_->kernel_config, |
| 228 kernel_config_, len); |
| 260 } else { | 229 } else { |
| 261 Memset(image_->options.cmd_line, 0, sizeof(image_->options.cmd_line)); | 230 Memset(image_->kernel_config, 0, |
| 231 sizeof(image_->kernel_config)); |
| 262 } | 232 } |
| 263 image_->options.kernel_load_addr = options_.kernel_load_addr; | |
| 264 image_->options.kernel_entry_addr = options_.kernel_entry_addr; | |
| 265 image_->kernel_data = BufferFromFile(in_file_.c_str(), | 233 image_->kernel_data = BufferFromFile(in_file_.c_str(), |
| 266 &image_->options.kernel_len); | 234 &image_->kernel_len); |
| 267 if (!image_) | 235 if (!image_) |
| 268 return false; | 236 return false; |
| 269 // Generate and add the signatures. | 237 // Generate and add the signatures. |
| 270 if (!AddKernelKeySignature(image_, firmware_key_file_.c_str())) { | 238 if (!AddKernelKeySignature(image_, firmware_key_file_.c_str())) { |
| 271 cerr << "Couldn't write key signature to verified boot kernel image.\n"; | 239 cerr << "Couldn't write key signature to verified boot kernel image.\n"; |
| 272 return false; | 240 return false; |
| 273 } | 241 } |
| 274 | 242 |
| 275 if (!AddKernelSignature(image_, kernel_key_file_.c_str())) { | 243 if (!AddKernelSignature(image_, kernel_key_file_.c_str())) { |
| 276 cerr << "Couldn't write firmware signature to verified boot kernel image.\n"
; | 244 cerr << "Couldn't write firmware signature to verified boot kernel image.\n"
; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 } | 344 } |
| 377 else if (ku.is_verify()) { | 345 else if (ku.is_verify()) { |
| 378 cerr << "Verification "; | 346 cerr << "Verification "; |
| 379 if (ku.VerifySignedImage()) | 347 if (ku.VerifySignedImage()) |
| 380 cerr << "SUCCESS.\n"; | 348 cerr << "SUCCESS.\n"; |
| 381 else | 349 else |
| 382 cerr << "FAILURE.\n"; | 350 cerr << "FAILURE.\n"; |
| 383 } | 351 } |
| 384 return 0; | 352 return 0; |
| 385 } | 353 } |
| OLD | NEW |