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  * Host functions for verified boot.
      6  *
      7  * TODO: change all 'return 0', 'return 1' into meaningful return codes.
      8  */
      9 
     10 #include <string.h>
     11 
     12 #include "host_common.h"
     13 #include "cryptolib.h"
     14 #include "utility.h"
     15 #include "vboot_common.h"
     16 
     17 VbFirmwarePreambleHeader *CreateFirmwarePreamble(
     18 	uint64_t firmware_version,
     19 	const VbPublicKey *kernel_subkey,
     20 	const VbSignature *body_signature,
     21 	const VbPrivateKey *signing_key,
     22 	uint32_t flags)
     23 {
     24 	VbFirmwarePreambleHeader *h;
     25 	uint64_t signed_size = (sizeof(VbFirmwarePreambleHeader) +
     26 				kernel_subkey->key_size +
     27 				body_signature->sig_size);
     28 	uint64_t block_size = signed_size + siglen_map[signing_key->algorithm];
     29 	uint8_t *kernel_subkey_dest;
     30 	uint8_t *body_sig_dest;
     31 	uint8_t *block_sig_dest;
     32 	VbSignature *sigtmp;
     33 
     34 	/* Allocate key block */
     35 	h = (VbFirmwarePreambleHeader *)malloc(block_size);
     36 	if (!h)
     37 		return NULL;
     38 
     39 	Memset(h, 0, block_size);
     40 	kernel_subkey_dest = (uint8_t *)(h + 1);
     41 	body_sig_dest = kernel_subkey_dest + kernel_subkey->key_size;
     42 	block_sig_dest = body_sig_dest + body_signature->sig_size;
     43 
     44 	h->header_version_major = FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR;
     45 	h->header_version_minor = FIRMWARE_PREAMBLE_HEADER_VERSION_MINOR;
     46 	h->preamble_size = block_size;
     47 	h->firmware_version = firmware_version;
     48 	h->flags = flags;
     49 
     50 	/* Copy data key */
     51 	PublicKeyInit(&h->kernel_subkey, kernel_subkey_dest,
     52 		      kernel_subkey->key_size);
     53 	PublicKeyCopy(&h->kernel_subkey, kernel_subkey);
     54 
     55 	/* Copy body signature */
     56 	SignatureInit(&h->body_signature, body_sig_dest,
     57 		      body_signature->sig_size, 0);
     58 	SignatureCopy(&h->body_signature, body_signature);
     59 
     60 	/* Set up signature struct so we can calculate the signature */
     61 	SignatureInit(&h->preamble_signature, block_sig_dest,
     62 		      siglen_map[signing_key->algorithm], signed_size);
     63 
     64 	/* Calculate signature */
     65 	sigtmp = CalculateSignature((uint8_t *)h, signed_size, signing_key);
     66 	SignatureCopy(&h->preamble_signature, sigtmp);
     67 	free(sigtmp);
     68 
     69 	/* Return the header */
     70 	return h;
     71 }
     72 
     73 VbKernelPreambleHeader *CreateKernelPreamble(
     74 	uint64_t kernel_version,
     75 	uint64_t body_load_address,
     76 	uint64_t bootloader_address,
     77 	uint64_t bootloader_size,
     78 	const VbSignature *body_signature,
     79 	uint64_t vmlinuz_header_address,
     80 	uint64_t vmlinuz_header_size,
     81 	uint32_t flags,
     82 	uint64_t desired_size,
     83 	const VbPrivateKey *signing_key)
     84 {
     85 	VbKernelPreambleHeader *h;
     86 	uint64_t signed_size = (sizeof(VbKernelPreambleHeader) +
     87 				body_signature->sig_size);
     88 	uint64_t block_size = signed_size + siglen_map[signing_key->algorithm];
     89 	uint8_t *body_sig_dest;
     90 	uint8_t *block_sig_dest;
     91 	VbSignature *sigtmp;
     92 
     93 	/* If the block size is smaller than the desired size, pad it */
     94 	if (block_size < desired_size)
     95 		block_size = desired_size;
     96 
     97 	/* Allocate key block */
     98 	h = (VbKernelPreambleHeader *)malloc(block_size);
     99 	if (!h)
    100 		return NULL;
    101 
    102 	Memset(h, 0, block_size);
    103 	body_sig_dest = (uint8_t *)(h + 1);
    104 	block_sig_dest = body_sig_dest + body_signature->sig_size;
    105 
    106 	h->header_version_major = KERNEL_PREAMBLE_HEADER_VERSION_MAJOR;
    107 	h->header_version_minor = KERNEL_PREAMBLE_HEADER_VERSION_MINOR;
    108 	h->preamble_size = block_size;
    109 	h->kernel_version = kernel_version;
    110 	h->body_load_address = body_load_address;
    111 	h->bootloader_address = bootloader_address;
    112 	h->bootloader_size = bootloader_size;
    113 	h->vmlinuz_header_address = vmlinuz_header_address;
    114 	h->vmlinuz_header_size = vmlinuz_header_size;
    115 	h->flags = flags;
    116 
    117 	/* Copy body signature */
    118 	SignatureInit(&h->body_signature, body_sig_dest,
    119 		      body_signature->sig_size, 0);
    120 	SignatureCopy(&h->body_signature, body_signature);
    121 
    122 	/* Set up signature struct so we can calculate the signature */
    123 	SignatureInit(&h->preamble_signature, block_sig_dest,
    124 		      siglen_map[signing_key->algorithm], signed_size);
    125 
    126 	/* Calculate signature */
    127 	sigtmp = CalculateSignature((uint8_t *)h, signed_size, signing_key);
    128 	SignatureCopy(&h->preamble_signature, sigtmp);
    129 	free(sigtmp);
    130 
    131 	/* Return the header */
    132 	return h;
    133 }
    134