/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * * Host functions for verified boot. * * TODO: change all 'return 0', 'return 1' into meaningful return codes. */ #include #include "host_common.h" #include "cryptolib.h" #include "utility.h" #include "vboot_common.h" VbFirmwarePreambleHeader *CreateFirmwarePreamble( uint64_t firmware_version, const VbPublicKey *kernel_subkey, const VbSignature *body_signature, const VbPrivateKey *signing_key, uint32_t flags) { VbFirmwarePreambleHeader *h; uint64_t signed_size = (sizeof(VbFirmwarePreambleHeader) + kernel_subkey->key_size + body_signature->sig_size); uint64_t block_size = signed_size + siglen_map[signing_key->algorithm]; uint8_t *kernel_subkey_dest; uint8_t *body_sig_dest; uint8_t *block_sig_dest; VbSignature *sigtmp; /* Allocate key block */ h = (VbFirmwarePreambleHeader *)malloc(block_size); if (!h) return NULL; Memset(h, 0, block_size); kernel_subkey_dest = (uint8_t *)(h + 1); body_sig_dest = kernel_subkey_dest + kernel_subkey->key_size; block_sig_dest = body_sig_dest + body_signature->sig_size; h->header_version_major = FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR; h->header_version_minor = FIRMWARE_PREAMBLE_HEADER_VERSION_MINOR; h->preamble_size = block_size; h->firmware_version = firmware_version; h->flags = flags; /* Copy data key */ PublicKeyInit(&h->kernel_subkey, kernel_subkey_dest, kernel_subkey->key_size); PublicKeyCopy(&h->kernel_subkey, kernel_subkey); /* Copy body signature */ SignatureInit(&h->body_signature, body_sig_dest, body_signature->sig_size, 0); SignatureCopy(&h->body_signature, body_signature); /* Set up signature struct so we can calculate the signature */ SignatureInit(&h->preamble_signature, block_sig_dest, siglen_map[signing_key->algorithm], signed_size); /* Calculate signature */ sigtmp = CalculateSignature((uint8_t *)h, signed_size, signing_key); SignatureCopy(&h->preamble_signature, sigtmp); free(sigtmp); /* Return the header */ return h; } VbKernelPreambleHeader *CreateKernelPreamble( uint64_t kernel_version, uint64_t body_load_address, uint64_t bootloader_address, uint64_t bootloader_size, const VbSignature *body_signature, uint64_t vmlinuz_header_address, uint64_t vmlinuz_header_size, uint32_t flags, uint64_t desired_size, const VbPrivateKey *signing_key) { VbKernelPreambleHeader *h; uint64_t signed_size = (sizeof(VbKernelPreambleHeader) + body_signature->sig_size); uint64_t block_size = signed_size + siglen_map[signing_key->algorithm]; uint8_t *body_sig_dest; uint8_t *block_sig_dest; VbSignature *sigtmp; /* If the block size is smaller than the desired size, pad it */ if (block_size < desired_size) block_size = desired_size; /* Allocate key block */ h = (VbKernelPreambleHeader *)malloc(block_size); if (!h) return NULL; Memset(h, 0, block_size); body_sig_dest = (uint8_t *)(h + 1); block_sig_dest = body_sig_dest + body_signature->sig_size; h->header_version_major = KERNEL_PREAMBLE_HEADER_VERSION_MAJOR; h->header_version_minor = KERNEL_PREAMBLE_HEADER_VERSION_MINOR; h->preamble_size = block_size; h->kernel_version = kernel_version; h->body_load_address = body_load_address; h->bootloader_address = bootloader_address; h->bootloader_size = bootloader_size; h->vmlinuz_header_address = vmlinuz_header_address; h->vmlinuz_header_size = vmlinuz_header_size; h->flags = flags; /* Copy body signature */ SignatureInit(&h->body_signature, body_sig_dest, body_signature->sig_size, 0); SignatureCopy(&h->body_signature, body_signature); /* Set up signature struct so we can calculate the signature */ SignatureInit(&h->preamble_signature, block_sig_dest, siglen_map[signing_key->algorithm], signed_size); /* Calculate signature */ sigtmp = CalculateSignature((uint8_t *)h, signed_size, signing_key); SignatureCopy(&h->preamble_signature, sigtmp); free(sigtmp); /* Return the header */ return h; }