| 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 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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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: // firmware_sign_key | 103 case 2: // firmware_sign_key |
| 104 firmware_sign_key_file_ = optarg; | 104 firmware_key_file_ = optarg; |
| 105 break; | 105 break; |
| 106 case 3: // firmware_sign_key_pub | 106 case 3: // firmware_sign_key_pub |
| 107 firmware_sign_key_pub_file_ = optarg; | 107 firmware_key_pub_file_ = optarg; |
| 108 break; | 108 break; |
| 109 case 4: // firmware_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 firmware_sign_algorithm_ = strtol(optarg, (char**) NULL, 10); | 111 firmware_sign_algorithm_ = strtol(optarg, |
| 112 reinterpret_cast<char**>(NULL), 10); |
| 112 if (errno) | 113 if (errno) |
| 113 return false; | 114 return false; |
| 114 break; | 115 break; |
| 115 case 5: // firmware_key_version | 116 case 5: // firmware_key_version |
| 116 errno = 0; | 117 errno = 0; |
| 117 firmware_key_version_ = strtol(optarg, (char**) NULL, 10); | 118 firmware_key_version_ = strtol(optarg, |
| 119 reinterpret_cast<char**>(NULL), 10); |
| 118 if (errno) | 120 if (errno) |
| 119 return false; | 121 return false; |
| 120 break; | 122 break; |
| 121 case 6: // firmware_version | 123 case 6: // firmware_version |
| 122 errno = 0; | 124 errno = 0; |
| 123 firmware_version_ = strtol(optarg, (char**) NULL, 10); | 125 firmware_version_ = strtol(optarg, |
| 126 reinterpret_cast<char**>(NULL), 10); |
| 124 if (errno) | 127 if (errno) |
| 125 return false; | 128 return false; |
| 126 break; | 129 break; |
| 127 case 7: // in | 130 case 7: // in |
| 128 in_file_ = optarg; | 131 in_file_ = optarg; |
| 129 break; | 132 break; |
| 130 case 8: // out | 133 case 8: // out |
| 131 out_file_ = optarg; | 134 out_file_ = optarg; |
| 132 break; | 135 break; |
| 133 case 9: // generate | 136 case 9: // generate |
| (...skipping 22 matching lines...) Expand all Loading... |
| 156 uint32_t firmware_sign_key_pub_len; | 159 uint32_t firmware_sign_key_pub_len; |
| 157 uint8_t* header_checksum; | 160 uint8_t* header_checksum; |
| 158 DigestContext ctx; | 161 DigestContext ctx; |
| 159 image_ = FirmwareImageNew(); | 162 image_ = FirmwareImageNew(); |
| 160 | 163 |
| 161 Memcpy(image_->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE); | 164 Memcpy(image_->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE); |
| 162 | 165 |
| 163 // Copy pre-processed public signing key. | 166 // Copy pre-processed public signing key. |
| 164 image_->firmware_sign_algorithm = (uint16_t) firmware_sign_algorithm_; | 167 image_->firmware_sign_algorithm = (uint16_t) firmware_sign_algorithm_; |
| 165 image_->firmware_sign_key = BufferFromFile( | 168 image_->firmware_sign_key = BufferFromFile( |
| 166 firmware_sign_key_pub_file_.c_str(), | 169 firmware_key_pub_file_.c_str(), |
| 167 &firmware_sign_key_pub_len); | 170 &firmware_sign_key_pub_len); |
| 168 if (!image_->firmware_sign_key) | 171 if (!image_->firmware_sign_key) |
| 169 return false; | 172 return false; |
| 170 image_->firmware_key_version = firmware_key_version_; | 173 image_->firmware_key_version = firmware_key_version_; |
| 171 | 174 |
| 172 // Update header length. | 175 // Update header length. |
| 173 image_->header_len = (sizeof(image_->header_len) + | 176 image_->header_len = GetFirmwareHeaderLen(image_); |
| 174 sizeof(image_->firmware_sign_algorithm) + | |
| 175 firmware_sign_key_pub_len + | |
| 176 sizeof(image_->firmware_key_version) + | |
| 177 sizeof(image_->header_checksum)); | |
| 178 | 177 |
| 179 // Calculate header checksum. | 178 // Calculate header checksum. |
| 180 DigestInit(&ctx, SHA512_DIGEST_ALGORITHM); | 179 DigestInit(&ctx, SHA512_DIGEST_ALGORITHM); |
| 181 DigestUpdate(&ctx, (uint8_t*) &image_->header_len, | 180 DigestUpdate(&ctx, reinterpret_cast<uint8_t*>(&image_->header_len), |
| 182 sizeof(image_->header_len)); | 181 sizeof(image_->header_len)); |
| 183 DigestUpdate(&ctx, (uint8_t*) &image_->firmware_sign_algorithm, | 182 DigestUpdate(&ctx, |
| 183 reinterpret_cast<uint8_t*>(&image_->firmware_sign_algorithm), |
| 184 sizeof(image_->firmware_sign_algorithm)); | 184 sizeof(image_->firmware_sign_algorithm)); |
| 185 DigestUpdate(&ctx, image_->firmware_sign_key, | 185 DigestUpdate(&ctx, image_->firmware_sign_key, |
| 186 RSAProcessedKeySize(image_->firmware_sign_algorithm)); | 186 RSAProcessedKeySize(image_->firmware_sign_algorithm)); |
| 187 DigestUpdate(&ctx, (uint8_t*) &image_->firmware_key_version, | 187 DigestUpdate(&ctx, reinterpret_cast<uint8_t*>(&image_->firmware_key_version), |
| 188 sizeof(image_->firmware_key_version)); | 188 sizeof(image_->firmware_key_version)); |
| 189 header_checksum = DigestFinal(&ctx); | 189 header_checksum = DigestFinal(&ctx); |
| 190 Memcpy(image_->header_checksum, header_checksum, SHA512_DIGEST_SIZE); | 190 Memcpy(image_->header_checksum, header_checksum, SHA512_DIGEST_SIZE); |
| 191 Free(header_checksum); | 191 Free(header_checksum); |
| 192 | 192 |
| 193 image_->firmware_version = firmware_version_; | 193 image_->firmware_version = firmware_version_; |
| 194 image_->firmware_len = 0; | 194 image_->firmware_len = 0; |
| 195 // TODO(gauravsh): Populate this with the right bytes once we decide | 195 // TODO(gauravsh): Populate this with the right bytes once we decide |
| 196 // what goes into the preamble. | 196 // what goes into the preamble. |
| 197 Memset(image_->preamble, 'P', FIRMWARE_PREAMBLE_SIZE); | 197 Memset(image_->preamble, 'P', FIRMWARE_PREAMBLE_SIZE); |
| 198 image_->firmware_data = BufferFromFile(in_file_.c_str(), | 198 image_->firmware_data = BufferFromFile(in_file_.c_str(), |
| 199 &image_->firmware_len); | 199 &image_->firmware_len); |
| 200 if (!image_) | 200 if (!image_) |
| 201 return false; | 201 return false; |
| 202 // Generate and add the signatures. | 202 // Generate and add the signatures. |
| 203 if (!AddFirmwareKeySignature(image_, root_key_file_.c_str())) { | 203 if (!AddFirmwareKeySignature(image_, root_key_file_.c_str())) { |
| 204 cerr << "Couldn't write key signature to verified boot image.\n"; | 204 cerr << "Couldn't write key signature to verified boot image.\n"; |
| 205 return false; | 205 return false; |
| 206 } | 206 } |
| 207 | 207 |
| 208 if (!AddFirmwareSignature(image_, firmware_sign_key_file_.c_str())) { | 208 if (!AddFirmwareSignature(image_, firmware_key_file_.c_str())) { |
| 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()); |
| 219 | 219 |
| 220 if (!root_key_pub_) { | 220 if (!root_key_pub_) { |
| 221 cerr << "Couldn't read pre-processed public root key.\n"; | 221 cerr << "Couldn't read pre-processed public root key.\n"; |
| 222 return false; | 222 return false; |
| 223 } | 223 } |
| 224 | 224 |
| 225 if (!image_) { | 225 if (!image_) { |
| 226 cerr << "Couldn't read firmware image or malformed image.\n"; | 226 cerr << "Couldn't read firmware image or malformed image.\n"; |
| 227 return false; | 227 return false; |
| 228 } | 228 } |
| 229 if(!(error = VerifyFirmwareImage(root_key_pub_, image_, 0))) // Trusted Mode. | 229 if (!(error = VerifyFirmwareImage(root_key_pub_, image_, |
| 230 0))) // Trusted Mode. |
| 230 return true; | 231 return true; |
| 231 cerr << VerifyFirmwareErrorString(error) << "\n"; | 232 cerr << VerifyFirmwareErrorString(error) << "\n"; |
| 232 return false;; | 233 return false;; |
| 233 } | 234 } |
| 234 | 235 |
| 235 bool FirmwareUtility::CheckOptions(void) { | 236 bool FirmwareUtility::CheckOptions(void) { |
| 236 if (is_generate_ == is_verify_) { | 237 if (is_generate_ == is_verify_) { |
| 237 cerr << "One of --generate or --verify must be specified.\n"; | 238 cerr << "One of --generate or --verify must be specified.\n"; |
| 238 return false; | 239 return false; |
| 239 } | 240 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 250 // Required options for --generate. | 251 // Required options for --generate. |
| 251 if (is_generate_) { | 252 if (is_generate_) { |
| 252 if (root_key_file_.empty()) { | 253 if (root_key_file_.empty()) { |
| 253 cerr << "No root key file specified." << "\n"; | 254 cerr << "No root key file specified." << "\n"; |
| 254 return false; | 255 return false; |
| 255 } | 256 } |
| 256 if (firmware_version_ <= 0 || firmware_version_ > UINT16_MAX) { | 257 if (firmware_version_ <= 0 || firmware_version_ > UINT16_MAX) { |
| 257 cerr << "Invalid or no firmware version specified." << "\n"; | 258 cerr << "Invalid or no firmware version specified." << "\n"; |
| 258 return false; | 259 return false; |
| 259 } | 260 } |
| 260 if (firmware_sign_key_file_.empty()) { | 261 if (firmware_key_file_.empty()) { |
| 261 cerr << "No signing key file specified." << "\n"; | 262 cerr << "No signing key file specified." << "\n"; |
| 262 return false; | 263 return false; |
| 263 } | 264 } |
| 264 if (firmware_sign_key_pub_file_.empty()) { | 265 if (firmware_key_pub_file_.empty()) { |
| 265 cerr << "No pre-processed public signing key file specified." << "\n"; | 266 cerr << "No pre-processed public signing key file specified." << "\n"; |
| 266 return false; | 267 return false; |
| 267 } | 268 } |
| 268 if (firmware_key_version_ <= 0 || firmware_key_version_ > UINT16_MAX) { | 269 if (firmware_key_version_ <= 0 || firmware_key_version_ > UINT16_MAX) { |
| 269 cerr << "Invalid or no key version specified." << "\n"; | 270 cerr << "Invalid or no key version specified." << "\n"; |
| 270 return false; | 271 return false; |
| 271 } | 272 } |
| 272 if (firmware_sign_algorithm_ < 0 || | 273 if (firmware_sign_algorithm_ < 0 || |
| 273 firmware_sign_algorithm_ >= kNumAlgorithms) { | 274 firmware_sign_algorithm_ >= kNumAlgorithms) { |
| 274 cerr << "Invalid or no signing key algorithm specified." << "\n"; | 275 cerr << "Invalid or no signing key algorithm specified." << "\n"; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 291 fu.PrintUsage(); | 292 fu.PrintUsage(); |
| 292 return -1; | 293 return -1; |
| 293 } | 294 } |
| 294 if (fu.is_generate()) { | 295 if (fu.is_generate()) { |
| 295 if (!fu.GenerateSignedImage()) | 296 if (!fu.GenerateSignedImage()) |
| 296 return -1; | 297 return -1; |
| 297 fu.OutputSignedImage(); | 298 fu.OutputSignedImage(); |
| 298 } | 299 } |
| 299 if (fu.is_verify()) { | 300 if (fu.is_verify()) { |
| 300 cerr << "Verification "; | 301 cerr << "Verification "; |
| 301 if(fu.VerifySignedImage()) | 302 if (fu.VerifySignedImage()) |
| 302 cerr << "SUCCESS.\n"; | 303 cerr << "SUCCESS.\n"; |
| 303 else | 304 else |
| 304 cerr << "FAILURE.\n"; | 305 cerr << "FAILURE.\n"; |
| 305 } | 306 } |
| 306 return 0; | 307 return 0; |
| 307 } | 308 } |
| OLD | NEW |