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
CreateFirmwarePreamble(uint64_t firmware_version,const VbPublicKey * kernel_subkey,const VbSignature * body_signature,const VbPrivateKey * signing_key,uint32_t flags)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
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)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