OLD | NEW |
(Empty) | |
| 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 |
| 3 * found in the LICENSE file. |
| 4 * |
| 5 * Tests for kernel image library. |
| 6 */ |
| 7 |
| 8 #include <stdio.h> |
| 9 #include <stdlib.h> |
| 10 |
| 11 #include "file_keys.h" |
| 12 #include "kernel_image.h" |
| 13 #include "rsa_utility.h" |
| 14 #include "sha_utility.h" |
| 15 #include "utility.h" |
| 16 |
| 17 /* ANSI Color coding sequences. */ |
| 18 #define COL_GREEN "\e[1;32m" |
| 19 #define COL_RED "\e[0;31m" |
| 20 #define COL_STOP "\e[m" |
| 21 |
| 22 int TEST_EQ(int result, int expected_result, char* testname) { |
| 23 if (result == expected_result) { |
| 24 fprintf(stderr, "%s Test " COL_GREEN " PASSED\n" COL_STOP, testname); |
| 25 return 1; |
| 26 } |
| 27 else { |
| 28 fprintf(stderr, "%s Test " COL_RED " FAILED\n" COL_STOP, testname); |
| 29 return 0; |
| 30 } |
| 31 } |
| 32 |
| 33 KernelImage* GenerateTestKernelImage(int firmware_sign_algorithm, |
| 34 int kernel_sign_algorithm, |
| 35 uint8_t* kernel_sign_key, |
| 36 int kernel_key_version, |
| 37 int kernel_version, |
| 38 int kernel_len) { |
| 39 KernelImage* image = KernelImageNew(); |
| 40 uint8_t* header_checksum; |
| 41 DigestContext ctx; |
| 42 |
| 43 Memcpy(image->magic, KERNEL_MAGIC, KERNEL_MAGIC_SIZE); |
| 44 image->header_version = 1; |
| 45 image->firmware_sign_algorithm = firmware_sign_algorithm; |
| 46 image->kernel_sign_algorithm = kernel_sign_algorithm; |
| 47 image->kernel_key_version = kernel_key_version; |
| 48 image->kernel_sign_key = (uint8_t*) Malloc( |
| 49 RSAProcessedKeySize(image->kernel_sign_algorithm)); |
| 50 Memcpy(image->kernel_sign_key, kernel_sign_key, |
| 51 RSAProcessedKeySize(image->kernel_sign_algorithm)); |
| 52 |
| 53 /* Update correct header length. */ |
| 54 image->header_len = (sizeof(image->header_version) + |
| 55 sizeof(image->header_len) + |
| 56 sizeof(image->firmware_sign_algorithm) + |
| 57 sizeof(image->kernel_sign_algorithm) + |
| 58 RSAProcessedKeySize(image->kernel_sign_algorithm) + |
| 59 sizeof(image->kernel_key_version) + |
| 60 sizeof(image->header_checksum)); |
| 61 |
| 62 /* Calculate SHA-512 digest on header and populate header_checksum. */ |
| 63 DigestInit(&ctx, SHA512_DIGEST_ALGORITHM); |
| 64 DigestUpdate(&ctx, (uint8_t*) &image->header_version, |
| 65 sizeof(image->header_version)); |
| 66 DigestUpdate(&ctx, (uint8_t*) &image->header_len, |
| 67 sizeof(image->header_len)); |
| 68 DigestUpdate(&ctx, (uint8_t*) &image->firmware_sign_algorithm, |
| 69 sizeof(image->firmware_sign_algorithm)); |
| 70 DigestUpdate(&ctx, (uint8_t*) &image->kernel_sign_algorithm, |
| 71 sizeof(image->kernel_sign_algorithm)); |
| 72 DigestUpdate(&ctx, (uint8_t*) &image->kernel_key_version, |
| 73 sizeof(image->kernel_key_version)); |
| 74 DigestUpdate(&ctx, image->kernel_sign_key, |
| 75 RSAProcessedKeySize(image->kernel_sign_algorithm)); |
| 76 header_checksum = DigestFinal(&ctx); |
| 77 Memcpy(image->header_checksum, header_checksum, SHA512_DIGEST_SIZE); |
| 78 Free(header_checksum); |
| 79 |
| 80 /* Populate kernel options and data with dummy data. */ |
| 81 image->kernel_version = kernel_version; |
| 82 image->options.version[0] = 1; |
| 83 image->options.version[1] = 1; |
| 84 image->options.kernel_len = kernel_len; |
| 85 image->options.kernel_load_addr = 0; |
| 86 image->options.kernel_entry_addr = 0; |
| 87 image->kernel_key_signature = image->kernel_signature = NULL; |
| 88 image->kernel_data = Malloc(kernel_len); |
| 89 Memset(image->kernel_data, 'F', kernel_len); |
| 90 |
| 91 return image; |
| 92 } |
| 93 |
| 94 #define DEV_MODE_ENABLED 1 |
| 95 #define DEV_MODE_DISABLED 0 |
| 96 |
| 97 /* Normal Kernel Blob Verification Tests. */ |
| 98 int VerifyKernelTest(uint8_t* kernel_blob, uint8_t* firmware_key_blob) { |
| 99 int success = 1; |
| 100 if (!TEST_EQ(VerifyKernel(firmware_key_blob, kernel_blob, DEV_MODE_ENABLED), |
| 101 VERIFY_KERNEL_SUCCESS, |
| 102 "Normal Kernel Blob Verification (Dev Mode)")) |
| 103 success = 0; |
| 104 |
| 105 if (!TEST_EQ(VerifyKernel(firmware_key_blob, kernel_blob, DEV_MODE_DISABLED), |
| 106 VERIFY_KERNEL_SUCCESS, |
| 107 "Normal Kernel Blob Verification (Trusted)")) |
| 108 success = 0; |
| 109 return success; |
| 110 } |
| 111 |
| 112 |
| 113 /* Normal KernelImage Verification Tests. */ |
| 114 int VerifyKernelImageTest(KernelImage* image, |
| 115 RSAPublicKey* firmware_key) { |
| 116 int success = 1; |
| 117 if (!TEST_EQ(VerifyKernelImage(firmware_key, image, DEV_MODE_ENABLED), |
| 118 VERIFY_KERNEL_SUCCESS, |
| 119 "Normal KernelImage Verification (Dev Mode)")) |
| 120 success = 0; |
| 121 |
| 122 if (!TEST_EQ(VerifyKernelImage(firmware_key, image, DEV_MODE_DISABLED), |
| 123 VERIFY_KERNEL_SUCCESS, |
| 124 "Normal KernelImage Verification (Trusted)")) |
| 125 success = 0; |
| 126 return success; |
| 127 } |
| 128 |
| 129 /* Tampered KernelImage Verification Tests. */ |
| 130 int VerifyKernelImageTamperTest(KernelImage* image, |
| 131 RSAPublicKey* firmware_key) { |
| 132 int success = 1; |
| 133 fprintf(stderr, "[[Tampering with kernel config....]]\n"); |
| 134 image->options.kernel_load_addr = 0xFFFF; |
| 135 if (!TEST_EQ(VerifyKernelImage(firmware_key, image, DEV_MODE_ENABLED), |
| 136 VERIFY_KERNEL_CONFIG_SIGNATURE_FAILED, |
| 137 "KernelImage Config Tamper Verification (Dev Mode)")) |
| 138 success = 0; |
| 139 if (!TEST_EQ(VerifyKernelImage(firmware_key, image, DEV_MODE_DISABLED), |
| 140 VERIFY_KERNEL_CONFIG_SIGNATURE_FAILED, |
| 141 "KernelImage Config Tamper Verification (Trusted)")) |
| 142 success = 0; |
| 143 image->options.kernel_load_addr = 0; |
| 144 |
| 145 image->kernel_data[0] = 'T'; |
| 146 if (!TEST_EQ(VerifyKernelImage(firmware_key, image, DEV_MODE_ENABLED), |
| 147 VERIFY_KERNEL_SIGNATURE_FAILED, |
| 148 "KernelImage Tamper Verification (Dev Mode)")) |
| 149 success = 0; |
| 150 if (!TEST_EQ(VerifyKernelImage(firmware_key, image, DEV_MODE_DISABLED), |
| 151 VERIFY_KERNEL_SIGNATURE_FAILED, |
| 152 "KernelImage Tamper Verification (Trusted)")) |
| 153 success = 0; |
| 154 image->kernel_data[0] = 'F'; |
| 155 |
| 156 |
| 157 fprintf(stderr, "[[Tampering with kernel key signature...]]\n"); |
| 158 image->kernel_key_signature[0] = 0xFF; |
| 159 image->kernel_key_signature[1] = 0x00; |
| 160 if (!TEST_EQ(VerifyKernelImage(firmware_key, image, DEV_MODE_ENABLED), |
| 161 VERIFY_KERNEL_SUCCESS, |
| 162 "KernelImage Key Signature Tamper Verification (Dev Mode)")) |
| 163 success = 0; |
| 164 if (!TEST_EQ(VerifyKernelImage(firmware_key, image, DEV_MODE_DISABLED), |
| 165 VERIFY_KERNEL_KEY_SIGNATURE_FAILED, |
| 166 "KernelImage Key Signature Tamper Verification (Trusted)")) |
| 167 success = 0; |
| 168 |
| 169 return success; |
| 170 } |
| 171 |
| 172 int main(int argc, char* argv[]) { |
| 173 uint32_t len; |
| 174 uint8_t* kernel_sign_key_buf = NULL; |
| 175 uint8_t* firmware_key_blob = NULL; |
| 176 uint8_t* kernel_blob = NULL; |
| 177 KernelImage* image = NULL; |
| 178 RSAPublicKey* firmware_key = NULL; |
| 179 int error_code = 1; |
| 180 char* tmp_kernelblob_file = ".tmpKernelBlob"; |
| 181 |
| 182 if(argc != 7) { |
| 183 fprintf(stderr, "Usage: %s <firmware signing algorithm> " /* argv[1] */ |
| 184 "<kernel signing algorithm> " /* argv[2] */ |
| 185 "<firmware key> " /* argv[3] */ |
| 186 "<processed firmware pubkey> " /* argv[4] */ |
| 187 "<kernel signing key> " /* argv[5] */ |
| 188 "<processed kernel signing key>\n", /* argv[6] */ |
| 189 argv[0]); |
| 190 return -1; |
| 191 } |
| 192 |
| 193 /* Read verification keys and create a test image. */ |
| 194 firmware_key = RSAPublicKeyFromFile(argv[4]); |
| 195 firmware_key_blob = BufferFromFile(argv[4], &len); |
| 196 kernel_sign_key_buf = BufferFromFile(argv[6], &len); |
| 197 if (!firmware_key || !kernel_sign_key_buf || !kernel_sign_key_buf) { |
| 198 error_code = 1; |
| 199 goto failure; |
| 200 } |
| 201 |
| 202 image = GenerateTestKernelImage(atoi(argv[1]), |
| 203 atoi(argv[2]), |
| 204 kernel_sign_key_buf, |
| 205 1, /* Kernel Key Version */ |
| 206 1, /* Kernel Version */ |
| 207 1000); /* Kernel Size */ |
| 208 if (!image) { |
| 209 error_code = 1; |
| 210 goto failure; |
| 211 } |
| 212 |
| 213 /* Generate and populate signatures. */ |
| 214 if (!AddKernelKeySignature(image, argv[3])) { |
| 215 fprintf(stderr, "Couldn't create key signature.\n"); |
| 216 error_code = 1; |
| 217 goto failure; |
| 218 } |
| 219 |
| 220 if (!AddKernelSignature(image, argv[5], image->kernel_sign_algorithm)) { |
| 221 fprintf(stderr, "Couldn't create firmware and preamble signature.\n"); |
| 222 error_code = 1; |
| 223 goto failure; |
| 224 } |
| 225 |
| 226 /* Generate a firmware binary blob from image. |
| 227 * |
| 228 * TODO(gauravsh): Add a function to directly generate a binary |
| 229 * blob buffer from a KernelImage instead of indirectly writing to a file |
| 230 * and reading it into a buffer. |
| 231 */ |
| 232 if (!WriteKernelImage(tmp_kernelblob_file, image)) { |
| 233 fprintf(stderr, "Couldn't create a temporary kernel blob file.\n"); |
| 234 error_code = 1; |
| 235 goto failure; |
| 236 } |
| 237 kernel_blob = BufferFromFile(tmp_kernelblob_file, &len); |
| 238 |
| 239 /* Test Kernel blob verify operations. */ |
| 240 if (!VerifyKernelTest(kernel_blob, firmware_key_blob)) |
| 241 error_code = 255; |
| 242 |
| 243 /* Test KernelImage verify operations. */ |
| 244 if (!VerifyKernelImageTest(image, firmware_key)) |
| 245 error_code = 255; |
| 246 if (!VerifyKernelImageTamperTest(image, firmware_key)) |
| 247 error_code = 255; |
| 248 |
| 249 failure: |
| 250 Free(kernel_blob); |
| 251 KernelImageFree(image); |
| 252 Free(kernel_sign_key_buf); |
| 253 Free(firmware_key_blob); |
| 254 Free(firmware_key); |
| 255 |
| 256 return error_code; |
| 257 } |
OLD | NEW |