blob: b691fc36ac366260d105959484bed447fc490b30 [file] [log] [blame]
Randall Spangler93943262013-02-26 11:03:57 -08001/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
Randall Spanglerd1836442010-06-10 09:59:04 -07002 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Common functions between firmware and kernel verified boot.
6 * (Firmware portion)
7 */
8
Bill Richardson0c3ba242013-03-29 11:09:30 -07009#include "sysincludes.h"
Randall Spangler7c3ae422016-05-11 13:50:18 -070010#include "2sysincludes.h"
Bill Richardson0c3ba242013-03-29 11:09:30 -070011
Randall Spangler7c3ae422016-05-11 13:50:18 -070012#include "2common.h"
13#include "2sha.h"
Randall Spanglere49e8af2011-07-08 13:03:32 -070014#include "vboot_api.h"
Randall Spanglerd1836442010-06-10 09:59:04 -070015#include "vboot_common.h"
16#include "utility.h"
17
Randall Spangler68f54d42013-01-25 15:05:08 -080018const char *kVbootErrors[VBOOT_ERROR_MAX] = {
19 "Success.",
20 "Key block invalid.",
21 "Key block signature failed.",
22 "Key block hash failed.",
23 "Public key invalid.",
24 "Preamble invalid.",
25 "Preamble signature check failed.",
26 "Shared data invalid."
Randall Spanglerd1836442010-06-10 09:59:04 -070027};
28
Randall Spangler68f54d42013-01-25 15:05:08 -080029uint64_t OffsetOf(const void *base, const void *ptr)
30{
31 return (uint64_t)(size_t)ptr - (uint64_t)(size_t)base;
Randall Spanglerd1836442010-06-10 09:59:04 -070032}
33
Randall Spanglerd1836442010-06-10 09:59:04 -070034/* Helper functions to get data pointed to by a public key or signature. */
Randall Spangler68f54d42013-01-25 15:05:08 -080035
36uint8_t *GetPublicKeyData(VbPublicKey *key)
37{
38 return (uint8_t *)key + key->key_offset;
Randall Spanglerd1836442010-06-10 09:59:04 -070039}
40
Randall Spangler68f54d42013-01-25 15:05:08 -080041const uint8_t *GetPublicKeyDataC(const VbPublicKey *key)
42{
43 return (const uint8_t *)key + key->key_offset;
Randall Spanglerd1836442010-06-10 09:59:04 -070044}
45
Randall Spangler68f54d42013-01-25 15:05:08 -080046uint8_t *GetSignatureData(VbSignature *sig)
47{
48 return (uint8_t *)sig + sig->sig_offset;
Randall Spanglerd1836442010-06-10 09:59:04 -070049}
50
Randall Spangler68f54d42013-01-25 15:05:08 -080051const uint8_t *GetSignatureDataC(const VbSignature *sig)
52{
53 return (const uint8_t *)sig + sig->sig_offset;
Randall Spanglerd1836442010-06-10 09:59:04 -070054}
55
Randall Spangler68f54d42013-01-25 15:05:08 -080056/*
57 * Helper functions to verify the data pointed to by a subfield is inside
58 * the parent data. Returns 0 if inside, 1 if error.
59 */
Randall Spanglerd1836442010-06-10 09:59:04 -070060
Randall Spangler68f54d42013-01-25 15:05:08 -080061int VerifyMemberInside(const void *parent, uint64_t parent_size,
62 const void *member, uint64_t member_size,
Randall Spanglerd1836442010-06-10 09:59:04 -070063 uint64_t member_data_offset,
Randall Spangler68f54d42013-01-25 15:05:08 -080064 uint64_t member_data_size)
65{
66 uint64_t end = OffsetOf(parent, member);
Randall Spanglerd1836442010-06-10 09:59:04 -070067
Randall Spangler68f54d42013-01-25 15:05:08 -080068 if (end > parent_size)
69 return 1;
Randall Spanglerd1836442010-06-10 09:59:04 -070070
Randall Spangler68f54d42013-01-25 15:05:08 -080071 if (UINT64_MAX - end < member_size)
72 return 1; /* Detect wraparound in integer math */
73 if (end + member_size > parent_size)
74 return 1;
Randall Spanglerd1836442010-06-10 09:59:04 -070075
Randall Spangler68f54d42013-01-25 15:05:08 -080076 if (UINT64_MAX - end < member_data_offset)
77 return 1;
78 end += member_data_offset;
79 if (end > parent_size)
80 return 1;
Randall Spangler138acfe2010-08-17 15:45:21 -070081
Randall Spangler68f54d42013-01-25 15:05:08 -080082 if (UINT64_MAX - end < member_data_size)
83 return 1;
84 if (end + member_data_size > parent_size)
85 return 1;
Randall Spanglerd1836442010-06-10 09:59:04 -070086
Randall Spangler68f54d42013-01-25 15:05:08 -080087 return 0;
Randall Spanglerd1836442010-06-10 09:59:04 -070088}
89
Randall Spangler68f54d42013-01-25 15:05:08 -080090int VerifyPublicKeyInside(const void *parent, uint64_t parent_size,
91 const VbPublicKey *key)
92{
93 return VerifyMemberInside(parent, parent_size,
94 key, sizeof(VbPublicKey),
95 key->key_offset, key->key_size);
Randall Spanglerd1836442010-06-10 09:59:04 -070096}
97
Randall Spangler68f54d42013-01-25 15:05:08 -080098int VerifySignatureInside(const void *parent, uint64_t parent_size,
99 const VbSignature *sig)
100{
101 return VerifyMemberInside(parent, parent_size,
102 sig, sizeof(VbSignature),
103 sig->sig_offset, sig->sig_size);
Randall Spanglerd1836442010-06-10 09:59:04 -0700104}
105
Randall Spangler68f54d42013-01-25 15:05:08 -0800106void PublicKeyInit(VbPublicKey *key, uint8_t *key_data, uint64_t key_size)
107{
108 key->key_offset = OffsetOf(key, key_data);
109 key->key_size = key_size;
110 key->algorithm = kNumAlgorithms; /* Key not present yet */
111 key->key_version = 0;
Randall Spanglera55e5ca2010-06-15 18:45:09 -0700112}
113
Randall Spangler68f54d42013-01-25 15:05:08 -0800114int PublicKeyCopy(VbPublicKey *dest, const VbPublicKey *src)
115{
116 if (dest->key_size < src->key_size)
117 return 1;
Randall Spanglera55e5ca2010-06-15 18:45:09 -0700118
Randall Spangler68f54d42013-01-25 15:05:08 -0800119 dest->key_size = src->key_size;
120 dest->algorithm = src->algorithm;
121 dest->key_version = src->key_version;
Randall Spangler664096b2016-10-13 16:16:41 -0700122 memcpy(GetPublicKeyData(dest), GetPublicKeyDataC(src), src->key_size);
Randall Spangler68f54d42013-01-25 15:05:08 -0800123 return 0;
Randall Spanglera55e5ca2010-06-15 18:45:09 -0700124}
125
Randall Spangler68f54d42013-01-25 15:05:08 -0800126RSAPublicKey *PublicKeyToRSA(const VbPublicKey *key)
127{
128 RSAPublicKey *rsa;
129 uint64_t key_size;
Randall Spanglera55e5ca2010-06-15 18:45:09 -0700130
Randall Spangler68f54d42013-01-25 15:05:08 -0800131 if (kNumAlgorithms <= key->algorithm) {
132 VBDEBUG(("Invalid algorithm.\n"));
133 return NULL;
134 }
135 if (!RSAProcessedKeySize(key->algorithm, &key_size) ||
136 key_size != key->key_size) {
137 VBDEBUG(("Wrong key size for algorithm\n"));
138 return NULL;
139 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700140
Randall Spangler68f54d42013-01-25 15:05:08 -0800141 rsa = RSAPublicKeyFromBuf(GetPublicKeyDataC(key), key->key_size);
142 if (!rsa)
143 return NULL;
Randall Spanglerd1836442010-06-10 09:59:04 -0700144
Randall Spangler68f54d42013-01-25 15:05:08 -0800145 rsa->algorithm = (unsigned int)key->algorithm;
146 return rsa;
Randall Spanglerd1836442010-06-10 09:59:04 -0700147}
148
Randall Spangler68f54d42013-01-25 15:05:08 -0800149int VerifyData(const uint8_t *data, uint64_t size, const VbSignature *sig,
150 const RSAPublicKey *key)
151{
Simon Glass981cb2a2013-08-12 15:12:47 -0600152 VBDEBUG((" - sig_size=%d, expecting %d for algorithm %d\n",
153 (unsigned)sig->sig_size, siglen_map[key->algorithm],
154 key->algorithm));
Randall Spangler68f54d42013-01-25 15:05:08 -0800155 if (sig->sig_size != siglen_map[key->algorithm]) {
Simon Glass981cb2a2013-08-12 15:12:47 -0600156 VBDEBUG(("Wrong data signature size for algorithm, "
157 "sig_size=%d, expected %d for algorithm %d.\n",
158 (int)sig->sig_size, siglen_map[key->algorithm],
159 key->algorithm));
Randall Spangler68f54d42013-01-25 15:05:08 -0800160 return 1;
161 }
162 if (sig->data_size > size) {
163 VBDEBUG(("Data buffer smaller than length of signed data.\n"));
164 return 1;
165 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700166
Randall Spangler68f54d42013-01-25 15:05:08 -0800167 if (!RSAVerifyBinary_f(NULL, key, data, sig->data_size,
168 GetSignatureDataC(sig), key->algorithm))
169 return 1;
Randall Spanglerd1836442010-06-10 09:59:04 -0700170
Randall Spangler68f54d42013-01-25 15:05:08 -0800171 return 0;
Randall Spanglerd1836442010-06-10 09:59:04 -0700172}
173
Randall Spangler68f54d42013-01-25 15:05:08 -0800174int VerifyDigest(const uint8_t *digest, const VbSignature *sig,
175 const RSAPublicKey *key)
176{
177 if (sig->sig_size != siglen_map[key->algorithm]) {
Simon Glass981cb2a2013-08-12 15:12:47 -0600178 VBDEBUG(("Wrong digest signature size for algorithm.\n"));
Randall Spangler68f54d42013-01-25 15:05:08 -0800179 return 1;
180 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700181
Randall Spangler68f54d42013-01-25 15:05:08 -0800182 if (!RSAVerifyBinaryWithDigest_f(NULL, key, digest,
183 GetSignatureDataC(sig),
184 key->algorithm))
185 return 1;
Randall Spangler39ed88e2010-06-15 14:53:01 -0700186
Randall Spangler68f54d42013-01-25 15:05:08 -0800187 return 0;
Randall Spangler39ed88e2010-06-15 14:53:01 -0700188}
189
Randall Spangler68f54d42013-01-25 15:05:08 -0800190int KeyBlockVerify(const VbKeyBlockHeader *block, uint64_t size,
191 const VbPublicKey *key, int hash_only)
192{
193 const VbSignature *sig;
Randall Spangler39ed88e2010-06-15 14:53:01 -0700194
Randall Spangler68f54d42013-01-25 15:05:08 -0800195 /* Sanity checks before attempting signature of data */
196 if(size < sizeof(VbKeyBlockHeader)) {
197 VBDEBUG(("Not enough space for key block header.\n"));
198 return VBOOT_KEY_BLOCK_INVALID;
199 }
200 if (SafeMemcmp(block->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE)) {
201 VBDEBUG(("Not a valid verified boot key block.\n"));
202 return VBOOT_KEY_BLOCK_INVALID;
203 }
204 if (block->header_version_major != KEY_BLOCK_HEADER_VERSION_MAJOR) {
205 VBDEBUG(("Incompatible key block header version.\n"));
206 return VBOOT_KEY_BLOCK_INVALID;
207 }
208 if (size < block->key_block_size) {
209 VBDEBUG(("Not enough data for key block.\n"));
210 return VBOOT_KEY_BLOCK_INVALID;
211 }
212 if (!hash_only && !key) {
213 VBDEBUG(("Missing required public key.\n"));
214 return VBOOT_PUBLIC_KEY_INVALID;
215 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700216
Randall Spangler68f54d42013-01-25 15:05:08 -0800217 /*
218 * Check signature or hash, depending on the hash_only parameter. Note
219 * that we don't require a key even if the keyblock has a signature,
220 * because the caller may not care if the keyblock itself is signed
221 * (for example, booting a Google-signed kernel in developer mode).
222 */
223 if (hash_only) {
224 /* Check hash */
Randall Spangler7c3ae422016-05-11 13:50:18 -0700225 uint8_t header_checksum[VB2_SHA512_DIGEST_SIZE];
Randall Spangler68f54d42013-01-25 15:05:08 -0800226 int rv;
Randall Spanglerd1836442010-06-10 09:59:04 -0700227
Randall Spangler68f54d42013-01-25 15:05:08 -0800228 sig = &block->key_block_checksum;
Randall Spanglerd1836442010-06-10 09:59:04 -0700229
Randall Spangler68f54d42013-01-25 15:05:08 -0800230 if (VerifySignatureInside(block, block->key_block_size, sig)) {
231 VBDEBUG(("Key block hash off end of block\n"));
232 return VBOOT_KEY_BLOCK_INVALID;
233 }
Randall Spangler7c3ae422016-05-11 13:50:18 -0700234 if (sig->sig_size != VB2_SHA512_DIGEST_SIZE) {
Randall Spangler68f54d42013-01-25 15:05:08 -0800235 VBDEBUG(("Wrong hash size for key block.\n"));
236 return VBOOT_KEY_BLOCK_INVALID;
237 }
Randall Spangler138acfe2010-08-17 15:45:21 -0700238
Randall Spangler68f54d42013-01-25 15:05:08 -0800239 /* Make sure advertised signature data sizes are sane. */
240 if (block->key_block_size < sig->data_size) {
241 VBDEBUG(("Signature calculated past end of block\n"));
242 return VBOOT_KEY_BLOCK_INVALID;
243 }
Randall Spangler138acfe2010-08-17 15:45:21 -0700244
Randall Spangler68f54d42013-01-25 15:05:08 -0800245 VBDEBUG(("Checking key block hash only...\n"));
Randall Spangler7c3ae422016-05-11 13:50:18 -0700246 rv = vb2_digest_buffer((const uint8_t *)block,
247 sig->data_size,
248 VB2_HASH_SHA512,
249 header_checksum,
250 sizeof(header_checksum));
251 if (!rv)
252 rv = SafeMemcmp(header_checksum, GetSignatureDataC(sig),
253 sizeof(header_checksum));
254
Randall Spangler68f54d42013-01-25 15:05:08 -0800255 if (rv) {
256 VBDEBUG(("Invalid key block hash.\n"));
257 return VBOOT_KEY_BLOCK_HASH;
258 }
259 } else {
260 /* Check signature */
261 RSAPublicKey *rsa;
262 int rv;
Randall Spangler138acfe2010-08-17 15:45:21 -0700263
Randall Spangler68f54d42013-01-25 15:05:08 -0800264 sig = &block->key_block_signature;
Randall Spanglerac7c2d92011-03-25 15:20:58 -0700265
Randall Spangler68f54d42013-01-25 15:05:08 -0800266 if (VerifySignatureInside(block, block->key_block_size, sig)) {
267 VBDEBUG(("Key block signature off end of block\n"));
268 return VBOOT_KEY_BLOCK_INVALID;
269 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700270
Randall Spangler68f54d42013-01-25 15:05:08 -0800271 rsa = PublicKeyToRSA(key);
272 if (!rsa) {
273 VBDEBUG(("Invalid public key\n"));
274 return VBOOT_PUBLIC_KEY_INVALID;
275 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700276
Randall Spangler68f54d42013-01-25 15:05:08 -0800277 /* Make sure advertised signature data sizes are sane. */
278 if (block->key_block_size < sig->data_size) {
279 VBDEBUG(("Signature calculated past end of block\n"));
280 RSAPublicKeyFree(rsa);
281 return VBOOT_KEY_BLOCK_INVALID;
282 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700283
Randall Spangler68f54d42013-01-25 15:05:08 -0800284 VBDEBUG(("Checking key block signature...\n"));
285 rv = VerifyData((const uint8_t *)block, size, sig, rsa);
286 RSAPublicKeyFree(rsa);
287 if (rv) {
288 VBDEBUG(("Invalid key block signature.\n"));
289 return VBOOT_KEY_BLOCK_SIGNATURE;
290 }
291 }
Gaurav Shah2a80e8a2010-06-30 18:26:21 -0700292
Randall Spangler68f54d42013-01-25 15:05:08 -0800293 /* Verify we signed enough data */
294 if (sig->data_size < sizeof(VbKeyBlockHeader)) {
295 VBDEBUG(("Didn't sign enough data\n"));
296 return VBOOT_KEY_BLOCK_INVALID;
297 }
Randall Spanglerac7c2d92011-03-25 15:20:58 -0700298
Randall Spangler68f54d42013-01-25 15:05:08 -0800299 /* Verify data key is inside the block and inside signed data */
300 if (VerifyPublicKeyInside(block, block->key_block_size,
301 &block->data_key)) {
302 VBDEBUG(("Data key off end of key block\n"));
303 return VBOOT_KEY_BLOCK_INVALID;
304 }
305 if (VerifyPublicKeyInside(block, sig->data_size, &block->data_key)) {
306 VBDEBUG(("Data key off end of signed data\n"));
307 return VBOOT_KEY_BLOCK_INVALID;
308 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700309
Randall Spangler68f54d42013-01-25 15:05:08 -0800310 /* Success */
311 return VBOOT_SUCCESS;
Randall Spanglerd1836442010-06-10 09:59:04 -0700312}
313
Randall Spangler68f54d42013-01-25 15:05:08 -0800314int VerifyKernelPreamble(const VbKernelPreambleHeader *preamble,
315 uint64_t size, const RSAPublicKey *key)
316{
317 const VbSignature *sig = &preamble->preamble_signature;
Randall Spanglera712e012011-07-13 09:48:41 -0700318
Randall Spangler68f54d42013-01-25 15:05:08 -0800319 /* Sanity checks before attempting signature of data */
320 if(size < sizeof(VbKernelPreambleHeader)) {
321 VBDEBUG(("Not enough data for preamble header.\n"));
322 return VBOOT_PREAMBLE_INVALID;
323 }
324 if (preamble->header_version_major !=
325 KERNEL_PREAMBLE_HEADER_VERSION_MAJOR) {
326 VBDEBUG(("Incompatible kernel preamble header version.\n"));
327 return VBOOT_PREAMBLE_INVALID;
328 }
329 if (size < preamble->preamble_size) {
330 VBDEBUG(("Not enough data for preamble.\n"));
331 return VBOOT_PREAMBLE_INVALID;
332 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700333
Randall Spangler68f54d42013-01-25 15:05:08 -0800334 /* Check signature */
335 if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) {
336 VBDEBUG(("Preamble signature off end of preamble\n"));
337 return VBOOT_PREAMBLE_INVALID;
338 }
339 if (VerifyData((const uint8_t *)preamble, size, sig, key)) {
340 VBDEBUG(("Preamble signature validation failed\n"));
341 return VBOOT_PREAMBLE_SIGNATURE;
342 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700343
Randall Spangler68f54d42013-01-25 15:05:08 -0800344 /* Verify we signed enough data */
345 if (sig->data_size < sizeof(VbKernelPreambleHeader)) {
346 VBDEBUG(("Didn't sign enough data\n"));
347 return VBOOT_PREAMBLE_INVALID;
348 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700349
Randall Spangler68f54d42013-01-25 15:05:08 -0800350 /* Verify body signature is inside the signed data */
351 if (VerifySignatureInside(preamble, sig->data_size,
352 &preamble->body_signature)) {
353 VBDEBUG(("Kernel body signature off end of preamble\n"));
354 return VBOOT_PREAMBLE_INVALID;
355 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700356
Shelley Chenf1f53b32015-01-08 09:13:44 -0800357 /*
358 * If the preamble header version is at least 2.1, verify we have space
Furquan Shaikh80e779d2015-02-03 15:34:29 -0800359 * for the added fields from >2.1.
Shelley Chenf1f53b32015-01-08 09:13:44 -0800360 */
361 if (preamble->header_version_minor >= 1) {
Furquan Shaikh80e779d2015-02-03 15:34:29 -0800362 if((preamble->header_version_minor == 1) &&
363 (size < EXPECTED_VBKERNELPREAMBLEHEADER2_1_SIZE)) {
Shelley Chenf1f53b32015-01-08 09:13:44 -0800364 VBDEBUG(("Not enough data for preamble header 2.1.\n"));
365 return VBOOT_PREAMBLE_INVALID;
366 }
Furquan Shaikh80e779d2015-02-03 15:34:29 -0800367
368 if((preamble->header_version_minor == 2) &&
369 (size < EXPECTED_VBKERNELPREAMBLEHEADER2_2_SIZE)) {
370 VBDEBUG(("Not enough data for preamble header 2.2.\n"));
371 return VBOOT_PREAMBLE_INVALID;
372 }
Shelley Chenf1f53b32015-01-08 09:13:44 -0800373 }
374
Randall Spangler68f54d42013-01-25 15:05:08 -0800375 /* Success */
376 return VBOOT_SUCCESS;
Randall Spanglerd1836442010-06-10 09:59:04 -0700377}
Randall Spangler95c40312011-03-09 15:54:16 -0800378
Shelley Chenf1f53b32015-01-08 09:13:44 -0800379int VbGetKernelVmlinuzHeader(const VbKernelPreambleHeader *preamble,
380 uint64_t *vmlinuz_header_address,
381 uint64_t *vmlinuz_header_size)
382{
383 *vmlinuz_header_address = 0;
384 *vmlinuz_header_size = 0;
385 if (preamble->header_version_minor > 0) {
386 /*
387 * Set header and size only if the preamble header version is >
388 * 2.1 as they don't exist in version 2.0 (Note that we don't
389 * need to check header_version_major; if that's not 2 then
390 * VerifyKernelPreamble() would have already failed.
391 */
392 *vmlinuz_header_address = preamble->vmlinuz_header_address;
393 *vmlinuz_header_size = preamble->vmlinuz_header_size;
394 }
395 return VBOOT_SUCCESS;
396}
397
Furquan Shaikh80e779d2015-02-03 15:34:29 -0800398int VbKernelHasFlags(const VbKernelPreambleHeader *preamble)
399{
400 if (preamble->header_version_minor > 1)
401 return VBOOT_SUCCESS;
402
403 return VBOOT_KERNEL_PREAMBLE_NO_FLAGS;
404}
405
Shelley Chenf1f53b32015-01-08 09:13:44 -0800406int VerifyVmlinuzInsideKBlob(uint64_t kblob, uint64_t kblob_size,
407 uint64_t header, uint64_t header_size)
408{
409 uint64_t end = header-kblob;
410 if (end > kblob_size)
411 return VBOOT_PREAMBLE_INVALID;
412 if (UINT64_MAX - end < header_size)
413 return VBOOT_PREAMBLE_INVALID;
414 if (end + header_size > kblob_size)
415 return VBOOT_PREAMBLE_INVALID;
416
417 return VBOOT_SUCCESS;
418}
419
Randall Spangler68f54d42013-01-25 15:05:08 -0800420uint64_t VbSharedDataReserve(VbSharedDataHeader *header, uint64_t size)
421{
Randall Spangler68f54d42013-01-25 15:05:08 -0800422 if (!header || size > header->data_size - header->data_used) {
423 VBDEBUG(("VbSharedData buffer out of space.\n"));
424 return 0; /* Not initialized, or not enough space left. */
425 }
Randall Spangler1589f942016-09-02 12:10:31 -0700426
427 uint64_t offs = header->data_used;
428 VBDEBUG(("VbSharedDataReserve %d bytes at %d\n", (int)size, (int)offs));
429
Randall Spangler68f54d42013-01-25 15:05:08 -0800430 header->data_used += size;
431 return offs;
Randall Spangler95c40312011-03-09 15:54:16 -0800432}
433
Randall Spangler68f54d42013-01-25 15:05:08 -0800434int VbSharedDataSetKernelKey(VbSharedDataHeader *header, const VbPublicKey *src)
435{
Bill Richardson4c3b4ea2014-05-30 13:21:57 -0700436 VbPublicKey *kdest;
Simon Glass981cb2a2013-08-12 15:12:47 -0600437
Randall Spangler68f54d42013-01-25 15:05:08 -0800438 if (!header)
439 return VBOOT_SHARED_DATA_INVALID;
Bill Richardson4c3b4ea2014-05-30 13:21:57 -0700440 if (!src)
441 return VBOOT_PUBLIC_KEY_INVALID;
442
443 kdest = &header->kernel_subkey;
444
445 VBDEBUG(("Saving kernel subkey to shared data: size %d, algo %d\n",
446 siglen_map[src->algorithm], (int)src->algorithm));
Randall Spangler95c40312011-03-09 15:54:16 -0800447
Randall Spangler68f54d42013-01-25 15:05:08 -0800448 /* Attempt to allocate space for key, if it hasn't been allocated yet */
449 if (!header->kernel_subkey_data_offset) {
450 header->kernel_subkey_data_offset =
451 VbSharedDataReserve(header, src->key_size);
452 if (!header->kernel_subkey_data_offset)
453 return VBOOT_SHARED_DATA_INVALID;
454 header->kernel_subkey_data_size = src->key_size;
455 }
Randall Spangler95c40312011-03-09 15:54:16 -0800456
Randall Spangler68f54d42013-01-25 15:05:08 -0800457 /* Copy the kernel sign key blob into the destination buffer */
458 PublicKeyInit(kdest,
459 (uint8_t *)header + header->kernel_subkey_data_offset,
460 header->kernel_subkey_data_size);
Randall Spangler95c40312011-03-09 15:54:16 -0800461
Randall Spangler68f54d42013-01-25 15:05:08 -0800462 return PublicKeyCopy(kdest, src);
Randall Spangler95c40312011-03-09 15:54:16 -0800463}