| 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 * Functions for generating and manipulating a verified boot kernel image. | 5 * Functions for generating and manipulating a verified boot kernel image. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "kernel_image.h" | 8 #include "kernel_image.h" |
| 9 | 9 |
| 10 #include <fcntl.h> | 10 #include <fcntl.h> |
| 11 #include <stdio.h> | 11 #include <stdio.h> |
| 12 #include <sys/types.h> | 12 #include <sys/types.h> |
| 13 #include <sys/stat.h> | 13 #include <sys/stat.h> |
| 14 #include <unistd.h> | 14 #include <unistd.h> |
| 15 | 15 |
| 16 #include "file_keys.h" | 16 #include "file_keys.h" |
| 17 #include "padding.h" | 17 #include "padding.h" |
| 18 #include "rsa_utility.h" | 18 #include "rsa_utility.h" |
| 19 #include "sha_utility.h" | 19 #include "sha_utility.h" |
| 20 #include "signature_digest.h" |
| 20 #include "utility.h" | 21 #include "utility.h" |
| 21 | 22 |
| 22 /* Macro to determine the size of a field structure in the KernelImage | 23 /* Macro to determine the size of a field structure in the KernelImage |
| 23 * structure. */ | 24 * structure. */ |
| 24 #define FIELD_LEN(field) (sizeof(((KernelImage*)0)->field)) | 25 #define FIELD_LEN(field) (sizeof(((KernelImage*)0)->field)) |
| 25 | 26 |
| 26 KernelImage* KernelImageNew(void) { | 27 KernelImage* KernelImageNew(void) { |
| 27 KernelImage* image = (KernelImage*) Malloc(sizeof(KernelImage)); | 28 KernelImage* image = (KernelImage*) Malloc(sizeof(KernelImage)); |
| 28 if (image) { | 29 if (image) { |
| 29 image->kernel_sign_key = NULL; | 30 image->kernel_sign_key = NULL; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 if (!image) | 62 if (!image) |
| 62 return NULL; | 63 return NULL; |
| 63 | 64 |
| 64 kernel_buf = BufferFromFile(input_file, &file_size); | 65 kernel_buf = BufferFromFile(input_file, &file_size); |
| 65 image_len = file_size; | 66 image_len = file_size; |
| 66 | 67 |
| 67 st.remaining_len = image_len; | 68 st.remaining_len = image_len; |
| 68 st.remaining_buf = kernel_buf; | 69 st.remaining_buf = kernel_buf; |
| 69 | 70 |
| 70 /* Read and compare magic bytes. */ | 71 /* Read and compare magic bytes. */ |
| 71 if (!StatefulMemcpy(&st, &image->magic, KERNEL_MAGIC_SIZE)) | 72 StatefulMemcpy(&st, &image->magic, KERNEL_MAGIC_SIZE); |
| 72 goto parse_failure; | |
| 73 | 73 |
| 74 if (SafeMemcmp(image->magic, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) { | 74 if (SafeMemcmp(image->magic, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) { |
| 75 fprintf(stderr, "Wrong Kernel Magic.\n"); | 75 fprintf(stderr, "Wrong Kernel Magic.\n"); |
| 76 goto parse_failure; | 76 Free(kernel_buf); |
| 77 return NULL; |
| 77 } | 78 } |
| 78 StatefulMemcpy(&st, &image->header_version, FIELD_LEN(header_version)); | 79 StatefulMemcpy(&st, &image->header_version, FIELD_LEN(header_version)); |
| 79 StatefulMemcpy(&st, &image->header_len, FIELD_LEN(header_len)); | 80 StatefulMemcpy(&st, &image->header_len, FIELD_LEN(header_len)); |
| 80 StatefulMemcpy(&st, &image->firmware_sign_algorithm, | 81 StatefulMemcpy(&st, &image->firmware_sign_algorithm, |
| 81 FIELD_LEN(firmware_sign_algorithm)); | 82 FIELD_LEN(firmware_sign_algorithm)); |
| 82 StatefulMemcpy(&st, &image->kernel_sign_algorithm, | 83 StatefulMemcpy(&st, &image->kernel_sign_algorithm, |
| 83 FIELD_LEN(kernel_sign_algorithm)); | 84 FIELD_LEN(kernel_sign_algorithm)); |
| 84 | 85 |
| 85 /* Valid Kernel Key signing algorithm. */ | 86 /* Valid Kernel Key signing algorithm. */ |
| 86 if (image->firmware_sign_algorithm >= kNumAlgorithms) | 87 if (image->firmware_sign_algorithm >= kNumAlgorithms) { |
| 87 goto parse_failure; | 88 Free(kernel_buf); |
| 89 return NULL; |
| 90 } |
| 88 | 91 |
| 89 /* Valid Kernel Signing Algorithm? */ | 92 /* Valid Kernel Signing Algorithm? */ |
| 90 if (image->kernel_sign_algorithm >= kNumAlgorithms) | 93 if (image->kernel_sign_algorithm >= kNumAlgorithms) { |
| 91 goto parse_failure; | 94 Free(kernel_buf); |
| 95 return NULL; |
| 96 } |
| 92 | 97 |
| 93 /* Compute size of pre-processed RSA public keys and signatures. */ | 98 /* Compute size of pre-processed RSA public keys and signatures. */ |
| 94 firmware_sign_key_len = RSAProcessedKeySize(image->firmware_sign_algorithm); | 99 firmware_sign_key_len = RSAProcessedKeySize(image->firmware_sign_algorithm); |
| 95 kernel_key_signature_len = siglen_map[image->firmware_sign_algorithm]; | 100 kernel_key_signature_len = siglen_map[image->firmware_sign_algorithm]; |
| 96 kernel_sign_key_len = RSAProcessedKeySize(image->kernel_sign_algorithm); | 101 kernel_sign_key_len = RSAProcessedKeySize(image->kernel_sign_algorithm); |
| 97 kernel_signature_len = siglen_map[image->kernel_sign_algorithm]; | 102 kernel_signature_len = siglen_map[image->kernel_sign_algorithm]; |
| 98 | 103 |
| 99 /* Check whether key header length is correct. */ | 104 /* Check whether key header length is correct. */ |
| 100 header_len = (FIELD_LEN(header_version) + | 105 header_len = (FIELD_LEN(header_version) + |
| 101 FIELD_LEN(header_len) + | 106 FIELD_LEN(header_len) + |
| 102 FIELD_LEN(firmware_sign_algorithm) + | 107 FIELD_LEN(firmware_sign_algorithm) + |
| 103 FIELD_LEN(kernel_sign_algorithm) + | 108 FIELD_LEN(kernel_sign_algorithm) + |
| 104 FIELD_LEN(kernel_key_version) + | 109 FIELD_LEN(kernel_key_version) + |
| 105 kernel_sign_key_len + | 110 kernel_sign_key_len + |
| 106 FIELD_LEN(header_checksum)); | 111 FIELD_LEN(header_checksum)); |
| 107 | 112 |
| 108 if (header_len != image->header_len) { | 113 if (header_len != image->header_len) { |
| 109 fprintf(stderr, "Header length mismatch. Got: %d, Expected: %d\n", | 114 fprintf(stderr, "Header length mismatch. Got: %d, Expected: %d\n", |
| 110 image->header_len, header_len); | 115 image->header_len, header_len); |
| 111 goto parse_failure; | 116 Free(kernel_buf); |
| 117 return NULL; |
| 112 } | 118 } |
| 113 | 119 |
| 114 /* Read pre-processed public half of the kernel signing key. */ | 120 /* Read pre-processed public half of the kernel signing key. */ |
| 115 StatefulMemcpy(&st, &image->kernel_key_version, | 121 StatefulMemcpy(&st, &image->kernel_key_version, |
| 116 FIELD_LEN(kernel_key_version)); | 122 FIELD_LEN(kernel_key_version)); |
| 117 image->kernel_sign_key = (uint8_t*) Malloc(kernel_sign_key_len); | 123 image->kernel_sign_key = (uint8_t*) Malloc(kernel_sign_key_len); |
| 118 StatefulMemcpy(&st, image->kernel_sign_key, kernel_sign_key_len); | 124 StatefulMemcpy(&st, image->kernel_sign_key, kernel_sign_key_len); |
| 119 StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum)); | 125 StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum)); |
| 120 | 126 |
| 121 /* Read key signature. */ | 127 /* Read key signature. */ |
| (...skipping 13 matching lines...) Expand all Loading... |
| 135 /* Read kernel config signature. */ | 141 /* Read kernel config signature. */ |
| 136 image->config_signature = (uint8_t*) Malloc(kernel_signature_len); | 142 image->config_signature = (uint8_t*) Malloc(kernel_signature_len); |
| 137 StatefulMemcpy(&st, image->config_signature, kernel_signature_len); | 143 StatefulMemcpy(&st, image->config_signature, kernel_signature_len); |
| 138 | 144 |
| 139 image->kernel_signature = (uint8_t*) Malloc(kernel_signature_len); | 145 image->kernel_signature = (uint8_t*) Malloc(kernel_signature_len); |
| 140 StatefulMemcpy(&st, image->kernel_signature, kernel_signature_len); | 146 StatefulMemcpy(&st, image->kernel_signature, kernel_signature_len); |
| 141 | 147 |
| 142 image->kernel_data = (uint8_t*) Malloc(image->options.kernel_len); | 148 image->kernel_data = (uint8_t*) Malloc(image->options.kernel_len); |
| 143 StatefulMemcpy(&st, image->kernel_data, image->options.kernel_len); | 149 StatefulMemcpy(&st, image->kernel_data, image->options.kernel_len); |
| 144 | 150 |
| 145 if(st.remaining_len != 0) /* Overrun or underrun. */ | 151 if(st.remaining_len != 0) { /* Overrun or underrun. */ |
| 146 goto parse_failure; | 152 Free(kernel_buf); |
| 147 | |
| 148 Free(kernel_buf); | |
| 149 return image; | |
| 150 | |
| 151 parse_failure: | |
| 152 Free(kernel_buf); | |
| 153 return NULL; | |
| 154 } | |
| 155 | |
| 156 void WriteKernelHeader(int fd, KernelImage* image) { | |
| 157 int kernel_sign_key_len; | |
| 158 write(fd, &image->header_version, FIELD_LEN(header_version)); | |
| 159 write(fd, &image->header_len, FIELD_LEN(header_len)); | |
| 160 write(fd, &image->firmware_sign_algorithm, | |
| 161 FIELD_LEN(firmware_sign_algorithm)); | |
| 162 write(fd, &image->kernel_sign_algorithm, | |
| 163 FIELD_LEN(kernel_sign_algorithm)); | |
| 164 write(fd, &image->kernel_key_version, FIELD_LEN(kernel_key_version)); | |
| 165 kernel_sign_key_len = (image->header_len - | |
| 166 FIELD_LEN(header_version) - | |
| 167 FIELD_LEN(header_len) - | |
| 168 FIELD_LEN(firmware_sign_algorithm) - | |
| 169 FIELD_LEN(kernel_sign_algorithm) - | |
| 170 FIELD_LEN(kernel_key_version) - | |
| 171 FIELD_LEN(header_checksum)); | |
| 172 write(fd, image->kernel_sign_key, kernel_sign_key_len); | |
| 173 write(fd, &image->header_checksum, FIELD_LEN(header_checksum)); | |
| 174 } | |
| 175 | |
| 176 void WriteKernelConfig(int fd, KernelImage* image) { | |
| 177 write(fd, &image->kernel_version, FIELD_LEN(kernel_version)); | |
| 178 write(fd, image->options.version, FIELD_LEN(options.version)); | |
| 179 write(fd, &image->options.kernel_len, FIELD_LEN(options.kernel_len)); | |
| 180 write(fd, &image->options.kernel_load_addr, | |
| 181 FIELD_LEN(options.kernel_load_addr)); | |
| 182 write(fd, &image->options.kernel_entry_addr, | |
| 183 FIELD_LEN(options.kernel_entry_addr)); | |
| 184 } | |
| 185 | |
| 186 KernelImage* WriteKernelImage(const char* input_file, | |
| 187 KernelImage* image) { | |
| 188 int fd; | |
| 189 int kernel_key_signature_len; | |
| 190 int kernel_signature_len; | |
| 191 if (!image) | |
| 192 return NULL; | |
| 193 if (-1 == (fd = creat(input_file, | |
| 194 S_IRUSR | S_IWUSR))) { /* Owner has R/W permissions. */ | |
| 195 fprintf(stderr, "Couldn't open file for writing.\n"); | |
| 196 return NULL; | 153 return NULL; |
| 197 } | 154 } |
| 198 | 155 Free(kernel_buf); |
| 199 kernel_key_signature_len = siglen_map[image->firmware_sign_algorithm]; | |
| 200 kernel_signature_len = siglen_map[image->kernel_sign_algorithm]; | |
| 201 | |
| 202 write(fd, image->magic, FIELD_LEN(magic)); | |
| 203 WriteKernelHeader(fd, image); | |
| 204 write(fd, image->kernel_key_signature, kernel_key_signature_len); | |
| 205 WriteKernelConfig(fd, image); | |
| 206 write(fd, image->config_signature, kernel_signature_len); | |
| 207 write(fd, image->kernel_signature, kernel_signature_len); | |
| 208 write(fd, image->kernel_data, image->options.kernel_len); | |
| 209 | |
| 210 close(fd); | |
| 211 return image; | 156 return image; |
| 212 } | 157 } |
| 213 | 158 |
| 159 int GetKernelHeaderLen(const KernelImage* image) { |
| 160 return (FIELD_LEN(header_version) + FIELD_LEN(header_len) + |
| 161 FIELD_LEN(firmware_sign_algorithm) + |
| 162 FIELD_LEN(kernel_sign_algorithm) + FIELD_LEN(kernel_key_version) + |
| 163 RSAProcessedKeySize(image->kernel_sign_algorithm) + |
| 164 FIELD_LEN(header_checksum)); |
| 165 } |
| 166 |
| 167 uint8_t* GetKernelHeaderBlob(const KernelImage* image) { |
| 168 uint8_t* header_blob = NULL; |
| 169 MemcpyState st; |
| 170 |
| 171 header_blob = (uint8_t*) Malloc(GetKernelHeaderLen(image)); |
| 172 st.remaining_len = GetKernelHeaderLen(image); |
| 173 st.remaining_buf = header_blob; |
| 174 |
| 175 StatefulMemcpy_r(&st, &image->header_version, FIELD_LEN(header_version)); |
| 176 StatefulMemcpy_r(&st, &image->header_len, FIELD_LEN(header_len)); |
| 177 StatefulMemcpy_r(&st, &image->firmware_sign_algorithm, |
| 178 FIELD_LEN(firmware_sign_algorithm)); |
| 179 StatefulMemcpy_r(&st, &image->kernel_sign_algorithm, |
| 180 FIELD_LEN(kernel_sign_algorithm)); |
| 181 StatefulMemcpy_r(&st, &image->kernel_key_version, |
| 182 FIELD_LEN(kernel_key_version)); |
| 183 StatefulMemcpy_r(&st, image->kernel_sign_key, |
| 184 RSAProcessedKeySize(image->kernel_sign_algorithm)); |
| 185 StatefulMemcpy_r(&st, &image->header_checksum, FIELD_LEN(header_checksum)); |
| 186 |
| 187 if (st.remaining_len != 0) { /* Underrun or Overrun. */ |
| 188 Free(header_blob); |
| 189 return NULL; |
| 190 } |
| 191 return header_blob; |
| 192 } |
| 193 |
| 194 int GetKernelConfigLen(const KernelImage* image) { |
| 195 return (FIELD_LEN(kernel_version) + FIELD_LEN(options.version) + |
| 196 FIELD_LEN(options.kernel_len) + FIELD_LEN(options.kernel_load_addr) + |
| 197 FIELD_LEN(options.kernel_entry_addr)); |
| 198 } |
| 199 |
| 200 uint8_t* GetKernelConfigBlob(const KernelImage* image) { |
| 201 uint8_t* config_blob = NULL; |
| 202 MemcpyState st; |
| 203 |
| 204 config_blob = (uint8_t*) Malloc(GetKernelConfigLen(image)); |
| 205 st.remaining_len = GetKernelConfigLen(image); |
| 206 st.remaining_buf = config_blob; |
| 207 |
| 208 StatefulMemcpy_r(&st, &image->kernel_version, FIELD_LEN(kernel_version)); |
| 209 StatefulMemcpy_r(&st, image->options.version, FIELD_LEN(options.version)); |
| 210 StatefulMemcpy_r(&st, &image->options.kernel_len, |
| 211 FIELD_LEN(options.kernel_len)); |
| 212 StatefulMemcpy_r(&st, &image->options.kernel_load_addr, |
| 213 FIELD_LEN(options.kernel_load_addr)); |
| 214 StatefulMemcpy_r(&st, &image->options.kernel_entry_addr, |
| 215 FIELD_LEN(options.kernel_entry_addr)); |
| 216 if (st.remaining_len != 0) { /* Overrun or Underrun. */ |
| 217 Free(config_blob); |
| 218 return NULL; |
| 219 } |
| 220 return config_blob; |
| 221 } |
| 222 |
| 223 uint8_t* GetKernelBlob(const KernelImage* image, int* blob_len) { |
| 224 int kernel_key_signature_len; |
| 225 int kernel_signature_len; |
| 226 uint8_t* kernel_blob = NULL; |
| 227 uint8_t* header_blob = NULL; |
| 228 uint8_t* config_blob = NULL; |
| 229 MemcpyState st; |
| 230 |
| 231 if (!image) |
| 232 return NULL; |
| 233 kernel_key_signature_len = siglen_map[image->firmware_sign_algorithm]; |
| 234 kernel_signature_len = siglen_map[image->kernel_sign_algorithm]; |
| 235 *blob_len = (FIELD_LEN(magic) + |
| 236 GetKernelHeaderLen(image) + |
| 237 kernel_key_signature_len + |
| 238 GetKernelConfigLen(image) + |
| 239 2 * kernel_signature_len + |
| 240 image->options.kernel_len); |
| 241 kernel_blob = (uint8_t*) Malloc(*blob_len); |
| 242 st.remaining_len = *blob_len; |
| 243 st.remaining_buf = kernel_blob; |
| 244 |
| 245 header_blob = GetKernelHeaderBlob(image); |
| 246 config_blob = GetKernelConfigBlob(image); |
| 247 |
| 248 StatefulMemcpy_r(&st, image->magic, FIELD_LEN(magic)); |
| 249 StatefulMemcpy_r(&st, header_blob, GetKernelHeaderLen(image)); |
| 250 StatefulMemcpy_r(&st, image->kernel_key_signature, kernel_key_signature_len); |
| 251 StatefulMemcpy_r(&st, config_blob, GetKernelConfigLen(image)); |
| 252 StatefulMemcpy_r(&st, image->config_signature, kernel_signature_len); |
| 253 StatefulMemcpy_r(&st, image->kernel_signature, kernel_signature_len); |
| 254 StatefulMemcpy_r(&st, image->kernel_data, image->options.kernel_len); |
| 255 |
| 256 Free(config_blob); |
| 257 Free(header_blob); |
| 258 |
| 259 if (st.remaining_len != 0) { /* Underrun or Overrun. */ |
| 260 Free(kernel_blob); |
| 261 return NULL; |
| 262 } |
| 263 return kernel_blob; |
| 264 } |
| 265 |
| 266 int WriteKernelImage(const char* input_file, |
| 267 const KernelImage* image) { |
| 268 int fd; |
| 269 uint8_t* kernel_blob; |
| 270 int blob_len; |
| 271 |
| 272 if (!image) |
| 273 return 0; |
| 274 if (-1 == (fd = creat(input_file, S_IRWXU))) { |
| 275 fprintf(stderr, "Couldn't open file for writing kernel image: %s\n", |
| 276 input_file); |
| 277 return 0; |
| 278 } |
| 279 kernel_blob = GetKernelBlob(image, &blob_len); |
| 280 if (!kernel_blob) { |
| 281 fprintf(stderr, "Couldn't create kernel blob from KernelImage.\n"); |
| 282 return 0; |
| 283 } |
| 284 if (blob_len != write(fd, kernel_blob, blob_len)) { |
| 285 fprintf(stderr, "Couldn't write Kernel Image to file: %s\n", |
| 286 input_file); |
| 287 |
| 288 Free(kernel_blob); |
| 289 close(fd); |
| 290 return 0; |
| 291 } |
| 292 Free(kernel_blob); |
| 293 close(fd); |
| 294 return 1; |
| 295 } |
| 296 |
| 214 void PrintKernelImage(const KernelImage* image) { | 297 void PrintKernelImage(const KernelImage* image) { |
| 215 if (!image) | 298 if (!image) |
| 216 return; | 299 return; |
| 217 | 300 |
| 218 /* Print header. */ | 301 /* Print header. */ |
| 219 printf("Header Length = %d\n" | 302 printf("Header Length = %d\n" |
| 220 "Firmware Signing key algorithm id = %d\n" | 303 "Firmware Signing key algorithm id = %d\n" |
| 221 "Kernel Signing key algorithm id = %d\n" | 304 "Kernel Signing key algorithm id = %d\n" |
| 222 "Kernel Signature Algorithm = %s\n" | 305 "Kernel Signature Algorithm = %s\n" |
| 223 "Kernel Key Version = %d\n\n", | 306 "Kernel Key Version = %d\n\n", |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 FIELD_LEN(firmware_sign_algorithm)); | 554 FIELD_LEN(firmware_sign_algorithm)); |
| 472 DigestUpdate(&ctx, (uint8_t*) &image->kernel_sign_algorithm, | 555 DigestUpdate(&ctx, (uint8_t*) &image->kernel_sign_algorithm, |
| 473 FIELD_LEN(kernel_sign_algorithm)); | 556 FIELD_LEN(kernel_sign_algorithm)); |
| 474 DigestUpdate(&ctx, (uint8_t*) &image->kernel_key_version, | 557 DigestUpdate(&ctx, (uint8_t*) &image->kernel_key_version, |
| 475 FIELD_LEN(kernel_key_version)); | 558 FIELD_LEN(kernel_key_version)); |
| 476 DigestUpdate(&ctx, image->kernel_sign_key, | 559 DigestUpdate(&ctx, image->kernel_sign_key, |
| 477 RSAProcessedKeySize(image->kernel_sign_algorithm)); | 560 RSAProcessedKeySize(image->kernel_sign_algorithm)); |
| 478 DigestUpdate(&ctx, image->header_checksum, | 561 DigestUpdate(&ctx, image->header_checksum, |
| 479 FIELD_LEN(header_checksum)); | 562 FIELD_LEN(header_checksum)); |
| 480 header_digest = DigestFinal(&ctx); | 563 header_digest = DigestFinal(&ctx); |
| 481 if (!RSA_verify(firmware_key, image->kernel_key_signature, | 564 if (!RSAVerify(firmware_key, image->kernel_key_signature, |
| 482 siglen_map[image->firmware_sign_algorithm], | 565 siglen_map[image->firmware_sign_algorithm], |
| 483 image->firmware_sign_algorithm, | 566 image->firmware_sign_algorithm, |
| 484 header_digest)) { | 567 header_digest)) { |
| 485 fprintf(stderr, "VerifyKernelImage(): Key signature check failed.\n"); | 568 fprintf(stderr, "VerifyKernelImage(): Key signature check failed.\n"); |
| 486 error_code = VERIFY_KERNEL_KEY_SIGNATURE_FAILED; | 569 error_code = VERIFY_KERNEL_KEY_SIGNATURE_FAILED; |
| 487 goto verify_failure; | 570 goto verify_failure; |
| 488 } | 571 } |
| 489 } | 572 } |
| 490 | 573 |
| 491 /* Get kernel signing key to verify the rest of the kernel. */ | 574 /* Get kernel signing key to verify the rest of the kernel. */ |
| 492 kernel_sign_key_size = RSAProcessedKeySize(image->kernel_sign_algorithm); | 575 kernel_sign_key_size = RSAProcessedKeySize(image->kernel_sign_algorithm); |
| 493 kernel_sign_key = RSAPublicKeyFromBuf(image->kernel_sign_key, | 576 kernel_sign_key = RSAPublicKeyFromBuf(image->kernel_sign_key, |
| 494 kernel_sign_key_size); | 577 kernel_sign_key_size); |
| 495 kernel_signature_size = siglen_map[image->kernel_sign_algorithm]; | 578 kernel_signature_size = siglen_map[image->kernel_sign_algorithm]; |
| 496 | 579 |
| 497 /* Verify kernel config signature. */ | 580 /* Verify kernel config signature. */ |
| 498 DigestInit(&ctx, image->kernel_sign_algorithm); | 581 DigestInit(&ctx, image->kernel_sign_algorithm); |
| 499 DigestUpdate(&ctx, (uint8_t*) &image->kernel_version, | 582 DigestUpdate(&ctx, (uint8_t*) &image->kernel_version, |
| 500 FIELD_LEN(kernel_version)); | 583 FIELD_LEN(kernel_version)); |
| 501 DigestUpdate(&ctx, (uint8_t*) &image->options.version, | 584 DigestUpdate(&ctx, (uint8_t*) &image->options.version, |
| 502 FIELD_LEN(options.version)); | 585 FIELD_LEN(options.version)); |
| 503 DigestUpdate(&ctx, (uint8_t*) &image->options.kernel_len, | 586 DigestUpdate(&ctx, (uint8_t*) &image->options.kernel_len, |
| 504 FIELD_LEN(options.kernel_len)); | 587 FIELD_LEN(options.kernel_len)); |
| 505 DigestUpdate(&ctx, (uint8_t*) &image->options.kernel_load_addr, | 588 DigestUpdate(&ctx, (uint8_t*) &image->options.kernel_load_addr, |
| 506 FIELD_LEN(options.kernel_load_addr)); | 589 FIELD_LEN(options.kernel_load_addr)); |
| 507 DigestUpdate(&ctx, (uint8_t*) &image->options.kernel_entry_addr, | 590 DigestUpdate(&ctx, (uint8_t*) &image->options.kernel_entry_addr, |
| 508 FIELD_LEN(options.kernel_entry_addr)); | 591 FIELD_LEN(options.kernel_entry_addr)); |
| 509 config_digest = DigestFinal(&ctx); | 592 config_digest = DigestFinal(&ctx); |
| 510 if (!RSA_verify(kernel_sign_key, image->config_signature, | 593 if (!RSAVerify(kernel_sign_key, image->config_signature, |
| 511 kernel_signature_size, image->kernel_sign_algorithm, | 594 kernel_signature_size, image->kernel_sign_algorithm, |
| 512 config_digest)) { | 595 config_digest)) { |
| 513 error_code = VERIFY_KERNEL_CONFIG_SIGNATURE_FAILED; | 596 error_code = VERIFY_KERNEL_CONFIG_SIGNATURE_FAILED; |
| 514 goto verify_failure; | 597 goto verify_failure; |
| 515 } | 598 } |
| 516 | 599 |
| 517 /* Verify firmware signature. */ | 600 /* Verify firmware signature. */ |
| 518 kernel_digest = DigestBuf(image->kernel_data, | 601 kernel_digest = DigestBuf(image->kernel_data, |
| 519 image->options.kernel_len, | 602 image->options.kernel_len, |
| 520 image->kernel_sign_algorithm); | 603 image->kernel_sign_algorithm); |
| 521 if(!RSA_verify(kernel_sign_key, image->kernel_signature, | 604 if (!RSAVerify(kernel_sign_key, image->kernel_signature, |
| 522 kernel_signature_size, image->kernel_sign_algorithm, | 605 kernel_signature_size, image->kernel_sign_algorithm, |
| 523 kernel_digest)) { | 606 kernel_digest)) { |
| 524 error_code = VERIFY_KERNEL_SIGNATURE_FAILED; | 607 error_code = VERIFY_KERNEL_SIGNATURE_FAILED; |
| 525 goto verify_failure; | 608 goto verify_failure; |
| 526 } | 609 } |
| 527 | 610 |
| 528 verify_failure: | 611 verify_failure: |
| 529 Free(kernel_digest); | 612 Free(kernel_digest); |
| 530 Free(config_digest); | 613 Free(config_digest); |
| 531 Free(header_digest); | 614 Free(header_digest); |
| 532 return error_code; | 615 return error_code; |
| 533 } | 616 } |
| 534 | 617 |
| 535 const char* VerifyKernelErrorString(int error) { | 618 const char* VerifyKernelErrorString(int error) { |
| 536 return kVerifyKernelErrors[error]; | 619 return kVerifyKernelErrors[error]; |
| 537 } | 620 } |
| 538 | 621 |
| 539 int AddKernelKeySignature(KernelImage* image, const char* firmware_key_file) { | 622 int AddKernelKeySignature(KernelImage* image, const char* firmware_key_file) { |
| 540 int tmp_hdr_fd; | 623 uint8_t* header_blob = NULL; |
| 541 char* tmp_hdr_file = ".tmpKernelHdrFile"; | |
| 542 uint8_t* signature; | 624 uint8_t* signature; |
| 543 int signature_len = siglen_map[image->firmware_sign_algorithm]; | 625 int signature_len = siglen_map[image->firmware_sign_algorithm]; |
| 544 | 626 if (!image || !firmware_key_file) |
| 545 if(-1 == (tmp_hdr_fd = creat(tmp_hdr_file, S_IRWXU))) { | 627 return 0; |
| 546 fprintf(stderr, "Could not open temporary file for writing " | 628 header_blob = GetKernelHeaderBlob(image); |
| 547 "kernel header.\n"); | 629 if (!header_blob) |
| 630 return 0; |
| 631 if (!(signature = SignatureBuf(header_blob, |
| 632 GetKernelHeaderLen(image), |
| 633 firmware_key_file, |
| 634 image->firmware_sign_algorithm))) { |
| 635 Free(header_blob); |
| 548 return 0; | 636 return 0; |
| 549 } | 637 } |
| 550 WriteKernelHeader(tmp_hdr_fd, image); | |
| 551 close(tmp_hdr_fd); | |
| 552 if (!(signature = SignatureFile(tmp_hdr_file, firmware_key_file, | |
| 553 image->firmware_sign_algorithm))) | |
| 554 return 0; | |
| 555 image->kernel_key_signature = Malloc(signature_len); | 638 image->kernel_key_signature = Malloc(signature_len); |
| 556 Memcpy(image->kernel_key_signature, signature, signature_len); | 639 Memcpy(image->kernel_key_signature, signature, signature_len); |
| 640 Free(signature); |
| 641 Free(header_blob); |
| 557 return 1; | 642 return 1; |
| 558 } | 643 } |
| 559 | 644 |
| 560 int AddKernelSignature(KernelImage* image, const char* kernel_signing_key_file, | 645 int AddKernelSignature(KernelImage* image, |
| 561 int algorithm) { | 646 const char* kernel_signing_key_file) { |
| 562 int tmp_config_fd; | 647 uint8_t* config_blob; |
| 563 char* tmp_config_file = ".tmpConfigFile"; | |
| 564 int tmp_kernel_fd; | |
| 565 char* tmp_kernel_file = ".tmpKernelFile"; | |
| 566 uint8_t* config_signature; | 648 uint8_t* config_signature; |
| 567 uint8_t* kernel_signature; | 649 uint8_t* kernel_signature; |
| 568 int signature_len = siglen_map[algorithm]; | 650 int signature_len = siglen_map[image->kernel_sign_algorithm]; |
| 569 | 651 |
| 570 /* Write config to a file. */ | 652 config_blob = GetKernelConfigBlob(image); |
| 571 if(-1 == (tmp_config_fd = creat(tmp_config_file, S_IRWXU))) { | 653 if (!(config_signature = SignatureBuf(config_blob, |
| 572 fprintf(stderr, "Could not open temporary file for writing " | 654 GetKernelConfigLen(image), |
| 573 "kernel config.\n"); | 655 kernel_signing_key_file, |
| 656 image->kernel_sign_algorithm))) { |
| 657 fprintf(stderr, "Could not compute signature on the kernel config.\n"); |
| 658 Free(config_blob); |
| 574 return 0; | 659 return 0; |
| 575 } | 660 } |
| 576 WriteKernelConfig(tmp_config_fd, image); | 661 |
| 577 close(tmp_config_fd); | |
| 578 if (!(config_signature = SignatureFile(tmp_config_file, | |
| 579 kernel_signing_key_file, | |
| 580 algorithm))) | |
| 581 return 0; | |
| 582 image->config_signature = (uint8_t*) Malloc(signature_len); | 662 image->config_signature = (uint8_t*) Malloc(signature_len); |
| 583 Memcpy(image->config_signature, config_signature, signature_len); | 663 Memcpy(image->config_signature, config_signature, signature_len); |
| 584 Free(config_signature); | 664 Free(config_signature); |
| 585 | 665 |
| 586 if (-1 == (tmp_kernel_fd = creat(tmp_kernel_file, S_IRWXU))) { | 666 if (!(kernel_signature = SignatureBuf(image->kernel_data, |
| 587 fprintf(stderr, "Could not open temporary file for writing " | 667 image->options.kernel_len, |
| 588 "kernel.\n"); | 668 kernel_signing_key_file, |
| 589 return 0; | 669 image->kernel_sign_algorithm))) { |
| 590 } | |
| 591 write(tmp_kernel_fd, image->kernel_data, image->options.kernel_len); | |
| 592 close(tmp_kernel_fd); | |
| 593 | |
| 594 if (!(kernel_signature = SignatureFile(tmp_kernel_file, | |
| 595 kernel_signing_key_file, | |
| 596 algorithm))) { | |
| 597 fprintf(stderr, "Could not compute signature on the kernel.\n"); | 670 fprintf(stderr, "Could not compute signature on the kernel.\n"); |
| 598 return 0; | 671 return 0; |
| 599 } | 672 } |
| 600 image->kernel_signature = (uint8_t*) Malloc(signature_len); | 673 image->kernel_signature = (uint8_t*) Malloc(signature_len); |
| 601 Memcpy(image->kernel_signature, kernel_signature, signature_len); | 674 Memcpy(image->kernel_signature, kernel_signature, signature_len); |
| 602 Free(kernel_signature); | 675 Free(kernel_signature); |
| 603 return 1; | 676 return 1; |
| 604 } | 677 } |
| OLD | NEW |