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 |