• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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