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 |