blob: fad17df45da589d6a50edc8428341f9d2b9d9e15 [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 Spangler939cc3a2016-06-21 15:23:32 -07008#include <stdio.h>
9
Randall Spangler7c3ae422016-05-11 13:50:18 -070010#include "2sysincludes.h"
Randall Spangler729b8722010-06-11 11:16:20 -070011
Randall Spangler939cc3a2016-06-21 15:23:32 -070012#include "2api.h"
Randall Spangler7c3ae422016-05-11 13:50:18 -070013#include "2common.h"
Randall Spangler939cc3a2016-06-21 15:23:32 -070014#include "2rsa.h"
Randall Spangler7c3ae422016-05-11 13:50:18 -070015#include "2sha.h"
Randall Spangler729b8722010-06-11 11:16:20 -070016#include "host_common.h"
Randall Spangler939cc3a2016-06-21 15:23:32 -070017#include "host_key.h"
18#include "host_key2.h"
Randall Spangler32a65262011-06-27 10:49:11 -070019#include "host_keyblock.h"
Randall Spangler939cc3a2016-06-21 15:23:32 -070020#include "vb2_common.h"
21#include "vb2_struct.h"
Randall Spangler729b8722010-06-11 11:16:20 -070022#include "vboot_common.h"
23
Randall Spangler939cc3a2016-06-21 15:23:32 -070024struct vb2_keyblock *vb2_create_keyblock(
25 const struct vb2_packed_key *data_key,
26 const struct vb2_private_key *signing_key,
27 uint32_t flags)
28{
29 /* Allocate key block */
30 uint32_t signed_size = sizeof(struct vb2_keyblock) + data_key->key_size;
31 uint32_t sig_data_size =
32 (signing_key ? vb2_rsa_sig_size(signing_key->sig_alg) : 0);
33 uint32_t block_size =
34 signed_size + VB2_SHA512_DIGEST_SIZE + sig_data_size;
35 struct vb2_keyblock *h = (struct vb2_keyblock *)calloc(block_size, 1);
36 if (!h)
37 return NULL;
Randall Spangler729b8722010-06-11 11:16:20 -070038
Randall Spangler939cc3a2016-06-21 15:23:32 -070039 uint8_t *data_key_dest = (uint8_t *)(h + 1);
40 uint8_t *block_chk_dest = data_key_dest + data_key->key_size;
41 uint8_t *block_sig_dest = block_chk_dest + VB2_SHA512_DIGEST_SIZE;
Randall Spangler729b8722010-06-11 11:16:20 -070042
Randall Spangler939cc3a2016-06-21 15:23:32 -070043 memcpy(h->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE);
44 h->header_version_major = KEY_BLOCK_HEADER_VERSION_MAJOR;
45 h->header_version_minor = KEY_BLOCK_HEADER_VERSION_MINOR;
46 h->keyblock_size = block_size;
47 h->keyblock_flags = flags;
Randall Spangler729b8722010-06-11 11:16:20 -070048
Randall Spangler939cc3a2016-06-21 15:23:32 -070049 /* Copy data key */
50 vb2_init_packed_key(&h->data_key, data_key_dest, data_key->key_size);
51 vb2_copy_packed_key(&h->data_key, data_key);
Randall Spangler729b8722010-06-11 11:16:20 -070052
Randall Spangler939cc3a2016-06-21 15:23:32 -070053 /* Set up signature structs so we can calculate the signatures */
54 vb2_init_signature(&h->keyblock_hash, block_chk_dest,
55 VB2_SHA512_DIGEST_SIZE, signed_size);
56 if (signing_key) {
57 vb2_init_signature(&h->keyblock_signature, block_sig_dest,
58 sig_data_size, signed_size);
59 } else {
60 memset(&h->keyblock_signature, 0,
61 sizeof(h->keyblock_signature));
62 }
Randall Spangler729b8722010-06-11 11:16:20 -070063
Randall Spangler939cc3a2016-06-21 15:23:32 -070064 /* Calculate hash */
65 struct vb2_signature *chk =
66 vb2_sha512_signature((uint8_t*)h, signed_size);
67 vb2_copy_signature(&h->keyblock_hash, chk);
68 free(chk);
Randall Spangler729b8722010-06-11 11:16:20 -070069
Randall Spangler939cc3a2016-06-21 15:23:32 -070070 /* Calculate signature */
71 if (signing_key) {
72 struct vb2_signature *sigtmp =
73 vb2_calculate_signature((uint8_t*)h,
74 signed_size,
75 signing_key);
76 vb2_copy_signature(&h->keyblock_signature, sigtmp);
77 free(sigtmp);
78 }
Randall Spangler729b8722010-06-11 11:16:20 -070079
Randall Spangler939cc3a2016-06-21 15:23:32 -070080 /* Return the header */
81 return h;
Randall Spangler729b8722010-06-11 11:16:20 -070082}
83
Randall Spangler939cc3a2016-06-21 15:23:32 -070084/* TODO(gauravsh): This could easily be integrated into the function above
Gaurav Shah068fc6f2010-10-29 10:59:50 -070085 * since the code is almost a mirror - I have kept it as such to avoid changing
86 * the existing interface. */
Randall Spangler939cc3a2016-06-21 15:23:32 -070087struct vb2_keyblock *vb2_create_keyblock_external(
88 const struct vb2_packed_key *data_key,
89 const char *signing_key_pem_file,
90 uint32_t algorithm,
91 uint32_t flags,
92 const char *external_signer)
93{
Randall Spanglerd8a9ede2016-09-02 12:25:27 -070094 if (!signing_key_pem_file || !data_key || !external_signer)
95 return NULL;
96
Randall Spangler939cc3a2016-06-21 15:23:32 -070097 uint32_t signed_size = sizeof(struct vb2_keyblock) + data_key->key_size;
98 uint32_t sig_data_size = vb2_rsa_sig_size(algorithm);
99 uint32_t block_size =
100 signed_size + VB2_SHA512_DIGEST_SIZE + sig_data_size;
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700101
Randall Spangler939cc3a2016-06-21 15:23:32 -0700102 /* Allocate key block */
103 struct vb2_keyblock *h = (struct vb2_keyblock *)calloc(block_size, 1);
104 if (!h)
105 return NULL;
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700106
Randall Spangler939cc3a2016-06-21 15:23:32 -0700107 uint8_t *data_key_dest = (uint8_t *)(h + 1);
108 uint8_t *block_chk_dest = data_key_dest + data_key->key_size;
109 uint8_t *block_sig_dest = block_chk_dest + VB2_SHA512_DIGEST_SIZE;
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700110
Randall Spangler939cc3a2016-06-21 15:23:32 -0700111 memcpy(h->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE);
112 h->header_version_major = KEY_BLOCK_HEADER_VERSION_MAJOR;
113 h->header_version_minor = KEY_BLOCK_HEADER_VERSION_MINOR;
114 h->keyblock_size = block_size;
115 h->keyblock_flags = flags;
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700116
Randall Spangler939cc3a2016-06-21 15:23:32 -0700117 /* Copy data key */
118 vb2_init_packed_key(&h->data_key, data_key_dest, data_key->key_size);
119 vb2_copy_packed_key(&h->data_key, data_key);
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700120
Randall Spangler939cc3a2016-06-21 15:23:32 -0700121 /* Set up signature structs so we can calculate the signatures */
122 vb2_init_signature(&h->keyblock_hash, block_chk_dest,
123 VB2_SHA512_DIGEST_SIZE, signed_size);
124 vb2_init_signature(&h->keyblock_signature, block_sig_dest,
125 sig_data_size, signed_size);
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700126
Randall Spangler939cc3a2016-06-21 15:23:32 -0700127 /* Calculate checksum */
128 struct vb2_signature *chk =
129 vb2_sha512_signature((uint8_t*)h, signed_size);
130 vb2_copy_signature(&h->keyblock_hash, chk);
131 free(chk);
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700132
Randall Spangler939cc3a2016-06-21 15:23:32 -0700133 /* Calculate signature */
Randall Spangler7d0cc742016-06-30 11:30:32 -0700134 struct vb2_signature *sigtmp =
135 vb2_external_signature((uint8_t*)h, signed_size,
136 signing_key_pem_file, algorithm,
137 external_signer);
Randall Spangler939cc3a2016-06-21 15:23:32 -0700138 free(sigtmp);
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700139
Randall Spangler939cc3a2016-06-21 15:23:32 -0700140 /* Return the header */
141 return h;
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700142}
Randall Spangler729b8722010-06-11 11:16:20 -0700143
Randall Spangler939cc3a2016-06-21 15:23:32 -0700144struct vb2_keyblock *vb2_read_keyblock(const char *filename)
145{
146 uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE];
147 struct vb2_workbuf wb;
148 vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
Randall Spangler729b8722010-06-11 11:16:20 -0700149
Randall Spangler939cc3a2016-06-21 15:23:32 -0700150 struct vb2_keyblock *block;
151 uint32_t file_size;
152 if (VB2_SUCCESS !=
153 vb2_read_file(filename, (uint8_t **)&block, &file_size)) {
154 fprintf(stderr, "Error reading key block file: %s\n", filename);
155 return NULL;
156 }
Randall Spangler729b8722010-06-11 11:16:20 -0700157
Randall Spangler939cc3a2016-06-21 15:23:32 -0700158 /* Verify the hash of the key block, since we can do that without
159 * the public signing key. */
160 if (VB2_SUCCESS != vb2_verify_keyblock_hash(block, file_size, &wb)) {
161 fprintf(stderr, "Invalid key block file: %s\n", filename);
162 free(block);
163 return NULL;
164 }
Randall Spangler729b8722010-06-11 11:16:20 -0700165
Randall Spangler939cc3a2016-06-21 15:23:32 -0700166 return block;
Randall Spangler729b8722010-06-11 11:16:20 -0700167}
168
169
Randall Spangler939cc3a2016-06-21 15:23:32 -0700170int vb2_write_keyblock(const char *filename,
171 const struct vb2_keyblock *keyblock)
172{
173 return vb2_write_file(filename, keyblock, keyblock->keyblock_size);
Randall Spangler729b8722010-06-11 11:16:20 -0700174}