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

Side by Side Diff: src/platform/vboot_reference/utils/firmware_utility.cc

Issue 661353: Vboot Reference: Refactor Code. (Closed)
Patch Set: Review Fixes. Created 10 years, 9 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 firmware images. 5 // Utility for manipulating verified boot firmware images.
6 // 6 //
7 7
8 #include "firmware_utility.h" 8 #include "firmware_utility.h"
9 9
10 #include <errno.h> 10 #include <errno.h>
(...skipping 15 matching lines...) Expand all
26 26
27 extern int errno; 27 extern int errno;
28 using std::cerr; 28 using std::cerr;
29 29
30 namespace vboot_reference { 30 namespace vboot_reference {
31 31
32 FirmwareUtility::FirmwareUtility(): 32 FirmwareUtility::FirmwareUtility():
33 image_(NULL), 33 image_(NULL),
34 root_key_pub_(NULL), 34 root_key_pub_(NULL),
35 firmware_version_(-1), 35 firmware_version_(-1),
36 key_version_(-1), 36 firmware_key_version_(-1),
37 sign_algorithm_(-1), 37 firmware_sign_algorithm_(-1),
38 is_generate_(false), 38 is_generate_(false),
39 is_verify_(false) { 39 is_verify_(false) {
40 } 40 }
41 41
42 FirmwareUtility::~FirmwareUtility() { 42 FirmwareUtility::~FirmwareUtility() {
43 RSAPublicKeyFree(root_key_pub_); 43 RSAPublicKeyFree(root_key_pub_);
44 FirmwareImageFree(image_); 44 FirmwareImageFree(image_);
45 } 45 }
46 46
47 void FirmwareUtility::PrintUsage(void) { 47 void FirmwareUtility::PrintUsage(void) {
48 cerr << 48 cerr <<
49 "Utility to generate/verify a verified boot firmware image\n\n" 49 "Utility to generate/verify a verified boot firmware image\n\n"
50 "Usage: firmware_utility <--generate|--verify> [OPTIONS]\n\n" 50 "Usage: firmware_utility <--generate|--verify> [OPTIONS]\n\n"
51 "For \"--verify\", required OPTIONS are:\n" 51 "For \"--verify\", required OPTIONS are:\n"
52 "--in <infile>\t\t\tVerified boot firmware image to verify.\n" 52 "--in <infile>\t\t\tVerified boot firmware image to verify.\n"
53 "--root_key_pub <pubkeyfile>\tPre-processed public root key " 53 "--root_key_pub <pubkeyfile>\tPre-processed public root key "
54 "to use for verification.\n\n" 54 "to use for verification.\n\n"
55 "For \"--generate\", required OPTIONS are:\n" 55 "For \"--generate\", required OPTIONS are:\n"
56 "--root_key <privkeyfile>\tPrivate root key file\n" 56 "--root_key <privkeyfile>\tPrivate root key file\n"
57 "--sign_key <privkeyfile>\tPrivate signing key file\n" 57 "--firmware_sign_key <privkeyfile>\tPrivate signing key file\n"
58 "--sign_key_pub <pubkeyfile>\tPre-processed public signing" 58 "--firmware_sign_key_pub <pubkeyfile>\tPre-processed public signing"
59 " key\n" 59 " key\n"
60 "--sign_algorithm <algoid>\tSigning algorithm to use\n" 60 "--firmware_sign_algorithm <algoid>\tSigning algorithm to use\n"
61 "--key_version <version#>\tSigning Key Version#\n" 61 "--firmware_key_version <version#>\tSigning Key Version#\n"
62 "--firmware_version <version#>\tFirmware Version#\n" 62 "--firmware_version <version#>\tFirmware Version#\n"
63 "--in <infile>\t\t\tFirmware Image to sign\n" 63 "--in <infile>\t\t\tFirmware Image to sign\n"
64 "--out <outfile>\t\t\tOutput file for verified boot firmware image\n\n" 64 "--out <outfile>\t\t\tOutput file for verified boot firmware image\n\n"
65 "<algoid> (for --sign-algorithm) is one of the following:\n"; 65 "<algoid> (for --sign-algorithm) is one of the following:\n";
66 for (int i = 0; i < kNumAlgorithms; i++) { 66 for (int i = 0; i < kNumAlgorithms; i++) {
67 cerr << i << " for " << algo_strings[i] << "\n"; 67 cerr << i << " for " << algo_strings[i] << "\n";
68 } 68 }
69 cerr << "\n\n"; 69 cerr << "\n\n";
70 } 70 }
71 71
72 bool FirmwareUtility::ParseCmdLineOptions(int argc, char* argv[]) { 72 bool FirmwareUtility::ParseCmdLineOptions(int argc, char* argv[]) {
73 int option_index; 73 int option_index;
74 static struct option long_options[] = { 74 static struct option long_options[] = {
75 {"root_key", 1, 0, 0}, 75 {"root_key", 1, 0, 0},
76 {"root_key_pub", 1, 0, 0}, 76 {"root_key_pub", 1, 0, 0},
77 {"sign_key", 1, 0, 0}, 77 {"firmware_sign_key", 1, 0, 0},
78 {"sign_key_pub", 1, 0, 0}, 78 {"firmware_sign_key_pub", 1, 0, 0},
79 {"sign_algorithm", 1, 0, 0}, 79 {"firmware_sign_algorithm", 1, 0, 0},
80 {"key_version", 1, 0, 0}, 80 {"firmware_key_version", 1, 0, 0},
81 {"firmware_version", 1, 0, 0}, 81 {"firmware_version", 1, 0, 0},
82 {"in", 1, 0, 0}, 82 {"in", 1, 0, 0},
83 {"out", 1, 0, 0}, 83 {"out", 1, 0, 0},
84 {"generate", 0, 0, 0}, 84 {"generate", 0, 0, 0},
85 {"verify", 0, 0, 0}, 85 {"verify", 0, 0, 0},
86 {NULL, 0, 0, 0} 86 {NULL, 0, 0, 0}
87 }; 87 };
88 while (1) { 88 while (1) {
89 int i = getopt_long(argc, argv, "", long_options, &option_index); 89 int i = getopt_long(argc, argv, "", long_options, &option_index);
90 if (-1 == i) // Done with option processing. 90 if (-1 == i) // Done with option processing.
91 break; 91 break;
92 if ('?' == i) // Invalid option found. 92 if ('?' == i) // Invalid option found.
93 return false; 93 return false;
94 94
95 if (0 == i) { 95 if (0 == i) {
96 switch(option_index) { 96 switch(option_index) {
97 case 0: // root_key 97 case 0: // root_key
98 root_key_file_ = optarg; 98 root_key_file_ = optarg;
99 break; 99 break;
100 case 1: // root_key_pub 100 case 1: // root_key_pub
101 root_key_pub_file_ = optarg; 101 root_key_pub_file_ = optarg;
102 break; 102 break;
103 case 2: // sign_key 103 case 2: // firmware_sign_key
104 sign_key_file_ = optarg; 104 firmware_sign_key_file_ = optarg;
105 break; 105 break;
106 case 3: // sign_key_pub 106 case 3: // firmware_sign_key_pub
107 sign_key_pub_file_ = optarg; 107 firmware_sign_key_pub_file_ = optarg;
108 break; 108 break;
109 case 4: // sign_algorithm 109 case 4: // firmware_sign_algorithm
110 errno = 0; // strtol() returns an error via errno 110 errno = 0; // strtol() returns an error via errno
111 sign_algorithm_ = strtol(optarg, (char**) NULL, 10); 111 firmware_sign_algorithm_ = strtol(optarg, (char**) NULL, 10);
112 if (errno) 112 if (errno)
113 return false; 113 return false;
114 break; 114 break;
115 case 5: // key_version 115 case 5: // firmware_key_version
116 errno = 0; 116 errno = 0;
117 key_version_ = strtol(optarg, (char**) NULL, 10); 117 firmware_key_version_ = strtol(optarg, (char**) NULL, 10);
118 if (errno) 118 if (errno)
119 return false; 119 return false;
120 break; 120 break;
121 case 6: // firmware_version 121 case 6: // firmware_version
122 errno = 0; 122 errno = 0;
123 firmware_version_ = strtol(optarg, (char**) NULL, 10); 123 firmware_version_ = strtol(optarg, (char**) NULL, 10);
124 if (errno) 124 if (errno)
125 return false; 125 return false;
126 break; 126 break;
127 case 7: // in 127 case 7: // in
(...skipping 18 matching lines...) Expand all
146 void FirmwareUtility::OutputSignedImage(void) { 146 void FirmwareUtility::OutputSignedImage(void) {
147 if (image_) { 147 if (image_) {
148 if (!WriteFirmwareImage(out_file_.c_str(), image_)) { 148 if (!WriteFirmwareImage(out_file_.c_str(), image_)) {
149 cerr << "Couldn't write verified boot image to file " 149 cerr << "Couldn't write verified boot image to file "
150 << out_file_ <<".\n"; 150 << out_file_ <<".\n";
151 } 151 }
152 } 152 }
153 } 153 }
154 154
155 bool FirmwareUtility::GenerateSignedImage(void) { 155 bool FirmwareUtility::GenerateSignedImage(void) {
156 uint32_t sign_key_pub_len; 156 uint32_t firmware_sign_key_pub_len;
157 uint8_t* header_checksum; 157 uint8_t* header_checksum;
158 DigestContext ctx; 158 DigestContext ctx;
159 image_ = FirmwareImageNew(); 159 image_ = FirmwareImageNew();
160 160
161 Memcpy(image_->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE); 161 Memcpy(image_->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE);
162 162
163 // Copy pre-processed public signing key. 163 // Copy pre-processed public signing key.
164 image_->sign_algorithm = (uint16_t) sign_algorithm_; 164 image_->firmware_sign_algorithm = (uint16_t) firmware_sign_algorithm_;
165 image_->sign_key = BufferFromFile(sign_key_pub_file_.c_str(), 165 image_->firmware_sign_key = BufferFromFile(
166 &sign_key_pub_len); 166 firmware_sign_key_pub_file_.c_str(),
167 if (!image_->sign_key) 167 &firmware_sign_key_pub_len);
168 if (!image_->firmware_sign_key)
168 return false; 169 return false;
169 image_->key_version = key_version_; 170 image_->firmware_key_version = firmware_key_version_;
170 171
171 // Update header length. 172 // Update header length.
172 image_->header_len = (sizeof(image_->header_len) + 173 image_->header_len = (sizeof(image_->header_len) +
173 sizeof(image_->sign_algorithm) + 174 sizeof(image_->firmware_sign_algorithm) +
174 sign_key_pub_len + 175 firmware_sign_key_pub_len +
175 sizeof(image_->key_version) + 176 sizeof(image_->firmware_key_version) +
176 sizeof(image_->header_checksum)); 177 sizeof(image_->header_checksum));
177 178
178 // Calculate header checksum. 179 // Calculate header checksum.
179 DigestInit(&ctx, SHA512_DIGEST_ALGORITHM); 180 DigestInit(&ctx, SHA512_DIGEST_ALGORITHM);
180 DigestUpdate(&ctx, (uint8_t*) &image_->header_len, 181 DigestUpdate(&ctx, (uint8_t*) &image_->header_len,
181 sizeof(image_->header_len)); 182 sizeof(image_->header_len));
182 DigestUpdate(&ctx, (uint8_t*) &image_->sign_algorithm, 183 DigestUpdate(&ctx, (uint8_t*) &image_->firmware_sign_algorithm,
183 sizeof(image_->sign_algorithm)); 184 sizeof(image_->firmware_sign_algorithm));
184 DigestUpdate(&ctx, image_->sign_key, 185 DigestUpdate(&ctx, image_->firmware_sign_key,
185 RSAProcessedKeySize(image_->sign_algorithm)); 186 RSAProcessedKeySize(image_->firmware_sign_algorithm));
186 DigestUpdate(&ctx, (uint8_t*) &image_->key_version, 187 DigestUpdate(&ctx, (uint8_t*) &image_->firmware_key_version,
187 sizeof(image_->key_version)); 188 sizeof(image_->firmware_key_version));
188 header_checksum = DigestFinal(&ctx); 189 header_checksum = DigestFinal(&ctx);
189 Memcpy(image_->header_checksum, header_checksum, SHA512_DIGEST_SIZE); 190 Memcpy(image_->header_checksum, header_checksum, SHA512_DIGEST_SIZE);
190 Free(header_checksum); 191 Free(header_checksum);
191 192
192 image_->firmware_version = firmware_version_; 193 image_->firmware_version = firmware_version_;
193 image_->firmware_len = 0; 194 image_->firmware_len = 0;
194 // TODO(gauravsh): Populate this with the right bytes once we decide 195 // TODO(gauravsh): Populate this with the right bytes once we decide
195 // what goes into the preamble. 196 // what goes into the preamble.
196 Memset(image_->preamble, 'P', FIRMWARE_PREAMBLE_SIZE); 197 Memset(image_->preamble, 'P', FIRMWARE_PREAMBLE_SIZE);
197 image_->firmware_data = BufferFromFile(in_file_.c_str(), 198 image_->firmware_data = BufferFromFile(in_file_.c_str(),
198 &image_->firmware_len); 199 &image_->firmware_len);
199 if (!image_) 200 if (!image_)
200 return false; 201 return false;
201 // Generate and add the signatures. 202 // Generate and add the signatures.
202 if(!AddFirmwareKeySignature(image_, root_key_file_.c_str())) { 203 if (!AddFirmwareKeySignature(image_, root_key_file_.c_str())) {
203 cerr << "Couldn't write key signature to verified boot image.\n"; 204 cerr << "Couldn't write key signature to verified boot image.\n";
204 return false; 205 return false;
205 } 206 }
206 207
207 if(!AddFirmwareSignature(image_, sign_key_file_.c_str(), 208 if (!AddFirmwareSignature(image_, firmware_sign_key_file_.c_str())) {
208 image_->sign_algorithm)) {
209 cerr << "Couldn't write firmware signature to verified boot image.\n"; 209 cerr << "Couldn't write firmware signature to verified boot image.\n";
210 return false; 210 return false;
211 } 211 }
212 return true; 212 return true;
213 } 213 }
214 214
215 bool FirmwareUtility::VerifySignedImage(void) { 215 bool FirmwareUtility::VerifySignedImage(void) {
216 int error; 216 int error;
217 root_key_pub_ = RSAPublicKeyFromFile(root_key_pub_file_.c_str()); 217 root_key_pub_ = RSAPublicKeyFromFile(root_key_pub_file_.c_str());
218 image_ = ReadFirmwareImage(in_file_.c_str()); 218 image_ = ReadFirmwareImage(in_file_.c_str());
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 // Required options for --generate. 250 // Required options for --generate.
251 if (is_generate_) { 251 if (is_generate_) {
252 if (root_key_file_.empty()) { 252 if (root_key_file_.empty()) {
253 cerr << "No root key file specified." << "\n"; 253 cerr << "No root key file specified." << "\n";
254 return false; 254 return false;
255 } 255 }
256 if (firmware_version_ <= 0 || firmware_version_ > UINT16_MAX) { 256 if (firmware_version_ <= 0 || firmware_version_ > UINT16_MAX) {
257 cerr << "Invalid or no firmware version specified." << "\n"; 257 cerr << "Invalid or no firmware version specified." << "\n";
258 return false; 258 return false;
259 } 259 }
260 if (sign_key_file_.empty()) { 260 if (firmware_sign_key_file_.empty()) {
261 cerr << "No signing key file specified." << "\n"; 261 cerr << "No signing key file specified." << "\n";
262 return false; 262 return false;
263 } 263 }
264 if (sign_key_pub_file_.empty()) { 264 if (firmware_sign_key_pub_file_.empty()) {
265 cerr << "No pre-processed public signing key file specified." << "\n"; 265 cerr << "No pre-processed public signing key file specified." << "\n";
266 return false; 266 return false;
267 } 267 }
268 if (key_version_ <= 0 || key_version_ > UINT16_MAX) { 268 if (firmware_key_version_ <= 0 || firmware_key_version_ > UINT16_MAX) {
269 cerr << "Invalid or no key version specified." << "\n"; 269 cerr << "Invalid or no key version specified." << "\n";
270 return false; 270 return false;
271 } 271 }
272 if (sign_algorithm_ < 0 || sign_algorithm_ >= kNumAlgorithms) { 272 if (firmware_sign_algorithm_ < 0 ||
273 firmware_sign_algorithm_ >= kNumAlgorithms) {
273 cerr << "Invalid or no signing key algorithm specified." << "\n"; 274 cerr << "Invalid or no signing key algorithm specified." << "\n";
274 return false; 275 return false;
275 } 276 }
276 if (out_file_.empty()) { 277 if (out_file_.empty()) {
277 cerr <<"No output file specified." << "\n"; 278 cerr <<"No output file specified." << "\n";
278 return false; 279 return false;
279 } 280 }
280 } 281 }
281 return true; 282 return true;
282 } 283 }
(...skipping 14 matching lines...) Expand all
297 } 298 }
298 if (fu.is_verify()) { 299 if (fu.is_verify()) {
299 cerr << "Verification "; 300 cerr << "Verification ";
300 if(fu.VerifySignedImage()) 301 if(fu.VerifySignedImage())
301 cerr << "SUCCESS.\n"; 302 cerr << "SUCCESS.\n";
302 else 303 else
303 cerr << "FAILURE.\n"; 304 cerr << "FAILURE.\n";
304 } 305 }
305 return 0; 306 return 0;
306 } 307 }
OLDNEW
« no previous file with comments | « src/platform/vboot_reference/utils/firmware_image.c ('k') | src/platform/vboot_reference/utils/kernel_image.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698