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 firmware image library. |
| 6 */ |
| 7 |
| 8 #include <stdio.h> |
| 9 #include <stdlib.h> |
| 10 |
| 11 #include "cryptolib.h" |
| 12 #include "file_keys.h" |
| 13 #include "firmware_image.h" |
| 14 #include "host_common.h" |
| 15 #include "test_common.h" |
| 16 #include "utility.h" |
| 17 #include "vboot_common.h" |
| 18 |
| 19 |
| 20 static void ReChecksumKeyBlock(VbKeyBlockHeader *h) { |
| 21 uint8_t* newchk = DigestBuf((const uint8_t*)h, |
| 22 h->key_block_checksum.data_size, |
| 23 SHA512_DIGEST_ALGORITHM); |
| 24 Memcpy(GetSignatureData(&h->key_block_checksum), newchk, SHA512_DIGEST_SIZE); |
| 25 Free(newchk); |
| 26 } |
| 27 |
| 28 |
| 29 static void VerifyKeyBlockTest(const VbPublicKey* public_key, |
| 30 const VbPrivateKey* private_key, |
| 31 const VbPublicKey* data_key) { |
| 32 |
| 33 VbKeyBlockHeader *hdr; |
| 34 VbKeyBlockHeader *h; |
| 35 uint64_t hsize; |
| 36 |
| 37 hdr = CreateKeyBlock(data_key, private_key, 0x1234); |
| 38 TEST_NEQ((size_t)hdr, 0, "VerifyKeyBlock() prerequisites"); |
| 39 if (!hdr) |
| 40 return; |
| 41 hsize = hdr->key_block_size; |
| 42 h = (VbKeyBlockHeader*)Malloc(hsize + 1024); |
| 43 |
| 44 TEST_EQ(VerifyKeyBlock(hdr, hsize, NULL), 0, |
| 45 "VerifyKeyBlock() ok using checksum"); |
| 46 TEST_EQ(VerifyKeyBlock(hdr, hsize, public_key), 0, |
| 47 "VerifyKeyBlock() ok using key"); |
| 48 |
| 49 TEST_NEQ(VerifyKeyBlock(hdr, hsize-1, NULL), 0, "VerifyKeyBlock() size"); |
| 50 |
| 51 Memcpy(h, hdr, hsize); |
| 52 h->magic[0] &= 0x12; |
| 53 TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, "VerifyKeyBlock() magic"); |
| 54 |
| 55 /* Care about major version but not minor */ |
| 56 Memcpy(h, hdr, hsize); |
| 57 h->header_version_major++; |
| 58 ReChecksumKeyBlock(h); |
| 59 TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, "VerifyKeyBlock() major++"); |
| 60 |
| 61 Memcpy(h, hdr, hsize); |
| 62 h->header_version_major--; |
| 63 ReChecksumKeyBlock(h); |
| 64 TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, "VerifyKeyBlock() major--"); |
| 65 |
| 66 Memcpy(h, hdr, hsize); |
| 67 h->header_version_minor++; |
| 68 ReChecksumKeyBlock(h); |
| 69 TEST_EQ(VerifyKeyBlock(h, hsize, NULL), 0, "VerifyKeyBlock() minor++"); |
| 70 |
| 71 Memcpy(h, hdr, hsize); |
| 72 h->header_version_minor--; |
| 73 ReChecksumKeyBlock(h); |
| 74 TEST_EQ(VerifyKeyBlock(h, hsize, NULL), 0, "VerifyKeyBlock() minor--"); |
| 75 |
| 76 /* Check hash */ |
| 77 Memcpy(h, hdr, hsize); |
| 78 h->key_block_checksum.sig_offset = hsize; |
| 79 ReChecksumKeyBlock(h); |
| 80 TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, |
| 81 "VerifyKeyBlock() checksum off end"); |
| 82 |
| 83 Memcpy(h, hdr, hsize); |
| 84 h->key_block_checksum.sig_size /= 2; |
| 85 ReChecksumKeyBlock(h); |
| 86 TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, |
| 87 "VerifyKeyBlock() checksum too small"); |
| 88 |
| 89 Memcpy(h, hdr, hsize); |
| 90 GetPublicKeyData(&h->data_key)[0] ^= 0x34; |
| 91 TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, |
| 92 "VerifyKeyBlock() checksum mismatch"); |
| 93 |
| 94 /* Check signature */ |
| 95 Memcpy(h, hdr, hsize); |
| 96 h->key_block_signature.sig_offset = hsize; |
| 97 ReChecksumKeyBlock(h); |
| 98 TEST_NEQ(VerifyKeyBlock(h, hsize, public_key), 0, |
| 99 "VerifyKeyBlock() sig off end"); |
| 100 |
| 101 Memcpy(h, hdr, hsize); |
| 102 h->key_block_signature.sig_size--; |
| 103 ReChecksumKeyBlock(h); |
| 104 TEST_NEQ(VerifyKeyBlock(h, hsize, public_key), 0, |
| 105 "VerifyKeyBlock() sig too small"); |
| 106 |
| 107 Memcpy(h, hdr, hsize); |
| 108 GetPublicKeyData(&h->data_key)[0] ^= 0x34; |
| 109 TEST_NEQ(VerifyKeyBlock(h, hsize, public_key), 0, |
| 110 "VerifyKeyBlock() sig mismatch"); |
| 111 |
| 112 /* Check that we signed header and data key */ |
| 113 Memcpy(h, hdr, hsize); |
| 114 h->key_block_checksum.data_size = 4; |
| 115 h->data_key.key_offset = 0; |
| 116 h->data_key.key_size = 0; |
| 117 ReChecksumKeyBlock(h); |
| 118 TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, |
| 119 "VerifyKeyBlock() didn't sign header"); |
| 120 |
| 121 Memcpy(h, hdr, hsize); |
| 122 h->data_key.key_offset = hsize; |
| 123 ReChecksumKeyBlock(h); |
| 124 TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, |
| 125 "VerifyKeyBlock() data key off end"); |
| 126 |
| 127 /* TODO: verify parser can support a bigger header (i.e., one where |
| 128 * data_key.key_offset is bigger than expected). */ |
| 129 |
| 130 Free(h); |
| 131 Free(hdr); |
| 132 } |
| 133 |
| 134 |
| 135 static void ReSignFirmwarePreamble(VbFirmwarePreambleHeader *h, |
| 136 const VbPrivateKey *key) { |
| 137 VbSignature *sig = CalculateSignature((const uint8_t*)h, |
| 138 h->preamble_signature.data_size, key); |
| 139 |
| 140 SignatureCopy(&h->preamble_signature, sig); |
| 141 Free(sig); |
| 142 } |
| 143 |
| 144 |
| 145 static void VerifyFirmwarePreambleTest(const VbPublicKey* public_key, |
| 146 const VbPrivateKey* private_key, |
| 147 const VbPublicKey* kernel_subkey) { |
| 148 |
| 149 VbFirmwarePreambleHeader *hdr; |
| 150 VbFirmwarePreambleHeader *h; |
| 151 RSAPublicKey* rsa; |
| 152 uint64_t hsize; |
| 153 |
| 154 /* Create a dummy signature */ |
| 155 VbSignature *body_sig = SignatureAlloc(56, 78); |
| 156 |
| 157 rsa = PublicKeyToRSA(public_key); |
| 158 hdr = CreateFirmwarePreamble(0x1234, kernel_subkey, body_sig, private_key); |
| 159 TEST_NEQ(hdr && rsa, 0, "VerifyFirmwarePreamble2() prerequisites"); |
| 160 if (!hdr) |
| 161 return; |
| 162 hsize = hdr->preamble_size; |
| 163 h = (VbFirmwarePreambleHeader*)Malloc(hsize + 16384); |
| 164 |
| 165 TEST_EQ(VerifyFirmwarePreamble2(hdr, hsize, rsa), 0, |
| 166 "VerifyFirmwarePreamble2() ok using key"); |
| 167 TEST_NEQ(VerifyFirmwarePreamble2(hdr, hsize-1, rsa), 0, |
| 168 "VerifyFirmwarePreamble2() size"); |
| 169 |
| 170 /* Care about major version but not minor */ |
| 171 Memcpy(h, hdr, hsize); |
| 172 h->header_version_major++; |
| 173 ReSignFirmwarePreamble(h, private_key); |
| 174 TEST_NEQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0, |
| 175 "VerifyFirmwarePreamble2() major++"); |
| 176 |
| 177 Memcpy(h, hdr, hsize); |
| 178 h->header_version_major--; |
| 179 ReSignFirmwarePreamble(h, private_key); |
| 180 TEST_NEQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0, |
| 181 "VerifyFirmwarePreamble2() major--"); |
| 182 |
| 183 Memcpy(h, hdr, hsize); |
| 184 h->header_version_minor++; |
| 185 ReSignFirmwarePreamble(h, private_key); |
| 186 TEST_EQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0, |
| 187 "VerifyFirmwarePreamble2() minor++"); |
| 188 |
| 189 Memcpy(h, hdr, hsize); |
| 190 h->header_version_minor--; |
| 191 ReSignFirmwarePreamble(h, private_key); |
| 192 TEST_EQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0, |
| 193 "VerifyFirmwarePreamble2() minor--"); |
| 194 |
| 195 /* Check signature */ |
| 196 Memcpy(h, hdr, hsize); |
| 197 h->preamble_signature.sig_offset = hsize; |
| 198 ReSignFirmwarePreamble(h, private_key); |
| 199 TEST_NEQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0, |
| 200 "VerifyFirmwarePreamble2() sig off end"); |
| 201 |
| 202 Memcpy(h, hdr, hsize); |
| 203 h->preamble_signature.sig_size--; |
| 204 ReSignFirmwarePreamble(h, private_key); |
| 205 TEST_NEQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0, |
| 206 "VerifyFirmwarePreamble2() sig too small"); |
| 207 |
| 208 Memcpy(h, hdr, hsize); |
| 209 GetPublicKeyData(&h->kernel_subkey)[0] ^= 0x34; |
| 210 TEST_NEQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0, |
| 211 "VerifyFirmwarePreamble2() sig mismatch"); |
| 212 |
| 213 /* Check that we signed header, kernel subkey, and body sig */ |
| 214 Memcpy(h, hdr, hsize); |
| 215 h->preamble_signature.data_size = 4; |
| 216 h->kernel_subkey.key_offset = 0; |
| 217 h->kernel_subkey.key_size = 0; |
| 218 h->body_signature.sig_offset = 0; |
| 219 h->body_signature.sig_size = 0; |
| 220 ReSignFirmwarePreamble(h, private_key); |
| 221 TEST_NEQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0, |
| 222 "VerifyFirmwarePreamble2() didn't sign header"); |
| 223 |
| 224 Memcpy(h, hdr, hsize); |
| 225 h->kernel_subkey.key_offset = hsize; |
| 226 ReSignFirmwarePreamble(h, private_key); |
| 227 TEST_NEQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0, |
| 228 "VerifyFirmwarePreamble2() kernel subkey off end"); |
| 229 |
| 230 Memcpy(h, hdr, hsize); |
| 231 h->body_signature.sig_offset = hsize; |
| 232 ReSignFirmwarePreamble(h, private_key); |
| 233 TEST_NEQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0, |
| 234 "VerifyFirmwarePreamble2() body sig off end"); |
| 235 |
| 236 /* TODO: verify parser can support a bigger header. */ |
| 237 |
| 238 Free(h); |
| 239 RSAPublicKeyFree(rsa); |
| 240 Free(hdr); |
| 241 } |
| 242 |
| 243 |
| 244 int main(int argc, char* argv[]) { |
| 245 VbPrivateKey* signing_private_key = NULL; |
| 246 VbPublicKey* signing_public_key = NULL; |
| 247 int signing_key_algorithm; |
| 248 |
| 249 VbPublicKey* data_public_key = NULL; |
| 250 int data_key_algorithm; |
| 251 |
| 252 int error_code = 0; |
| 253 |
| 254 if(argc != 7) { |
| 255 fprintf(stderr, "Usage: %s <signing_key_algorithm> <data_key_algorithm>" |
| 256 " <signing key> <processed signing pubkey>" |
| 257 " <data key> <processed data pubkey>\n", argv[0]); |
| 258 return -1; |
| 259 } |
| 260 |
| 261 /* Read verification keys and create a test image. */ |
| 262 signing_key_algorithm = atoi(argv[1]); |
| 263 data_key_algorithm = atoi(argv[2]); |
| 264 |
| 265 signing_private_key = PrivateKeyRead(argv[3], signing_key_algorithm); |
| 266 if (!signing_private_key) { |
| 267 fprintf(stderr, "Error reading signing_private_key"); |
| 268 return 1; |
| 269 } |
| 270 |
| 271 signing_public_key = PublicKeyRead(argv[4], signing_key_algorithm, 1); |
| 272 if (!signing_public_key) { |
| 273 fprintf(stderr, "Error reading signing_public_key"); |
| 274 return 1; |
| 275 } |
| 276 |
| 277 data_public_key = PublicKeyRead(argv[6], data_key_algorithm, 1); |
| 278 if (!data_public_key) { |
| 279 fprintf(stderr, "Error reading data_public_key"); |
| 280 return 1; |
| 281 } |
| 282 |
| 283 VerifyKeyBlockTest(signing_public_key, signing_private_key, data_public_key); |
| 284 VerifyFirmwarePreambleTest(signing_public_key, signing_private_key, |
| 285 data_public_key); |
| 286 |
| 287 if (signing_public_key) |
| 288 Free(signing_public_key); |
| 289 if (signing_private_key) |
| 290 Free(signing_private_key); |
| 291 if (data_public_key) |
| 292 Free(data_public_key); |
| 293 |
| 294 return error_code; |
| 295 } |
OLD | NEW |