Home | History | Annotate | Download | only in lib
      1 /* Copyright (c) 2013 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  * Common functions between firmware and kernel verified boot.
      6  * (Firmware portion)
      7  */
      8 
      9 #include "sysincludes.h"
     10 
     11 #include "vboot_api.h"
     12 #include "vboot_common.h"
     13 #include "utility.h"
     14 
     15 const char *kVbootErrors[VBOOT_ERROR_MAX] = {
     16 	"Success.",
     17 	"Key block invalid.",
     18 	"Key block signature failed.",
     19 	"Key block hash failed.",
     20 	"Public key invalid.",
     21 	"Preamble invalid.",
     22 	"Preamble signature check failed.",
     23 	"Shared data invalid."
     24 };
     25 
     26 uint64_t OffsetOf(const void *base, const void *ptr)
     27 {
     28 	return (uint64_t)(size_t)ptr - (uint64_t)(size_t)base;
     29 }
     30 
     31 /* Helper functions to get data pointed to by a public key or signature. */
     32 
     33 uint8_t *GetPublicKeyData(VbPublicKey *key)
     34 {
     35 	return (uint8_t *)key + key->key_offset;
     36 }
     37 
     38 const uint8_t *GetPublicKeyDataC(const VbPublicKey *key)
     39 {
     40 	return (const uint8_t *)key + key->key_offset;
     41 }
     42 
     43 uint8_t *GetSignatureData(VbSignature *sig)
     44 {
     45 	return (uint8_t *)sig + sig->sig_offset;
     46 }
     47 
     48 const uint8_t *GetSignatureDataC(const VbSignature *sig)
     49 {
     50 	return (const uint8_t *)sig + sig->sig_offset;
     51 }
     52 
     53 /*
     54  * Helper functions to verify the data pointed to by a subfield is inside
     55  * the parent data.  Returns 0 if inside, 1 if error.
     56  */
     57 
     58 int VerifyMemberInside(const void *parent, uint64_t parent_size,
     59                        const void *member, uint64_t member_size,
     60                        uint64_t member_data_offset,
     61                        uint64_t member_data_size)
     62 {
     63 	uint64_t end = OffsetOf(parent, member);
     64 
     65 	if (end > parent_size)
     66 		return 1;
     67 
     68 	if (UINT64_MAX - end < member_size)
     69 		return 1;  /* Detect wraparound in integer math */
     70 	if (end + member_size > parent_size)
     71 		return 1;
     72 
     73 	if (UINT64_MAX - end < member_data_offset)
     74 		return 1;
     75 	end += member_data_offset;
     76 	if (end > parent_size)
     77 		return 1;
     78 
     79 	if (UINT64_MAX - end < member_data_size)
     80 		return 1;
     81 	if (end + member_data_size > parent_size)
     82 		return 1;
     83 
     84 	return 0;
     85 }
     86 
     87 int VerifyPublicKeyInside(const void *parent, uint64_t parent_size,
     88                           const VbPublicKey *key)
     89 {
     90 	return VerifyMemberInside(parent, parent_size,
     91 				  key, sizeof(VbPublicKey),
     92 				  key->key_offset, key->key_size);
     93 }
     94 
     95 int VerifySignatureInside(const void *parent, uint64_t parent_size,
     96                           const VbSignature *sig)
     97 {
     98 	return VerifyMemberInside(parent, parent_size,
     99 				  sig, sizeof(VbSignature),
    100 				  sig->sig_offset, sig->sig_size);
    101 }
    102 
    103 void PublicKeyInit(VbPublicKey *key, uint8_t *key_data, uint64_t key_size)
    104 {
    105 	key->key_offset = OffsetOf(key, key_data);
    106 	key->key_size = key_size;
    107 	key->algorithm = kNumAlgorithms; /* Key not present yet */
    108 	key->key_version = 0;
    109 }
    110 
    111 int PublicKeyCopy(VbPublicKey *dest, const VbPublicKey *src)
    112 {
    113 	if (dest->key_size < src->key_size)
    114 		return 1;
    115 
    116 	dest->key_size = src->key_size;
    117 	dest->algorithm = src->algorithm;
    118 	dest->key_version = src->key_version;
    119 	Memcpy(GetPublicKeyData(dest), GetPublicKeyDataC(src), src->key_size);
    120 	return 0;
    121 }
    122 
    123 RSAPublicKey *PublicKeyToRSA(const VbPublicKey *key)
    124 {
    125 	RSAPublicKey *rsa;
    126 	uint64_t key_size;
    127 
    128 	if (kNumAlgorithms <= key->algorithm) {
    129 		VBDEBUG(("Invalid algorithm.\n"));
    130 		return NULL;
    131 	}
    132 	if (!RSAProcessedKeySize(key->algorithm, &key_size) ||
    133 	    key_size != key->key_size) {
    134 		VBDEBUG(("Wrong key size for algorithm\n"));
    135 		return NULL;
    136 	}
    137 
    138 	rsa = RSAPublicKeyFromBuf(GetPublicKeyDataC(key), key->key_size);
    139 	if (!rsa)
    140 		return NULL;
    141 
    142 	rsa->algorithm = (unsigned int)key->algorithm;
    143 	return rsa;
    144 }
    145 
    146 int VerifyData(const uint8_t *data, uint64_t size, const VbSignature *sig,
    147                const RSAPublicKey *key)
    148 {
    149 	VBDEBUG(("   - sig_size=%d, expecting %d for algorithm %d\n",
    150 		 (unsigned)sig->sig_size, siglen_map[key->algorithm],
    151 		 key->algorithm));
    152 	if (sig->sig_size != siglen_map[key->algorithm]) {
    153 		VBDEBUG(("Wrong data signature size for algorithm, "
    154 			 "sig_size=%d, expected %d for algorithm %d.\n",
    155 			 (int)sig->sig_size, siglen_map[key->algorithm],
    156 			 key->algorithm));
    157 		return 1;
    158 	}
    159 	if (sig->data_size > size) {
    160 		VBDEBUG(("Data buffer smaller than length of signed data.\n"));
    161 		return 1;
    162 	}
    163 
    164 	if (!RSAVerifyBinary_f(NULL, key, data, sig->data_size,
    165 			       GetSignatureDataC(sig), key->algorithm))
    166 		return 1;
    167 
    168 	return 0;
    169 }
    170 
    171 int VerifyDigest(const uint8_t *digest, const VbSignature *sig,
    172                  const RSAPublicKey *key)
    173 {
    174 	if (sig->sig_size != siglen_map[key->algorithm]) {
    175 		VBDEBUG(("Wrong digest signature size for algorithm.\n"));
    176 		return 1;
    177 	}
    178 
    179 	if (!RSAVerifyBinaryWithDigest_f(NULL, key, digest,
    180 					 GetSignatureDataC(sig),
    181 					 key->algorithm))
    182 		return 1;
    183 
    184 	return 0;
    185 }
    186 
    187 int KeyBlockVerify(const VbKeyBlockHeader *block, uint64_t size,
    188                    const VbPublicKey *key, int hash_only)
    189 {
    190 	const VbSignature *sig;
    191 
    192 	/* Sanity checks before attempting signature of data */
    193 	if(size < sizeof(VbKeyBlockHeader)) {
    194 		VBDEBUG(("Not enough space for key block header.\n"));
    195 		return VBOOT_KEY_BLOCK_INVALID;
    196 	}
    197 	if (SafeMemcmp(block->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE)) {
    198 		VBDEBUG(("Not a valid verified boot key block.\n"));
    199 		return VBOOT_KEY_BLOCK_INVALID;
    200 	}
    201 	if (block->header_version_major != KEY_BLOCK_HEADER_VERSION_MAJOR) {
    202 		VBDEBUG(("Incompatible key block header version.\n"));
    203 		return VBOOT_KEY_BLOCK_INVALID;
    204 	}
    205 	if (size < block->key_block_size) {
    206 		VBDEBUG(("Not enough data for key block.\n"));
    207 		return VBOOT_KEY_BLOCK_INVALID;
    208 	}
    209 	if (!hash_only && !key) {
    210 		VBDEBUG(("Missing required public key.\n"));
    211 		return VBOOT_PUBLIC_KEY_INVALID;
    212 	}
    213 
    214 	/*
    215 	 * Check signature or hash, depending on the hash_only parameter. Note
    216 	 * that we don't require a key even if the keyblock has a signature,
    217 	 * because the caller may not care if the keyblock itself is signed
    218 	 * (for example, booting a Google-signed kernel in developer mode).
    219 	 */
    220 	if (hash_only) {
    221 		/* Check hash */
    222 		uint8_t *header_checksum = NULL;
    223 		int rv;
    224 
    225 		sig = &block->key_block_checksum;
    226 
    227 		if (VerifySignatureInside(block, block->key_block_size, sig)) {
    228 			VBDEBUG(("Key block hash off end of block\n"));
    229 			return VBOOT_KEY_BLOCK_INVALID;
    230 		}
    231 		if (sig->sig_size != SHA512_DIGEST_SIZE) {
    232 			VBDEBUG(("Wrong hash size for key block.\n"));
    233 			return VBOOT_KEY_BLOCK_INVALID;
    234 		}
    235 
    236 		/* Make sure advertised signature data sizes are sane. */
    237 		if (block->key_block_size < sig->data_size) {
    238 			VBDEBUG(("Signature calculated past end of block\n"));
    239 			return VBOOT_KEY_BLOCK_INVALID;
    240 		}
    241 
    242 		VBDEBUG(("Checking key block hash only...\n"));
    243 		header_checksum = DigestBuf((const uint8_t *)block,
    244 					    sig->data_size,
    245 					    SHA512_DIGEST_ALGORITHM);
    246 		rv = SafeMemcmp(header_checksum, GetSignatureDataC(sig),
    247 				SHA512_DIGEST_SIZE);
    248 		VbExFree(header_checksum);
    249 		if (rv) {
    250 			VBDEBUG(("Invalid key block hash.\n"));
    251 			return VBOOT_KEY_BLOCK_HASH;
    252 		}
    253 	} else {
    254 		/* Check signature */
    255 		RSAPublicKey *rsa;
    256 		int rv;
    257 
    258 		sig = &block->key_block_signature;
    259 
    260 		if (VerifySignatureInside(block, block->key_block_size, sig)) {
    261 			VBDEBUG(("Key block signature off end of block\n"));
    262 			return VBOOT_KEY_BLOCK_INVALID;
    263 		}
    264 
    265 		rsa = PublicKeyToRSA(key);
    266 		if (!rsa) {
    267 			VBDEBUG(("Invalid public key\n"));
    268 			return VBOOT_PUBLIC_KEY_INVALID;
    269 		}
    270 
    271 		/* Make sure advertised signature data sizes are sane. */
    272 		if (block->key_block_size < sig->data_size) {
    273 			VBDEBUG(("Signature calculated past end of block\n"));
    274 			RSAPublicKeyFree(rsa);
    275 			return VBOOT_KEY_BLOCK_INVALID;
    276 		}
    277 
    278 		VBDEBUG(("Checking key block signature...\n"));
    279 		rv = VerifyData((const uint8_t *)block, size, sig, rsa);
    280 		RSAPublicKeyFree(rsa);
    281 		if (rv) {
    282 			VBDEBUG(("Invalid key block signature.\n"));
    283 			return VBOOT_KEY_BLOCK_SIGNATURE;
    284 		}
    285 	}
    286 
    287 	/* Verify we signed enough data */
    288 	if (sig->data_size < sizeof(VbKeyBlockHeader)) {
    289 		VBDEBUG(("Didn't sign enough data\n"));
    290 		return VBOOT_KEY_BLOCK_INVALID;
    291 	}
    292 
    293 	/* Verify data key is inside the block and inside signed data */
    294 	if (VerifyPublicKeyInside(block, block->key_block_size,
    295 				  &block->data_key)) {
    296 		VBDEBUG(("Data key off end of key block\n"));
    297 		return VBOOT_KEY_BLOCK_INVALID;
    298 	}
    299 	if (VerifyPublicKeyInside(block, sig->data_size, &block->data_key)) {
    300 		VBDEBUG(("Data key off end of signed data\n"));
    301 		return VBOOT_KEY_BLOCK_INVALID;
    302 	}
    303 
    304 	/* Success */
    305 	return VBOOT_SUCCESS;
    306 }
    307 
    308 int VerifyFirmwarePreamble(const VbFirmwarePreambleHeader *preamble,
    309                            uint64_t size, const RSAPublicKey *key)
    310 {
    311 	const VbSignature *sig = &preamble->preamble_signature;
    312 
    313 	VBDEBUG(("Verifying preamble.\n"));
    314 	/* Sanity checks before attempting signature of data */
    315 	if(size < EXPECTED_VBFIRMWAREPREAMBLEHEADER2_0_SIZE) {
    316 		VBDEBUG(("Not enough data for preamble header 2.0.\n"));
    317 		return VBOOT_PREAMBLE_INVALID;
    318 	}
    319 	if (preamble->header_version_major !=
    320 	    FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR) {
    321 		VBDEBUG(("Incompatible firmware preamble header version.\n"));
    322 		return VBOOT_PREAMBLE_INVALID;
    323 	}
    324 	if (size < preamble->preamble_size) {
    325 		VBDEBUG(("Not enough data for preamble.\n"));
    326 		return VBOOT_PREAMBLE_INVALID;
    327 	}
    328 
    329 	/* Check signature */
    330 	if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) {
    331 		VBDEBUG(("Preamble signature off end of preamble\n"));
    332 		return VBOOT_PREAMBLE_INVALID;
    333 	}
    334 
    335 	/* Make sure advertised signature data sizes are sane. */
    336 	if (preamble->preamble_size < sig->data_size) {
    337 		VBDEBUG(("Signature calculated past end of the block\n"));
    338 		return VBOOT_PREAMBLE_INVALID;
    339 	}
    340 
    341 	if (VerifyData((const uint8_t *)preamble, size, sig, key)) {
    342 		VBDEBUG(("Preamble signature validation failed\n"));
    343 		return VBOOT_PREAMBLE_SIGNATURE;
    344 	}
    345 
    346 	/* Verify we signed enough data */
    347 	if (sig->data_size < sizeof(VbFirmwarePreambleHeader)) {
    348 		VBDEBUG(("Didn't sign enough data\n"));
    349 		return VBOOT_PREAMBLE_INVALID;
    350 	}
    351 
    352 	/* Verify body signature is inside the signed data */
    353 	if (VerifySignatureInside(preamble, sig->data_size,
    354 				  &preamble->body_signature)) {
    355 		VBDEBUG(("Firmware body signature off end of preamble\n"));
    356 		return VBOOT_PREAMBLE_INVALID;
    357 	}
    358 
    359 	/* Verify kernel subkey is inside the signed data */
    360 	if (VerifyPublicKeyInside(preamble, sig->data_size,
    361 				  &preamble->kernel_subkey)) {
    362 		VBDEBUG(("Kernel subkey off end of preamble\n"));
    363 		return VBOOT_PREAMBLE_INVALID;
    364 	}
    365 
    366 	/*
    367 	 * If the preamble header version is at least 2.1, verify we have space
    368 	 * for the added fields from 2.1.
    369 	 */
    370 	if (preamble->header_version_minor >= 1) {
    371 		if(size < EXPECTED_VBFIRMWAREPREAMBLEHEADER2_1_SIZE) {
    372 			VBDEBUG(("Not enough data for preamble header 2.1.\n"));
    373 			return VBOOT_PREAMBLE_INVALID;
    374 		}
    375 	}
    376 
    377 	/* Success */
    378 	return VBOOT_SUCCESS;
    379 }
    380 
    381 uint32_t VbGetFirmwarePreambleFlags(const VbFirmwarePreambleHeader *preamble)
    382 {
    383 	if (preamble->header_version_minor < 1) {
    384 		/*
    385 		 * Old structure; return default flags.  (Note that we don't
    386 		 * need to check header_version_major; if that's not 2 then
    387 		 * VerifyFirmwarePreamble() would have already failed.
    388 		 */
    389 		return 0;
    390 	}
    391 
    392 	return preamble->flags;
    393 }
    394 
    395 int VerifyKernelPreamble(const VbKernelPreambleHeader *preamble,
    396                          uint64_t size, const RSAPublicKey *key)
    397 {
    398 	const VbSignature *sig = &preamble->preamble_signature;
    399 
    400 	/* Sanity checks before attempting signature of data */
    401 	if(size < sizeof(VbKernelPreambleHeader)) {
    402 		VBDEBUG(("Not enough data for preamble header.\n"));
    403 		return VBOOT_PREAMBLE_INVALID;
    404 	}
    405 	if (preamble->header_version_major !=
    406 	    KERNEL_PREAMBLE_HEADER_VERSION_MAJOR) {
    407 		VBDEBUG(("Incompatible kernel preamble header version.\n"));
    408 		return VBOOT_PREAMBLE_INVALID;
    409 	}
    410 	if (size < preamble->preamble_size) {
    411 		VBDEBUG(("Not enough data for preamble.\n"));
    412 		return VBOOT_PREAMBLE_INVALID;
    413 	}
    414 
    415 	/* Check signature */
    416 	if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) {
    417 		VBDEBUG(("Preamble signature off end of preamble\n"));
    418 		return VBOOT_PREAMBLE_INVALID;
    419 	}
    420 	if (VerifyData((const uint8_t *)preamble, size, sig, key)) {
    421 		VBDEBUG(("Preamble signature validation failed\n"));
    422 		return VBOOT_PREAMBLE_SIGNATURE;
    423 	}
    424 
    425 	/* Verify we signed enough data */
    426 	if (sig->data_size < sizeof(VbKernelPreambleHeader)) {
    427 		VBDEBUG(("Didn't sign enough data\n"));
    428 		return VBOOT_PREAMBLE_INVALID;
    429 	}
    430 
    431 	/* Verify body signature is inside the signed data */
    432 	if (VerifySignatureInside(preamble, sig->data_size,
    433 				  &preamble->body_signature)) {
    434 		VBDEBUG(("Kernel body signature off end of preamble\n"));
    435 		return VBOOT_PREAMBLE_INVALID;
    436 	}
    437 
    438 	/*
    439 	 * If the preamble header version is at least 2.1, verify we have space
    440 	 * for the added fields from >2.1.
    441 	 */
    442 	if (preamble->header_version_minor >= 1) {
    443 		if((preamble->header_version_minor == 1) &&
    444 		   (size < EXPECTED_VBKERNELPREAMBLEHEADER2_1_SIZE)) {
    445 			VBDEBUG(("Not enough data for preamble header 2.1.\n"));
    446 			return VBOOT_PREAMBLE_INVALID;
    447 		}
    448 
    449 		if((preamble->header_version_minor == 2) &&
    450 		   (size < EXPECTED_VBKERNELPREAMBLEHEADER2_2_SIZE)) {
    451 			VBDEBUG(("Not enough data for preamble header 2.2.\n"));
    452 			return VBOOT_PREAMBLE_INVALID;
    453 		}
    454 	}
    455 
    456 	/* Success */
    457 	return VBOOT_SUCCESS;
    458 }
    459 
    460 int VbGetKernelVmlinuzHeader(const VbKernelPreambleHeader *preamble,
    461 			     uint64_t *vmlinuz_header_address,
    462 			     uint64_t *vmlinuz_header_size)
    463 {
    464 	*vmlinuz_header_address = 0;
    465 	*vmlinuz_header_size = 0;
    466 	if (preamble->header_version_minor > 0) {
    467 		/*
    468 		 * Set header and size only if the preamble header version is >
    469 		 * 2.1 as they don't exist in version 2.0 (Note that we don't
    470 		 * need to check header_version_major; if that's not 2 then
    471 		 * VerifyKernelPreamble() would have already failed.
    472 		 */
    473 		*vmlinuz_header_address = preamble->vmlinuz_header_address;
    474 		*vmlinuz_header_size = preamble->vmlinuz_header_size;
    475 	}
    476 	return VBOOT_SUCCESS;
    477 }
    478 
    479 int VbKernelHasFlags(const VbKernelPreambleHeader *preamble)
    480 {
    481 	if (preamble->header_version_minor > 1)
    482 		return VBOOT_SUCCESS;
    483 
    484 	return VBOOT_KERNEL_PREAMBLE_NO_FLAGS;
    485 }
    486 
    487 int VerifyVmlinuzInsideKBlob(uint64_t kblob, uint64_t kblob_size,
    488 			     uint64_t header, uint64_t header_size)
    489 {
    490 	uint64_t end = header-kblob;
    491 	if (end > kblob_size)
    492 		return VBOOT_PREAMBLE_INVALID;
    493 	if (UINT64_MAX - end < header_size)
    494 		return VBOOT_PREAMBLE_INVALID;
    495 	if (end + header_size > kblob_size)
    496 		return VBOOT_PREAMBLE_INVALID;
    497 
    498 	return VBOOT_SUCCESS;
    499 }
    500 
    501 uint64_t VbSharedDataReserve(VbSharedDataHeader *header, uint64_t size)
    502 {
    503 	uint64_t offs = header->data_used;
    504 
    505 	VBDEBUG(("VbSharedDataReserve %d bytes at %d\n", (int)size, (int)offs));
    506 
    507 	if (!header || size > header->data_size - header->data_used) {
    508 		VBDEBUG(("VbSharedData buffer out of space.\n"));
    509 		return 0;  /* Not initialized, or not enough space left. */
    510 	}
    511 	header->data_used += size;
    512 	return offs;
    513 }
    514 
    515 int VbSharedDataSetKernelKey(VbSharedDataHeader *header, const VbPublicKey *src)
    516 {
    517 	VbPublicKey *kdest;
    518 
    519 	if (!header)
    520 		return VBOOT_SHARED_DATA_INVALID;
    521 	if (!src)
    522 		return VBOOT_PUBLIC_KEY_INVALID;
    523 
    524 	kdest = &header->kernel_subkey;
    525 
    526 	VBDEBUG(("Saving kernel subkey to shared data: size %d, algo %d\n",
    527 		 siglen_map[src->algorithm], (int)src->algorithm));
    528 
    529 	/* Attempt to allocate space for key, if it hasn't been allocated yet */
    530 	if (!header->kernel_subkey_data_offset) {
    531 		header->kernel_subkey_data_offset =
    532 			VbSharedDataReserve(header, src->key_size);
    533 		if (!header->kernel_subkey_data_offset)
    534 			return VBOOT_SHARED_DATA_INVALID;
    535 		header->kernel_subkey_data_size = src->key_size;
    536 	}
    537 
    538 	/* Copy the kernel sign key blob into the destination buffer */
    539 	PublicKeyInit(kdest,
    540 		      (uint8_t *)header + header->kernel_subkey_data_offset,
    541 		      header->kernel_subkey_data_size);
    542 
    543 	return PublicKeyCopy(kdest, src);
    544 }
    545