blob: dde8fe6c909141f7ed1633900689125177e891d9 [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 "cryptolib.h"
17#include "host_common.h"
Randall Spangler939cc3a2016-06-21 15:23:32 -070018#include "host_key.h"
19#include "host_key2.h"
Randall Spangler32a65262011-06-27 10:49:11 -070020#include "host_keyblock.h"
Randall Spangler939cc3a2016-06-21 15:23:32 -070021#include "vb2_common.h"
22#include "vb2_struct.h"
Randall Spangler729b8722010-06-11 11:16:20 -070023#include "vboot_common.h"
24
Randall Spangler939cc3a2016-06-21 15:23:32 -070025struct vb2_keyblock *vb2_create_keyblock(
26 const struct vb2_packed_key *data_key,
27 const struct vb2_private_key *signing_key,
28 uint32_t flags)
29{
30 /* Allocate key block */
31 uint32_t signed_size = sizeof(struct vb2_keyblock) + data_key->key_size;
32 uint32_t sig_data_size =
33 (signing_key ? vb2_rsa_sig_size(signing_key->sig_alg) : 0);
34 uint32_t block_size =
35 signed_size + VB2_SHA512_DIGEST_SIZE + sig_data_size;
36 struct vb2_keyblock *h = (struct vb2_keyblock *)calloc(block_size, 1);
37 if (!h)
38 return NULL;
Randall Spangler729b8722010-06-11 11:16:20 -070039
Randall Spangler939cc3a2016-06-21 15:23:32 -070040 uint8_t *data_key_dest = (uint8_t *)(h + 1);
41 uint8_t *block_chk_dest = data_key_dest + data_key->key_size;
42 uint8_t *block_sig_dest = block_chk_dest + VB2_SHA512_DIGEST_SIZE;
Randall Spangler729b8722010-06-11 11:16:20 -070043
Randall Spangler939cc3a2016-06-21 15:23:32 -070044 memcpy(h->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE);
45 h->header_version_major = KEY_BLOCK_HEADER_VERSION_MAJOR;
46 h->header_version_minor = KEY_BLOCK_HEADER_VERSION_MINOR;
47 h->keyblock_size = block_size;
48 h->keyblock_flags = flags;
Randall Spangler729b8722010-06-11 11:16:20 -070049
Randall Spangler939cc3a2016-06-21 15:23:32 -070050 /* Copy data key */
51 vb2_init_packed_key(&h->data_key, data_key_dest, data_key->key_size);
52 vb2_copy_packed_key(&h->data_key, data_key);
Randall Spangler729b8722010-06-11 11:16:20 -070053
Randall Spangler939cc3a2016-06-21 15:23:32 -070054 /* Set up signature structs so we can calculate the signatures */
55 vb2_init_signature(&h->keyblock_hash, block_chk_dest,
56 VB2_SHA512_DIGEST_SIZE, signed_size);
57 if (signing_key) {
58 vb2_init_signature(&h->keyblock_signature, block_sig_dest,
59 sig_data_size, signed_size);
60 } else {
61 memset(&h->keyblock_signature, 0,
62 sizeof(h->keyblock_signature));
63 }
Randall Spangler729b8722010-06-11 11:16:20 -070064
Randall Spangler939cc3a2016-06-21 15:23:32 -070065 /* Calculate hash */
66 struct vb2_signature *chk =
67 vb2_sha512_signature((uint8_t*)h, signed_size);
68 vb2_copy_signature(&h->keyblock_hash, chk);
69 free(chk);
Randall Spangler729b8722010-06-11 11:16:20 -070070
Randall Spangler939cc3a2016-06-21 15:23:32 -070071 /* Calculate signature */
72 if (signing_key) {
73 struct vb2_signature *sigtmp =
74 vb2_calculate_signature((uint8_t*)h,
75 signed_size,
76 signing_key);
77 vb2_copy_signature(&h->keyblock_signature, sigtmp);
78 free(sigtmp);
79 }
Randall Spangler729b8722010-06-11 11:16:20 -070080
Randall Spangler939cc3a2016-06-21 15:23:32 -070081 /* Return the header */
82 return h;
Randall Spangler729b8722010-06-11 11:16:20 -070083}
84
Randall Spangler939cc3a2016-06-21 15:23:32 -070085/* TODO(gauravsh): This could easily be integrated into the function above
Gaurav Shah068fc6f2010-10-29 10:59:50 -070086 * since the code is almost a mirror - I have kept it as such to avoid changing
87 * the existing interface. */
Randall Spangler939cc3a2016-06-21 15:23:32 -070088struct vb2_keyblock *vb2_create_keyblock_external(
89 const struct vb2_packed_key *data_key,
90 const char *signing_key_pem_file,
91 uint32_t algorithm,
92 uint32_t flags,
93 const char *external_signer)
94{
Randall Spanglerd8a9ede2016-09-02 12:25:27 -070095 if (!signing_key_pem_file || !data_key || !external_signer)
96 return NULL;
97
Randall Spangler939cc3a2016-06-21 15:23:32 -070098 uint32_t signed_size = sizeof(struct vb2_keyblock) + data_key->key_size;
99 uint32_t sig_data_size = vb2_rsa_sig_size(algorithm);
100 uint32_t block_size =
101 signed_size + VB2_SHA512_DIGEST_SIZE + sig_data_size;
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700102
Randall Spangler939cc3a2016-06-21 15:23:32 -0700103 /* Allocate key block */
104 struct vb2_keyblock *h = (struct vb2_keyblock *)calloc(block_size, 1);
105 if (!h)
106 return NULL;
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700107
Randall Spangler939cc3a2016-06-21 15:23:32 -0700108 uint8_t *data_key_dest = (uint8_t *)(h + 1);
109 uint8_t *block_chk_dest = data_key_dest + data_key->key_size;
110 uint8_t *block_sig_dest = block_chk_dest + VB2_SHA512_DIGEST_SIZE;
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700111
Randall Spangler939cc3a2016-06-21 15:23:32 -0700112 memcpy(h->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE);
113 h->header_version_major = KEY_BLOCK_HEADER_VERSION_MAJOR;
114 h->header_version_minor = KEY_BLOCK_HEADER_VERSION_MINOR;
115 h->keyblock_size = block_size;
116 h->keyblock_flags = flags;
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700117
Randall Spangler939cc3a2016-06-21 15:23:32 -0700118 /* Copy data key */
119 vb2_init_packed_key(&h->data_key, data_key_dest, data_key->key_size);
120 vb2_copy_packed_key(&h->data_key, data_key);
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700121
Randall Spangler939cc3a2016-06-21 15:23:32 -0700122 /* Set up signature structs so we can calculate the signatures */
123 vb2_init_signature(&h->keyblock_hash, block_chk_dest,
124 VB2_SHA512_DIGEST_SIZE, signed_size);
125 vb2_init_signature(&h->keyblock_signature, block_sig_dest,
126 sig_data_size, signed_size);
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700127
Randall Spangler939cc3a2016-06-21 15:23:32 -0700128 /* Calculate checksum */
129 struct vb2_signature *chk =
130 vb2_sha512_signature((uint8_t*)h, signed_size);
131 vb2_copy_signature(&h->keyblock_hash, chk);
132 free(chk);
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700133
Randall Spangler939cc3a2016-06-21 15:23:32 -0700134 /* Calculate signature */
Randall Spangler7d0cc742016-06-30 11:30:32 -0700135 struct vb2_signature *sigtmp =
136 vb2_external_signature((uint8_t*)h, signed_size,
137 signing_key_pem_file, algorithm,
138 external_signer);
Randall Spangler939cc3a2016-06-21 15:23:32 -0700139 free(sigtmp);
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700140
Randall Spangler939cc3a2016-06-21 15:23:32 -0700141 /* Return the header */
142 return h;
Gaurav Shah068fc6f2010-10-29 10:59:50 -0700143}
Randall Spangler729b8722010-06-11 11:16:20 -0700144
Randall Spangler939cc3a2016-06-21 15:23:32 -0700145struct vb2_keyblock *vb2_read_keyblock(const char *filename)
146{
147 uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE];
148 struct vb2_workbuf wb;
149 vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
Randall Spangler729b8722010-06-11 11:16:20 -0700150
Randall Spangler939cc3a2016-06-21 15:23:32 -0700151 struct vb2_keyblock *block;
152 uint32_t file_size;
153 if (VB2_SUCCESS !=
154 vb2_read_file(filename, (uint8_t **)&block, &file_size)) {
155 fprintf(stderr, "Error reading key block file: %s\n", filename);
156 return NULL;
157 }
Randall Spangler729b8722010-06-11 11:16:20 -0700158
Randall Spangler939cc3a2016-06-21 15:23:32 -0700159 /* Verify the hash of the key block, since we can do that without
160 * the public signing key. */
161 if (VB2_SUCCESS != vb2_verify_keyblock_hash(block, file_size, &wb)) {
162 fprintf(stderr, "Invalid key block file: %s\n", filename);
163 free(block);
164 return NULL;
165 }
Randall Spangler729b8722010-06-11 11:16:20 -0700166
Randall Spangler939cc3a2016-06-21 15:23:32 -0700167 return block;
Randall Spangler729b8722010-06-11 11:16:20 -0700168}
169
170
Randall Spangler939cc3a2016-06-21 15:23:32 -0700171int vb2_write_keyblock(const char *filename,
172 const struct vb2_keyblock *keyblock)
173{
174 return vb2_write_file(filename, keyblock, keyblock->keyblock_size);
Randall Spangler729b8722010-06-11 11:16:20 -0700175}