blob: b12f024fddfce3aa24fb7d5b93a8ee43e5825d21 [file] [log] [blame]
Randall Spangler32a65262011-06-27 10:49:11 -07001/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
Randall Spangler729b8722010-06-11 11:16:20 -07002 * 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
Randall Spangler729b8722010-06-11 11:16:20 -07008
9#include "cryptolib.h"
10#include "host_common.h"
Randall Spangler32a65262011-06-27 10:49:11 -070011#include "host_keyblock.h"
Randall Spangler729b8722010-06-11 11:16:20 -070012#include "vboot_common.h"
13
14
15VbKeyBlockHeader* KeyBlockCreate(const VbPublicKey* data_key,
16 const VbPrivateKey* signing_key,
17 uint64_t flags) {
18
19 VbKeyBlockHeader* h;
20 uint64_t signed_size = sizeof(VbKeyBlockHeader) + data_key->key_size;
21 uint64_t block_size = (signed_size + SHA512_DIGEST_SIZE +
Randall Spangler138acfe2010-08-17 15:45:21 -070022 (signing_key ?
23 siglen_map[signing_key->algorithm] : 0));
Randall Spangler729b8722010-06-11 11:16:20 -070024 uint8_t* data_key_dest;
25 uint8_t* block_sig_dest;
26 uint8_t* block_chk_dest;
27 VbSignature *sigtmp;
28
29 /* Allocate key block */
Randall Spangler32a65262011-06-27 10:49:11 -070030 h = (VbKeyBlockHeader*)malloc(block_size);
Randall Spangler729b8722010-06-11 11:16:20 -070031 if (!h)
32 return NULL;
33 data_key_dest = (uint8_t*)(h + 1);
34 block_chk_dest = data_key_dest + data_key->key_size;
35 block_sig_dest = block_chk_dest + SHA512_DIGEST_SIZE;
36
37 Memcpy(h->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE);
38 h->header_version_major = KEY_BLOCK_HEADER_VERSION_MAJOR;
39 h->header_version_minor = KEY_BLOCK_HEADER_VERSION_MINOR;
40 h->key_block_size = block_size;
41 h->key_block_flags = flags;
42
43 /* Copy data key */
44 PublicKeyInit(&h->data_key, data_key_dest, data_key->key_size);
45 PublicKeyCopy(&h->data_key, data_key);
46
47 /* Set up signature structs so we can calculate the signatures */
48 SignatureInit(&h->key_block_checksum, block_chk_dest,
49 SHA512_DIGEST_SIZE, signed_size);
Bill Richardson4f36ef32010-08-09 17:50:14 -070050 if (signing_key)
51 SignatureInit(&h->key_block_signature, block_sig_dest,
52 siglen_map[signing_key->algorithm], signed_size);
53 else
54 Memset(&h->key_block_signature, 0, sizeof(VbSignature));
Randall Spangler729b8722010-06-11 11:16:20 -070055
56 /* Calculate checksum */
57 sigtmp = CalculateChecksum((uint8_t*)h, signed_size);
58 SignatureCopy(&h->key_block_checksum, sigtmp);
Randall Spangler32a65262011-06-27 10:49:11 -070059 free(sigtmp);
Randall Spangler729b8722010-06-11 11:16:20 -070060
61 /* Calculate signature */
Bill Richardson4f36ef32010-08-09 17:50:14 -070062 if (signing_key) {
63 sigtmp = CalculateSignature((uint8_t*)h, signed_size, signing_key);
64 SignatureCopy(&h->key_block_signature, sigtmp);
Randall Spangler32a65262011-06-27 10:49:11 -070065 free(sigtmp);
Bill Richardson4f36ef32010-08-09 17:50:14 -070066 }
Randall Spangler729b8722010-06-11 11:16:20 -070067
68 /* Return the header */
69 return h;
70}
71
Gaurav Shah068fc6f2010-10-29 10:59:50 -070072/* TODO(gauravsh): This could easily be integrated into KeyBlockCreate()
73 * since the code is almost a mirror - I have kept it as such to avoid changing
74 * the existing interface. */
75VbKeyBlockHeader* KeyBlockCreate_external(const VbPublicKey* data_key,
76 const char* signing_key_pem_file,
77 uint64_t algorithm,
78 uint64_t flags,
79 const char* external_signer) {
80 VbKeyBlockHeader* h;
81 uint64_t signed_size = sizeof(VbKeyBlockHeader) + data_key->key_size;
82 uint64_t block_size = (signed_size + SHA512_DIGEST_SIZE +
83 siglen_map[algorithm]);
84 uint8_t* data_key_dest;
85 uint8_t* block_sig_dest;
86 uint8_t* block_chk_dest;
87 VbSignature *sigtmp;
88
89 /* Allocate key block */
Randall Spangler32a65262011-06-27 10:49:11 -070090 h = (VbKeyBlockHeader*)malloc(block_size);
Gaurav Shah068fc6f2010-10-29 10:59:50 -070091 if (!h)
92 return NULL;
93 if (!signing_key_pem_file || !data_key || !external_signer)
94 return NULL;
95
96 data_key_dest = (uint8_t*)(h + 1);
97 block_chk_dest = data_key_dest + data_key->key_size;
98 block_sig_dest = block_chk_dest + SHA512_DIGEST_SIZE;
99
100 Memcpy(h->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE);
101 h->header_version_major = KEY_BLOCK_HEADER_VERSION_MAJOR;
102 h->header_version_minor = KEY_BLOCK_HEADER_VERSION_MINOR;
103 h->key_block_size = block_size;
104 h->key_block_flags = flags;
105
106 /* Copy data key */
107 PublicKeyInit(&h->data_key, data_key_dest, data_key->key_size);
108 PublicKeyCopy(&h->data_key, data_key);
109
110 /* Set up signature structs so we can calculate the signatures */
111 SignatureInit(&h->key_block_checksum, block_chk_dest,
112 SHA512_DIGEST_SIZE, signed_size);
113 SignatureInit(&h->key_block_signature, block_sig_dest,
114 siglen_map[algorithm], signed_size);
115
116 /* Calculate checksum */
117 sigtmp = CalculateChecksum((uint8_t*)h, signed_size);
118 SignatureCopy(&h->key_block_checksum, sigtmp);
Randall Spangler32a65262011-06-27 10:49:11 -0700119 free(sigtmp);
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700120
121 /* Calculate signature */
122 sigtmp = CalculateSignature_external((uint8_t*)h, signed_size,
123 signing_key_pem_file, algorithm,
124 external_signer);
125 SignatureCopy(&h->key_block_signature, sigtmp);
Randall Spangler32a65262011-06-27 10:49:11 -0700126 free(sigtmp);
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700127
128 /* Return the header */
129 return h;
130}
Randall Spangler729b8722010-06-11 11:16:20 -0700131
132/* Read a key block from a .keyblock file. Caller owns the returned
Randall Spangler32a65262011-06-27 10:49:11 -0700133 * pointer, and must free it with free().
Randall Spangler729b8722010-06-11 11:16:20 -0700134 *
135 * Returns NULL if error. */
136VbKeyBlockHeader* KeyBlockRead(const char* filename) {
137
138 VbKeyBlockHeader* block;
139 uint64_t file_size;
140
141 block = (VbKeyBlockHeader*)ReadFile(filename, &file_size);
142 if (!block) {
Bill Richardsonabf05502010-07-01 10:22:06 -0700143 VBDEBUG(("Error reading key block file: %s\n", filename));
Randall Spangler729b8722010-06-11 11:16:20 -0700144 return NULL;
145 }
146
147 /* Verify the hash of the key block, since we can do that without
148 * the public signing key. */
Randall Spangler138acfe2010-08-17 15:45:21 -0700149 if (0 != KeyBlockVerify(block, file_size, NULL, 1)) {
Bill Richardsonabf05502010-07-01 10:22:06 -0700150 VBDEBUG(("Invalid key block file: filename\n", filename));
Randall Spangler32a65262011-06-27 10:49:11 -0700151 free(block);
Randall Spangler729b8722010-06-11 11:16:20 -0700152 return NULL;
153 }
154
155 return block;
156}
157
158
159/* Write a key block to a file in .keyblock format. */
160int KeyBlockWrite(const char* filename, const VbKeyBlockHeader* key_block) {
161
162 if (0 != WriteFile(filename, key_block, key_block->key_block_size)) {
Bill Richardsonabf05502010-07-01 10:22:06 -0700163 VBDEBUG(("KeyBlockWrite() error writing key block\n"));
Randall Spangler729b8722010-06-11 11:16:20 -0700164 return 1;
165 }
166
167 return 0;
168}