Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(481)

Side by Side Diff: src/platform/vboot_reference/utility/kernel_utility.cc

Issue 2283005: Modifying the kernel_utility tool to create our magic blob. (Closed) Base URL: ssh://git@chromiumos-git/chromeos
Patch Set: respond to feedback Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 padding_(0),
38 kernel_len_(0), 39 kernel_len_(0),
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 } 44 }
44 45
45 KernelUtility::~KernelUtility() { 46 KernelUtility::~KernelUtility() {
46 RSAPublicKeyFree(firmware_key_pub_); 47 RSAPublicKeyFree(firmware_key_pub_);
47 KernelImageFree(image_); 48 KernelImageFree(image_);
48 } 49 }
49 50
50 void KernelUtility::PrintUsage(void) { 51 void KernelUtility::PrintUsage(void) {
51 cerr << 52 cerr << "\n"
52 "Utility to generate/verify/describe a verified boot kernel image\n\n" 53 "Utility to generate/verify/describe a verified boot kernel image\n"
53 "Usage: kernel_utility <--generate|--verify|--describe> [OPTIONS]\n\n" 54 "\n"
55 "Usage: kernel_utility <--generate|--verify|--describe> [OPTIONS]\n"
56 "\n"
57 "For \"--describe\", the required OPTIONS are:\n"
58 " --in <infile>\t\t\t\tSigned boot image to describe.\n"
59 "\n"
54 "For \"--verify\", required OPTIONS are:\n" 60 "For \"--verify\", required OPTIONS are:\n"
55 "--in <infile>\t\t\tVerified boot kernel image to verify.\n" 61 " --in <infile>\t\t\t\tSigned boot image to verify.\n"
56 "--firmware_key_pub <pubkeyfile>\tPre-processed public firmware key " 62 " --firmware_key_pub <pubkeyfile>\tPre-processed public firmware key\n"
57 "to use for verification.\n\n" 63 "\n"
58 "For \"--generate\", required OPTIONS are:\n" 64 "For \"--generate\", required OPTIONS are:\n"
59 "--firmware_key <privkeyfile>\tPrivate firmware signing key file\n" 65 " --firmware_key <privkeyfile>\t\tPrivate firmware signing key file\n"
60 "--kernel_key <privkeyfile>\tPrivate kernel signing key file\n" 66 " --kernel_key <privkeyfile>\t\tPrivate kernel signing key file\n"
61 "--kernel_key_pub <pubkeyfile>\tPre-processed public kernel signing" 67 " --kernel_key_pub <pubkeyfile>\t\tPre-processed public kernel signing"
62 " key\n" 68 " key\n"
63 "--firmware_sign_algorithm <algoid>\tSigning algorithm used by " 69 " --firmware_sign_algorithm <algoid>\tSigning algorithm for firmware\n"
64 "the firmware\n" 70 " --kernel_sign_algorithm <algoid>\tSigning algorithm for kernel\n"
65 "--kernel_sign_algorithm <algoid>\tSigning algorithm to use for kernel\n" 71 " --kernel_key_version <number>\t\tKernel signing key version number\n"
66 "--kernel_key_version <version#>\tKernel signing Key Version#\n" 72 " --kernel_version <number>\t\tKernel Version number\n"
67 "--kernel_version <version#>\tKernel Version#\n" 73 " --config <file>\t\t\tEmbedded kernel command-line parameters\n"
68 "--in <infile>\t\tKernel Image to sign\n" 74 " --bootloader <file>\t\t\tEmbedded bootloader stub\n"
69 "--out <outfile>\t\tOutput file for verified boot Kernel image\n\n" 75 " --vmlinuz <file>\t\t\tEmbedded kernel image\n"
70 "Optional arguments for \"--generate\" include:\n" 76 " --out <outfile>\t\t\tOutput file for verified boot image\n"
71 "--vblock\t\t\tJust output the verification block\n\n" 77 "\n"
78 "Optional arguments for \"--generate\" are:\n"
79 " --vblock\t\t\t\tJust output the verification block\n"
80 " --padding\t\t\t\tPad the header to this size\n"
81 "\n"
72 "<algoid> (for --*_sign_algorithm) is one of the following:\n"; 82 "<algoid> (for --*_sign_algorithm) is one of the following:\n";
73 for (int i = 0; i < kNumAlgorithms; i++) { 83 for (int i = 0; i < kNumAlgorithms; i++) {
74 cerr << i << " for " << algo_strings[i] << "\n"; 84 cerr << " " << i << " for " << algo_strings[i] << "\n";
75 } 85 }
76 cerr << "\n\n"; 86 cerr << "\n\n";
77 } 87 }
78 88
79 bool KernelUtility::ParseCmdLineOptions(int argc, char* argv[]) { 89 bool KernelUtility::ParseCmdLineOptions(int argc, char* argv[]) {
80 int option_index, i; 90 int option_index, i;
91 char *e = 0;
81 enum { 92 enum {
82 OPT_FIRMWARE_KEY = 1000, 93 OPT_FIRMWARE_KEY = 1000,
83 OPT_FIRMWARE_KEY_PUB, 94 OPT_FIRMWARE_KEY_PUB,
84 OPT_KERNEL_KEY, 95 OPT_KERNEL_KEY,
85 OPT_KERNEL_KEY_PUB, 96 OPT_KERNEL_KEY_PUB,
86 OPT_FIRMWARE_SIGN_ALGORITHM, 97 OPT_FIRMWARE_SIGN_ALGORITHM,
87 OPT_KERNEL_SIGN_ALGORITHM, 98 OPT_KERNEL_SIGN_ALGORITHM,
88 OPT_KERNEL_KEY_VERSION, 99 OPT_KERNEL_KEY_VERSION,
89 OPT_KERNEL_VERSION, 100 OPT_KERNEL_VERSION,
90 OPT_IN, 101 OPT_IN,
91 OPT_OUT, 102 OPT_OUT,
92 OPT_GENERATE, 103 OPT_GENERATE,
93 OPT_VERIFY, 104 OPT_VERIFY,
94 OPT_DESCRIBE, 105 OPT_DESCRIBE,
95 OPT_VBLOCK, 106 OPT_VBLOCK,
107 OPT_BOOTLOADER,
108 OPT_VMLINUZ,
109 OPT_CONFIG,
110 OPT_PADDING,
96 }; 111 };
97 static struct option long_options[] = { 112 static struct option long_options[] = {
98 {"firmware_key", 1, 0, OPT_FIRMWARE_KEY }, 113 {"firmware_key", 1, 0, OPT_FIRMWARE_KEY },
99 {"firmware_key_pub", 1, 0, OPT_FIRMWARE_KEY_PUB }, 114 {"firmware_key_pub", 1, 0, OPT_FIRMWARE_KEY_PUB },
100 {"kernel_key", 1, 0, OPT_KERNEL_KEY }, 115 {"kernel_key", 1, 0, OPT_KERNEL_KEY },
101 {"kernel_key_pub", 1, 0, OPT_KERNEL_KEY_PUB }, 116 {"kernel_key_pub", 1, 0, OPT_KERNEL_KEY_PUB },
102 {"firmware_sign_algorithm", 1, 0, OPT_FIRMWARE_SIGN_ALGORITHM }, 117 {"firmware_sign_algorithm", 1, 0, OPT_FIRMWARE_SIGN_ALGORITHM },
103 {"kernel_sign_algorithm", 1, 0, OPT_KERNEL_SIGN_ALGORITHM }, 118 {"kernel_sign_algorithm", 1, 0, OPT_KERNEL_SIGN_ALGORITHM },
104 {"kernel_key_version", 1, 0, OPT_KERNEL_KEY_VERSION }, 119 {"kernel_key_version", 1, 0, OPT_KERNEL_KEY_VERSION },
105 {"kernel_version", 1, 0, OPT_KERNEL_VERSION }, 120 {"kernel_version", 1, 0, OPT_KERNEL_VERSION },
106 {"in", 1, 0, OPT_IN }, 121 {"in", 1, 0, OPT_IN },
107 {"out", 1, 0, OPT_OUT }, 122 {"out", 1, 0, OPT_OUT },
108 {"generate", 0, 0, OPT_GENERATE }, 123 {"generate", 0, 0, OPT_GENERATE },
109 {"verify", 0, 0, OPT_VERIFY }, 124 {"verify", 0, 0, OPT_VERIFY },
110 {"describe", 0, 0, OPT_DESCRIBE }, 125 {"describe", 0, 0, OPT_DESCRIBE },
111 {"vblock", 0, 0, OPT_VBLOCK }, 126 {"vblock", 0, 0, OPT_VBLOCK },
127 {"bootloader", 1, 0, OPT_BOOTLOADER },
128 {"vmlinuz", 1, 0, OPT_VMLINUZ },
129 {"config", 1, 0, OPT_CONFIG },
130 {"padding", 1, 0, OPT_PADDING },
112 {NULL, 0, 0, 0} 131 {NULL, 0, 0, 0}
113 }; 132 };
114 while ((i = getopt_long(argc, argv, "", long_options, &option_index)) != -1) { 133 while ((i = getopt_long(argc, argv, "", long_options, &option_index)) != -1) {
115 switch (i) { 134 switch (i) {
116 case '?': 135 case '?':
117 return false; 136 return false;
118 break; 137 break;
119 case OPT_FIRMWARE_KEY: 138 case OPT_FIRMWARE_KEY:
120 firmware_key_file_ = optarg; 139 firmware_key_file_ = optarg;
121 break; 140 break;
122 case OPT_FIRMWARE_KEY_PUB: 141 case OPT_FIRMWARE_KEY_PUB:
123 firmware_key_pub_file_ = optarg; 142 firmware_key_pub_file_ = optarg;
124 break; 143 break;
125 case OPT_KERNEL_KEY: 144 case OPT_KERNEL_KEY:
126 kernel_key_file_ = optarg; 145 kernel_key_file_ = optarg;
127 break; 146 break;
128 case OPT_KERNEL_KEY_PUB: 147 case OPT_KERNEL_KEY_PUB:
129 kernel_key_pub_file_ = optarg; 148 kernel_key_pub_file_ = optarg;
130 break; 149 break;
131 case OPT_FIRMWARE_SIGN_ALGORITHM: 150 case OPT_FIRMWARE_SIGN_ALGORITHM:
132 errno = 0; // strtol() returns an error via errno 151 firmware_sign_algorithm_ = strtol(optarg, &e, 0);
133 firmware_sign_algorithm_ = strtol(optarg, 152 if (!*optarg || (e && *e)) {
134 reinterpret_cast<char**>(NULL), 10); 153 cerr << "Invalid argument to --"
135 if (errno) 154 << long_options[option_index].name
155 << ": " << optarg << "\n";
136 return false; 156 return false;
157 }
137 break; 158 break;
138 case OPT_KERNEL_SIGN_ALGORITHM: 159 case OPT_KERNEL_SIGN_ALGORITHM:
139 errno = 0; 160 errno = 0;
140 kernel_sign_algorithm_ = strtol(optarg, 161 kernel_sign_algorithm_ = strtol(optarg, &e, 0);
141 reinterpret_cast<char**>(NULL), 10); 162 if (!*optarg || (e && *e)) {
142 if (errno) 163 cerr << "Invalid argument to --"
164 << long_options[option_index].name
165 << ": " << optarg << "\n";
143 return false; 166 return false;
167 }
144 break; 168 break;
145 case OPT_KERNEL_KEY_VERSION: 169 case OPT_KERNEL_KEY_VERSION:
146 errno = 0; 170 errno = 0;
147 kernel_key_version_ = strtol(optarg, 171 kernel_key_version_ = strtol(optarg, &e, 0);
148 reinterpret_cast<char**>(NULL), 10); 172 if (!*optarg || (e && *e)) {
149 if (errno) 173 cerr << "Invalid argument to --"
174 << long_options[option_index].name
175 << ": " << optarg << "\n";
150 return false; 176 return false;
151 break; 177 }
178 break;
152 case OPT_KERNEL_VERSION: 179 case OPT_KERNEL_VERSION:
153 errno = 0; 180 errno = 0;
154 kernel_version_ = strtol(optarg, 181 kernel_version_ = strtol(optarg, &e, 0);
155 reinterpret_cast<char**>(NULL), 10); 182 if (!*optarg || (e && *e)) {
156 if (errno) 183 cerr << "Invalid argument to --"
184 << long_options[option_index].name
185 << ": " << optarg << "\n";
157 return false; 186 return false;
187 }
158 break; 188 break;
159 case OPT_IN: 189 case OPT_IN:
160 in_file_ = optarg; 190 in_file_ = optarg;
161 break; 191 break;
162 case OPT_OUT: 192 case OPT_OUT:
163 out_file_ = optarg; 193 out_file_ = optarg;
164 break; 194 break;
165 case OPT_GENERATE: 195 case OPT_GENERATE:
166 is_generate_ = true; 196 is_generate_ = true;
167 break; 197 break;
168 case OPT_VERIFY: 198 case OPT_VERIFY:
169 is_verify_ = true; 199 is_verify_ = true;
170 break; 200 break;
171 case OPT_DESCRIBE: 201 case OPT_DESCRIBE:
172 is_describe_ = true; 202 is_describe_ = true;
173 break; 203 break;
174 case OPT_VBLOCK: 204 case OPT_VBLOCK:
175 is_only_vblock_ = true; 205 is_only_vblock_ = true;
176 break; 206 break;
207 case OPT_BOOTLOADER:
208 bootloader_file_ = optarg;
209 break;
210 case OPT_VMLINUZ:
211 vmlinuz_file_ = optarg;
212 break;
213 case OPT_CONFIG:
214 config_file_ = optarg;
215 break;
216 case OPT_PADDING:
217 padding_ = strtol(optarg, &e, 0);
218 if (!*optarg || (e && *e)) {
219 cerr << "Invalid argument to --"
220 << long_options[option_index].name
221 << ": " << optarg << "\n";
222 return false;
223 }
224 break;
177 } 225 }
178 } 226 }
179 return CheckOptions(); 227 return CheckOptions();
180 } 228 }
181 229
182 void KernelUtility::OutputSignedImage(void) { 230 void KernelUtility::OutputSignedImage(void) {
183 if (image_) { 231 if (image_) {
184 if (!WriteKernelImage(out_file_.c_str(), image_, is_only_vblock_)) { 232 if (!WriteKernelImage(out_file_.c_str(), image_, is_only_vblock_)) {
185 cerr << "Couldn't write verified boot kernel image to file " 233 cerr << "Couldn't write verified boot kernel image to file "
186 << out_file_ <<".\n"; 234 << out_file_ <<".\n";
(...skipping 11 matching lines...) Expand all
198 } 246 }
199 247
200 bool KernelUtility::GenerateSignedImage(void) { 248 bool KernelUtility::GenerateSignedImage(void) {
201 uint64_t kernel_key_pub_len; 249 uint64_t kernel_key_pub_len;
202 image_ = KernelImageNew(); 250 image_ = KernelImageNew();
203 251
204 Memcpy(image_->magic, KERNEL_MAGIC, KERNEL_MAGIC_SIZE); 252 Memcpy(image_->magic, KERNEL_MAGIC, KERNEL_MAGIC_SIZE);
205 253
206 // TODO(gauravsh): make this a command line option. 254 // TODO(gauravsh): make this a command line option.
207 image_->header_version = 1; 255 image_->header_version = 1;
256 if (padding_)
257 image_->padded_header_size = padding_;
208 image_->firmware_sign_algorithm = (uint16_t) firmware_sign_algorithm_; 258 image_->firmware_sign_algorithm = (uint16_t) firmware_sign_algorithm_;
209 // Copy pre-processed public signing key. 259 // Copy pre-processed public signing key.
210 image_->kernel_sign_algorithm = (uint16_t) kernel_sign_algorithm_; 260 image_->kernel_sign_algorithm = (uint16_t) kernel_sign_algorithm_;
211 image_->kernel_sign_key = BufferFromFile(kernel_key_pub_file_.c_str(), 261 image_->kernel_sign_key = BufferFromFile(kernel_key_pub_file_.c_str(),
212 &kernel_key_pub_len); 262 &kernel_key_pub_len);
213 if (!image_->kernel_sign_key) 263 if (!image_->kernel_sign_key)
214 return false; 264 return false;
215 image_->kernel_key_version = kernel_key_version_; 265 image_->kernel_key_version = kernel_key_version_;
216 266
217 // Update header length. 267 // Update header length.
218 image_->header_len = GetKernelHeaderLen(image_); 268 image_->header_len = GetKernelHeaderLen(image_);
219 269
220 // Calculate header checksum. 270 // Calculate header checksum.
221 CalculateKernelHeaderChecksum(image_, image_->header_checksum); 271 CalculateKernelHeaderChecksum(image_, image_->header_checksum);
222 272
223 image_->kernel_version = kernel_version_; 273 image_->kernel_version = kernel_version_;
224 image_->kernel_data = BufferFromFile(in_file_.c_str(), 274
225 &image_->kernel_len); 275 image_->kernel_data = GenerateKernelBlob(vmlinuz_file_.c_str(),
276 config_file_.c_str(),
277 bootloader_file_.c_str(),
278 &image_->kernel_len,
279 &image_->bootloader_offset,
280 &image_->bootloader_size);
226 if (!image_->kernel_data) 281 if (!image_->kernel_data)
227 return false; 282 return false;
228 // Generate and add the signatures. 283 // Generate and add the signatures.
229 if (!AddKernelKeySignature(image_, firmware_key_file_.c_str())) { 284 if (!AddKernelKeySignature(image_, firmware_key_file_.c_str())) {
230 cerr << "Couldn't write key signature to verified boot kernel image.\n"; 285 cerr << "Couldn't write key signature to verified boot kernel image.\n";
231 return false; 286 return false;
232 } 287 }
233 288
234 if (!AddKernelSignature(image_, kernel_key_file_.c_str())) { 289 if (!AddKernelSignature(image_, kernel_key_file_.c_str())) {
235 cerr << "Couldn't write firmware signature to verified boot kernel image.\n" ; 290 cerr << "Couldn't write firmware signature to verified boot kernel image.\n" ;
(...skipping 25 matching lines...) Expand all
261 bool KernelUtility::CheckOptions(void) { 316 bool KernelUtility::CheckOptions(void) {
262 // Ensure that only one of --{describe|generate|verify} is set. 317 // Ensure that only one of --{describe|generate|verify} is set.
263 if (!((is_describe_ && !is_generate_ && !is_verify_) || 318 if (!((is_describe_ && !is_generate_ && !is_verify_) ||
264 (!is_describe_ && is_generate_ && !is_verify_) || 319 (!is_describe_ && is_generate_ && !is_verify_) ||
265 (!is_describe_ && !is_generate_ && is_verify_))) { 320 (!is_describe_ && !is_generate_ && is_verify_))) {
266 cerr << "One (and only one) of --describe, --generate or --verify " 321 cerr << "One (and only one) of --describe, --generate or --verify "
267 << "must be specified.\n"; 322 << "must be specified.\n";
268 return false; 323 return false;
269 } 324 }
270 // Common required options. 325 // Common required options.
271 if (in_file_.empty()) { 326 // Required options for --describe.
272 cerr << "No input file specified.\n"; 327 if (is_describe_) {
273 return false; 328 if (in_file_.empty()) {
329 cerr << "No input file specified.\n";
330 return false;
331 }
274 } 332 }
275 // Required options for --verify. 333 // Required options for --verify.
276 if (is_verify_ && firmware_key_pub_file_.empty()) { 334 if (is_verify_) {
277 cerr << "No pre-processed public firmware key file specified.\n"; 335 if (firmware_key_pub_file_.empty()) {
278 return false; 336 cerr << "No pre-processed public firmware key file specified.\n";
337 return false;
338 }
339 if (in_file_.empty()) {
340 cerr << "No input file specified.\n";
341 return false;
342 }
279 } 343 }
280 // Required options for --generate. 344 // Required options for --generate.
281 if (is_generate_) { 345 if (is_generate_) {
282 if (firmware_key_file_.empty()) { 346 if (firmware_key_file_.empty()) {
283 cerr << "No firmware key file specified.\n"; 347 cerr << "No firmware key file specified.\n";
284 return false; 348 return false;
285 } 349 }
286 if (kernel_key_file_.empty()) { 350 if (kernel_key_file_.empty()) {
287 cerr << "No kernel key file specified.\n"; 351 cerr << "No kernel key file specified.\n";
288 return false; 352 return false;
(...skipping 17 matching lines...) Expand all
306 return false; 370 return false;
307 } 371 }
308 if (kernel_version_ <=0 || kernel_version_ > UINT16_MAX) { 372 if (kernel_version_ <=0 || kernel_version_ > UINT16_MAX) {
309 cerr << "Invalid or no kernel version specified.\n"; 373 cerr << "Invalid or no kernel version specified.\n";
310 return false; 374 return false;
311 } 375 }
312 if (out_file_.empty()) { 376 if (out_file_.empty()) {
313 cerr <<"No output file specified.\n"; 377 cerr <<"No output file specified.\n";
314 return false; 378 return false;
315 } 379 }
380 if (config_file_.empty()) {
381 cerr << "No config file specified.\n";
382 return false;
383 }
384 if (bootloader_file_.empty()) {
385 cerr << "No bootloader file specified.\n";
386 return false;
387 }
388 if (vmlinuz_file_.empty()) {
389 cerr << "No vmlinuz file specified.\n";
390 return false;
391 }
316 } 392 }
317 return true; 393 return true;
318 } 394 }
319 395
320 } // namespace vboot_reference 396 } // namespace vboot_reference
321 397
322 int main(int argc, char* argv[]) { 398 int main(int argc, char* argv[]) {
323 vboot_reference::KernelUtility ku; 399 vboot_reference::KernelUtility ku;
324 if (!ku.ParseCmdLineOptions(argc, argv)) { 400 if (!ku.ParseCmdLineOptions(argc, argv)) {
325 ku.PrintUsage(); 401 ku.PrintUsage();
326 return -1; 402 return -1;
327 } 403 }
328 if (ku.is_describe()) { 404 if (ku.is_describe()) {
329 ku.DescribeSignedImage(); 405 ku.DescribeSignedImage();
330 } 406 }
331 else if (ku.is_generate()) { 407 else if (ku.is_generate()) {
332 if (!ku.GenerateSignedImage()) 408 if (!ku.GenerateSignedImage())
333 return -1; 409 return -1;
334 ku.OutputSignedImage(); 410 ku.OutputSignedImage();
335 } 411 }
336 else if (ku.is_verify()) { 412 else if (ku.is_verify()) {
337 cerr << "Verification "; 413 cerr << "Verification ";
338 if (ku.VerifySignedImage()) 414 if (ku.VerifySignedImage())
339 cerr << "SUCCESS.\n"; 415 cerr << "SUCCESS.\n";
340 else 416 else
341 cerr << "FAILURE.\n"; 417 cerr << "FAILURE.\n";
342 } 418 }
343 return 0; 419 return 0;
344 } 420 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698