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