summaryrefslogtreecommitdiff
path: root/firmware/2lib/include/2api.h
blob: b091731b007b370c5a431b2b686914032ad492e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * APIs between calling firmware and vboot_reference
 *
 * General notes:
 *
 * TODO: split this file into a vboot_entry_points.h file which contains the
 * entry points for the firmware to call vboot_reference, and a
 * vboot_firmware_exports.h which contains the APIs to be implemented by the
 * calling firmware and exported to vboot_reference.
 *
 * Notes:
 *    * Assumes this code is never called in the S3 resume path.  TPM resume
 *      must be done elsewhere, and VB2_NV_DEBUG_RESET_MODE is ignored.
 */

#ifndef VBOOT_REFERENCE_2API_H_
#define VBOOT_REFERENCE_2API_H_

#include "2constants.h"
#include "2crypto.h"
#include "2fw_hash_tags.h"
#include "2gbb_flags.h"
#include "2id.h"
#include "2recovery_reasons.h"
#include "2return_codes.h"
#include "2secdata.h"

/* Modes for vb2ex_tpm_set_mode. */
enum vb2_tpm_mode {
	/*
	 * TPM is enabled tentatively, and may be set to either
	 * ENABLED or DISABLED mode.
	 */
	VB2_TPM_MODE_ENABLED_TENTATIVE = 0,

	/* TPM is enabled, and mode may not be changed. */
	VB2_TPM_MODE_ENABLED = 1,

	/* TPM is disabled, and mode may not be changed. */
	VB2_TPM_MODE_DISABLED = 2,
};

/* Flags for vb2_context.
 *
 * Unless otherwise noted, flags are set by verified boot and may be read (but
 * not set or cleared) by the caller.
 */
enum vb2_context_flags {

	/*
	 * Verified boot has changed nvdata[].  Caller must save nvdata[] back
	 * to its underlying storage, then may clear this flag.
	 */
	VB2_CONTEXT_NVDATA_CHANGED = (1 << 0),

	/*
	 * Verified boot has changed secdata[].  Caller must save secdata[]
	 * back to its underlying storage, then may clear this flag.
	 */
	VB2_CONTEXT_SECDATA_CHANGED = (1 << 1),

	/* Recovery mode is requested this boot */
	VB2_CONTEXT_RECOVERY_MODE = (1 << 2),

	/* Developer mode is requested this boot */
	VB2_CONTEXT_DEVELOPER_MODE = (1 << 3),

	/*
	 * Force recovery mode due to physical user request.  Caller may set
	 * this flag when initializing the context.
	 */
	VB2_CONTEXT_FORCE_RECOVERY_MODE = (1 << 4),

	/*
	 * Force developer mode enabled.  Caller may set this flag when
	 * initializing the context.  Previously used for forcing developer
	 * mode with physical dev switch.
	 *
	 * Deprecated as part of chromium:942901.
	 */
	VB2_CONTEXT_DEPRECATED_FORCE_DEVELOPER_MODE = (1 << 5),

	/* Using firmware slot B.  If this flag is clear, using slot A. */
	VB2_CONTEXT_FW_SLOT_B = (1 << 6),

	/* RAM should be cleared by caller this boot */
	VB2_CONTEXT_CLEAR_RAM = (1 << 7),

	/* Wipeout by the app should be requested. */
	VB2_CONTEXT_FORCE_WIPEOUT_MODE = (1 << 8),

	/* Erase TPM developer mode state if it is enabled. */
	VB2_CONTEXT_DISABLE_DEVELOPER_MODE = (1 << 9),

	/*
	 * Verified boot has changed secdatak[].  Caller must save secdatak[]
	 * back to its underlying storage, then may clear this flag.
	 */
	VB2_CONTEXT_SECDATAK_CHANGED = (1 << 10),

	/*
	 * Allow kernel verification to roll forward the version in secdatak[].
	 * Caller may set this flag before calling vb2api_kernel_phase3().
	 */
	VB2_CONTEXT_ALLOW_KERNEL_ROLL_FORWARD = (1 << 11),

	/*
	 * Boot optimistically: don't touch failure counters.  Caller may set
	 * this flag when initializing the context.
	 */
	VB2_CONTEXT_NOFAIL_BOOT = (1 << 12),

	/*
	 * Secdata is not ready this boot, but should be ready next boot.  It
	 * would like to reboot.  The decision whether to reboot or not must be
	 * deferred until vboot, because rebooting all the time before then
	 * could cause a device with malfunctioning secdata to get stuck in an
	 * unrecoverable crash loop.
	 */
	VB2_CONTEXT_SECDATA_WANTS_REBOOT = (1 << 13),

	/*
	 * Boot is S3->S0 resume, not S5->S0 normal boot.  Caller may set this
	 * flag when initializing the context.
	 */
	VB2_CONTEXT_S3_RESUME = (1 << 14),

	/*
	 * System supports EC software sync.  Caller may set this flag at any
	 * time before calling VbSelectAndLoadKernel().
	 */
	VB2_CONTEXT_EC_SYNC_SUPPORTED = (1 << 15),

	/*
	 * EC software sync is slow to update; warning screen should be
	 * displayed.  Caller may set this flag at any time before calling
	 * VbSelectAndLoadKernel().
	 */
	VB2_CONTEXT_EC_SYNC_SLOW = (1 << 16),

	/*
	 * EC firmware supports early firmware selection; two EC images exist,
	 * and EC may have already verified and jumped to EC-RW prior to EC
	 * software sync.
	 */
	VB2_CONTEXT_EC_EFS = (1 << 17),

	/*
	 * NV storage uses data format V2.  Data is size VB2_NVDATA_SIZE_V2,
	 * not VB2_NVDATA_SIZE.
	 *
	 * Caller must set this flag when initializing the context to use V2.
	 * (Vboot cannot infer the data size from the data itself, because the
	 * data provided by the caller could be uninitialized.)
	 */
	VB2_CONTEXT_NVDATA_V2 = (1 << 18),

	/* Allow vendor data to be set via the vendor data ui. */
	VB2_CONTEXT_VENDOR_DATA_SETTABLE = (1 << 19),

	/*
	 * Caller may set this before running vb2api_fw_phase1.  In this case,
	 * it means: "Display is available on this boot.  Please advertise
	 * as such to downstream vboot code and users."
	 *
	 * vboot may also set this before returning from vb2api_fw_phase1.
	 * In this case, it means: "Please initialize display so that it is
	 * available to downstream vboot code and users."  This is used when
	 * vboot encounters some internally-generated request for display
	 * support.
	 */
	VB2_CONTEXT_DISPLAY_INIT = (1 << 20),
};

/*
 * Context for firmware verification.  Pass this to all vboot APIs.
 *
 * Caller may relocate this between calls to vboot APIs.
 */
struct vb2_context {
	/**********************************************************************
	 * Fields which must be initialized by caller.
	 */

	/*
	 * Flags; see vb2_context_flags.  Some flags may only be set by caller
	 * prior to calling vboot functions.
	 */
	uint32_t flags;

	/*
	 * Work buffer, and length in bytes.  Caller may relocate this between
	 * calls to vboot APIs; it contains no internal pointers.  Caller must
	 * not examine the contents of this work buffer directly.
	 */
	uint8_t *workbuf;
	uint32_t workbuf_size;

	/*
	 * Non-volatile data.  Caller must fill this from some non-volatile
	 * location.  If the VB2_CONTEXT_NVDATA_CHANGED flag is set when a
	 * vb2api function returns, caller must save the data back to the
	 * non-volatile location and then clear the flag.
	 */
	uint8_t nvdata[VB2_NVDATA_SIZE_V2];

	/*
	 * Secure data for firmware verification stage.  Caller must fill this
	 * from some secure non-volatile location.  If the
	 * VB2_CONTEXT_SECDATA_CHANGED flag is set when a function returns,
	 * caller must save the data back to the secure non-volatile location
	 * and then clear the flag.
	 */
	uint8_t secdata[VB2_SECDATA_SIZE];

	/*
	 * Context pointer for use by caller.  Verified boot never looks at
	 * this.  Put context here if you need it for APIs that verified boot
	 * may call (vb2ex_...() functions).
	 */
	void *non_vboot_context;

	/**********************************************************************
	 * Fields caller may examine after calling vb2api_fw_phase1().  Caller
	 * must set these fields to 0 before calling any vboot functions.
	 */

	/*
	 * Amount of work buffer used so far.  Verified boot sub-calls use
	 * this to know where the unused work area starts.  Caller may use
	 * this between calls to vboot APIs to know how much data must be
	 * copied when relocating the work buffer.
	 */
	uint32_t workbuf_used;

	/**********************************************************************
	 * Fields caller must initialize before calling vb2api_kernel_phase1().
	 */

	/*
	 * Secure data for kernel verification stage.  Caller must fill this
	 * from some secure non-volatile location.  If the
	 * VB2_CONTEXT_SECDATAK_CHANGED flag is set when a function returns,
	 * caller must save the data back to the secure non-volatile location
	 * and then clear the flag.
	 */
	uint8_t secdatak[VB2_SECDATAK_SIZE];
};

/* Resource index for vb2ex_read_resource() */
enum vb2_resource_index {

	/* Google binary block */
	VB2_RES_GBB,

	/*
	 * Firmware verified boot block (keyblock+preamble).  Use
	 * VB2_CONTEXT_FW_SLOT_B to determine whether this refers to slot A or
	 * slot B; vboot will set that flag to the proper state before reading
	 * the vblock.
	 */
	VB2_RES_FW_VBLOCK,

	/*
	 * Kernel verified boot block (keyblock+preamble) for the current
	 * kernel partition.  Used only by vb2api_kernel_load_vblock().
	 * Contents are allowed to change between calls to that function (to
	 * allow multiple kernels to be examined).
	 */
	VB2_RES_KERNEL_VBLOCK,
};

/* Digest ID for vbapi_get_pcr_digest() */
enum vb2_pcr_digest {
	/* Digest based on current developer and recovery mode flags */
	BOOT_MODE_PCR,

	/* SHA-256 hash digest of HWID, from GBB */
	HWID_DIGEST_PCR,
};

/******************************************************************************
 * APIs provided by verified boot.
 *
 * At a high level, call functions in the order described below.  After each
 * call, examine vb2_context.flags to determine whether nvdata or secdata
 * needs to be written.
 *
 * If you need to cause the boot process to fail at any point, call
 * vb2api_fail().  Then check vb2_context.flags to see what data needs to be
 * written.  Then reboot.
 *
 *	Load nvdata from wherever you keep it.
 *
 *	Load secdata from wherever you keep it.
 *
 *      	If it wasn't there at all (for example, this is the first boot
 *		of a new system in the factory), call vb2api_secdata_create()
 *		to initialize the data.
 *
 *		If access to your storage is unreliable (reads/writes may
 *		contain corrupt data), you may call vb2api_secdata_check() to
 *		determine if the data was valid, and retry reading if it
 *		wasn't.  (In that case, you should also read back and check the
 *		data after any time you write it, to make sure it was written
 *		correctly.)
 *
 *	Call vb2api_fw_phase1().  At present, this nominally decides whether
 *	recovery mode is needed this boot.
 *
 *	Call vb2api_fw_phase2().  At present, this nominally decides which
 *	firmware slot will be attempted (A or B).
 *
 *	Call vb2api_fw_phase3().  At present, this nominally verifies the
 *	firmware keyblock and preamble.
 *
 *	Lock down wherever you keep secdata.  It should no longer be writable
 *	this boot.
 *
 *	Verify the hash of each section of code/data you need to boot the RW
 *	firmware.  For each section:
 *
 *		Call vb2_init_hash() to see if the hash exists.
 *
 *		Load the data for the section.  Call vb2_extend_hash() on the
 *		data as you load it.  You can load it all at once and make one
 *		call, or load and hash-extend a block at a time.
 *
 *		Call vb2_check_hash() to see if the hash is valid.
 *
 *			If it is valid, you may use the data and/or execute
 *			code from that section.
 *
 *			If the hash was invalid, you must reboot.
 *
 * At this point, firmware verification is done, and vb2_context contains the
 * kernel key needed to verify the kernel.  That context should be preserved
 * and passed on to kernel selection.  The kernel selection process may be
 * done by the same firmware image, or may be done by the RW firmware.  The
 * recommended order is:
 *
 *	Load secdatak from wherever you keep it.
 *
 *      	If it wasn't there at all (for example, this is the first boot
 *		of a new system in the factory), call vb2api_secdatak_create()
 *		to initialize the data.
 *
 *		If access to your storage is unreliable (reads/writes may
 *		contain corrupt data), you may call vb2api_secdatak_check() to
 *		determine if the data was valid, and retry reading if it
 *		wasn't.  (In that case, you should also read back and check the
 *		data after any time you write it, to make sure it was written
 *		correctly.)
 *
 *	Call vb2api_kernel_phase1().  At present, this decides which key to
 *	use to verify kernel data - the recovery key from the GBB, or the
 *	kernel subkey from the firmware verification stage.
 *
 *	Kernel phase 2 is finding loading, and verifying the kernel partition.
 *
 *	Find a boot device (you're on your own here).
 *
 *	Call vb2api_load_kernel_vblock() for each kernel partition on the
 *	boot device, until one succeeds.
 *
 *	When that succeeds, call vb2api_get_kernel_size() to determine where
 *	the kernel is located in the stream and how big it is.  Load or map
 *	the kernel.  (Again, you're on your own.  This is the responsibility of
 *	the caller so that the caller can choose whether to allocate a buffer,
 *	load the kernel data into a predefined area of RAM, or directly map a
 *	kernel file into the address space.  Note that technically it doesn't
 *	matter whether the kernel data is even in the same file or stream as
 *	the vblock, as long as the caller loads the right data.
 *
 *	Call vb2api_verify_kernel_data() on the kernel data.
 *
 *	If you ran out of kernels before finding a good one, call vb2api_fail()
 *	with an appropriate recovery reason.
 *
 *	Set the VB2_CONTEXT_ALLOW_KERNEL_ROLL_FORWARD flag if the current
 *	kernel partition has the successful flag (that is, it's already known
 *	or assumed to be a functional kernel partition).
 *
 *	Call vb2api_kernel_phase3().  This cleans up from kernel verification
 *	and updates the secure data if needed.
 *
 *	Lock down wherever you keep secdatak.  It should no longer be writable
 *	this boot.
 */

/**
 * Check the validity of the secure storage context.
 *
 * Checks version and CRC.
 *
 * @param ctx		Context pointer
 * @return VB2_SUCCESS, or non-zero error code if error.
 */
vb2_error_t vb2api_secdata_check(struct vb2_context *ctx);

/**
 * Create fresh data in the secure storage context.
 *
 * Use this only when initializing the secure storage context on a new machine
 * the first time it boots.  Do NOT simply use this if vb2api_secdata_check()
 * (or any other API in this library) fails; that could allow the secure data
 * to be rolled back to an insecure state.
 *
 * @param ctx		Context pointer
 * @return VB2_SUCCESS, or non-zero error code if error.
 */
vb2_error_t vb2api_secdata_create(struct vb2_context *ctx);

/**
 * Check the validity of the kernel version secure storage context.
 *
 * Checks version, UID, and CRC.
 *
 * @param ctx		Context pointer
 * @return VB2_SUCCESS, or non-zero error code if error.
 */
vb2_error_t vb2api_secdatak_check(struct vb2_context *ctx);

/**
 * Create fresh data in the kernel version secure storage context.
 *
 * Use this only when initializing the secure storage context on a new machine
 * the first time it boots.  Do NOT simply use this if vb2api_secdatak_check()
 * (or any other API in this library) fails; that could allow the secure data
 * to be rolled back to an insecure state.
 *
 * @param ctx		Context pointer
 * @return VB2_SUCCESS, or non-zero error code if error.
 */
vb2_error_t vb2api_secdatak_create(struct vb2_context *ctx);

/**
 * Report firmware failure to vboot.
 *
 * This may be called before vb2api_phase1() to indicate errors in the boot
 * process prior to the start of vboot.
 *
 * If this is called after vb2api_phase1(), on return, the calling firmware
 * should check for updates to secdata and/or nvdata, then reboot.
 *
 * @param reason	Recovery reason
 * @param subcode	Recovery subcode
 */
void vb2api_fail(struct vb2_context *ctx, uint8_t reason, uint8_t subcode);

/**
 * Firmware selection, phase 1.
 *
 * If the returned error is VB2_ERROR_API_PHASE1_RECOVERY, the calling firmware
 * should jump directly to recovery-mode firmware without rebooting.
 *
 * For other errors, the calling firmware should check for updates to secdata
 * and/or nvdata, then reboot.
 *
 * @param ctx		Vboot context
 * @return VB2_SUCCESS, or error code on error.
 */
vb2_error_t vb2api_fw_phase1(struct vb2_context *ctx);

/**
 * Firmware selection, phase 2.
 *
 * On error, the calling firmware should check for updates to secdata and/or
 * nvdata, then reboot.
 *
 * @param ctx		Vboot context
 * @return VB2_SUCCESS, or error code on error.
 */
vb2_error_t vb2api_fw_phase2(struct vb2_context *ctx);

/**
 * Firmware selection, phase 3.
 *
 * On error, the calling firmware should check for updates to secdata and/or
 * nvdata, then reboot.
 *
 * On success, the calling firmware should lock down secdata before continuing
 * with the boot process.
 *
 * @param ctx		Vboot context
 * @return VB2_SUCCESS, or error code on error.
 */
vb2_error_t vb2api_fw_phase3(struct vb2_context *ctx);

/**
 * Same, but for new-style structs.
 */
vb2_error_t vb21api_fw_phase3(struct vb2_context *ctx);

/**
 * Initialize hashing data for the specified tag.
 *
 * @param ctx		Vboot context
 * @param tag		Tag to start hashing (enum vb2_hash_tag)
 * @param size		If non-null, expected size of data for tag will be
 *			stored here on output.
 * @return VB2_SUCCESS, or error code on error.
 */
vb2_error_t vb2api_init_hash(struct vb2_context *ctx, uint32_t tag,
			     uint32_t *size);

/**
 * Same, but for new-style structs.
 */
vb2_error_t vb21api_init_hash(struct vb2_context *ctx, const struct vb2_id *id,
			      uint32_t *size);

/**
 * Extend the hash started by vb2api_init_hash() with additional data.
 *
 * (This is the same for both old and new style structs.)
 *
 * @param ctx		Vboot context
 * @param buf		Data to hash
 * @param size		Size of data in bytes
 * @return VB2_SUCCESS, or error code on error.
 */
vb2_error_t vb2api_extend_hash(struct vb2_context *ctx, const void *buf,
			       uint32_t size);

/**
 * Check the hash value started by vb2api_init_hash().
 *
 * @param ctx		Vboot context
 * @return VB2_SUCCESS, or error code on error.
 */
int vb2api_check_hash(struct vb2_context *ctx);

/**
 * Same, but for new-style structs.
 */
vb2_error_t vb21api_check_hash(struct vb2_context *ctx);

/**
 * Check the hash value started by vb2api_init_hash() while retrieving
 * calculated digest.
 *
 * @param ctx			Vboot context
 * @param digest_out		optional pointer to buffer to store digest
 * @param digest_out_size	optional size of buffer to store digest
 * @return VB2_SUCCESS, or error code on error.
 */
vb2_error_t vb2api_check_hash_get_digest(struct vb2_context *ctx,
					 void *digest_out,
					 uint32_t digest_out_size);

/**
 * Get a PCR digest
 *
 * @param ctx		Vboot context
 * @param which_digest	PCR index of the digest
 * @param dest		Destination where the digest is copied.
 * 			Recommended size is VB2_PCR_DIGEST_RECOMMENDED_SIZE.
 * @param dest_size	IN: size of the buffer pointed by dest
 * 			OUT: size of the copied digest
 * @return VB2_SUCCESS, or error code on error
 */
vb2_error_t vb2api_get_pcr_digest(struct vb2_context *ctx,
				  enum vb2_pcr_digest which_digest,
				  uint8_t *dest, uint32_t *dest_size);

/**
 * Prepare for kernel verification stage.
 *
 * Must be called before other vb2api kernel functions.
 *
 * @param ctx		Vboot context
 * @return VB2_SUCCESS, or error code on error.
 */
vb2_error_t vb2api_kernel_phase1(struct vb2_context *ctx);

/**
 * Load the verified boot block (vblock) for a kernel.
 *
 * This function may be called multiple times, to load and verify the
 * vblocks from multiple kernel partitions.
 *
 * @param ctx		Vboot context
 * @param stream	Kernel stream
 * @return VB2_SUCCESS, or error code on error.
 */
vb2_error_t vb2api_load_kernel_vblock(struct vb2_context *ctx);

/**
 * Get the size and offset of the kernel data for the most recent vblock.
 *
 * Valid after a successful call to vb2api_load_kernel_vblock().
 *
 * @param ctx		Vboot context
 * @param offset_ptr	Destination for offset in bytes of kernel data as
 *			reported by vblock.
 * @param size_ptr      Destination for size of kernel data in bytes.
 * @return VB2_SUCCESS, or error code on error.
 */
vb2_error_t vb2api_get_kernel_size(struct vb2_context *ctx,
				   uint32_t *offset_ptr, uint32_t *size_ptr);

/**
 * Verify kernel data using the previously loaded kernel vblock.
 *
 * Valid after a successful call to vb2api_load_kernel_vblock().  This allows
 * the caller to load or map the kernel data, as appropriate, and pass the
 * pointer to the kernel data into vboot.
 *
 * @param ctx		Vboot context
 * @param buf		Pointer to kernel data
 * @param size		Size of kernel data in bytes
 * @return VB2_SUCCESS, or error code on error.
 */
vb2_error_t vb2api_verify_kernel_data(struct vb2_context *ctx, const void *buf,
				      uint32_t size);

/**
 * Clean up after kernel verification.
 *
 * Call this after successfully loading a vblock and verifying kernel data,
 * or if you've run out of boot devices and/or kernel partitions.
 *
 * This cleans up intermediate data structures in the vboot context, and
 * updates the version in the secure data if necessary.
 */
vb2_error_t vb2api_kernel_phase3(struct vb2_context *ctx);

/**
 * Read the hardware ID from the GBB, and store it onto the given buffer.
 *
 * @param ctx		Vboot context.
 * @param hwid		Buffer to store HWID, which will be null-terminated.
 * @param size		Maximum size of HWID including null terminator.  HWID
 * 			length may not exceed 256 (VB2_GBB_HWID_MAX_SIZE), so
 * 			this value is suggested.  If size is too small, then
 * 			VB2_ERROR_INVALID_PARAMETER is returned.  Actual size
 * 			of the output HWID string is returned in this pointer,
 * 			also including null terminator.
 * @return VB2_SUCCESS, or error code on error.
 */
vb2_error_t vb2api_gbb_read_hwid(struct vb2_context *ctx, char *hwid,
				 uint32_t *size);

/**
 * Retrieve current GBB flags.
 *
 * See enum vb2_gbb_flag in 2gbb_flags.h for a list of all GBB flags.
 *
 * @param ctx		Vboot context.
 *
 * @return vb2_gbb_flags_t representing current GBB flags.
 */
vb2_gbb_flags_t vb2api_gbb_get_flags(struct vb2_context *ctx);

/*****************************************************************************/
/* APIs provided by the caller to verified boot */

/**
 * Clear the TPM owner.
 *
 * @param ctx		Vboot context
 * @return VB2_SUCCESS, or error code on error.
 */
vb2_error_t vb2ex_tpm_clear_owner(struct vb2_context *ctx);

/**
 * Read a verified boot resource.
 *
 * @param ctx		Vboot context
 * @param index		Resource index to read
 * @param offset	Byte offset within resource to start at
 * @param buf		Destination for data
 * @param size		Amount of data to read
 * @return VB2_SUCCESS, or error code on error.
 */
vb2_error_t vb2ex_read_resource(struct vb2_context *ctx,
				enum vb2_resource_index index, uint32_t offset,
				void *buf, uint32_t size);

/**
 * Print debug output
 *
 * This should work like printf().  If func!=NULL, it will be a string with
 * the current function name; that can be used to generate prettier debug
 * output.  If func==NULL, don't print any extra header/trailer so that this
 * can be used to composite a bigger output string from several calls - for
 * example, when doing a hex dump.
 *
 * @param func		Function name generating output, or NULL.
 * @param fmt		Printf format string
 */
void vb2ex_printf(const char *func, const char *fmt, ...);

/**
 * Initialize the hardware crypto engine to calculate a block-style digest.
 *
 * @param hash_alg	Hash algorithm to use
 * @param data_size	Expected total size of data to hash
 * @return VB2_SUCCESS, or non-zero error code (HWCRYPTO_UNSUPPORTED not fatal).
 */
vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
				       uint32_t data_size);

/**
 * Extend the hash in the hardware crypto engine with another block of data.
 *
 * @param buf		Next data block to hash
 * @param size		Length of data block in bytes
 * @return VB2_SUCCESS, or non-zero error code.
 */
vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size);

/**
 * Finalize the digest in the hardware crypto engine and extract the result.
 *
 * @param digest	Destination buffer for resulting digest
 * @param digest_size	Length of digest buffer in bytes
 * @return VB2_SUCCESS, or non-zero error code.
 */
vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest,
					   uint32_t digest_size);

/*
 * Set the current TPM mode value, and validate that it was changed.  If one
 * of the following occurs, the function call fails:
 *   - TPM does not understand the instruction (old version)
 *   - TPM has already left the TpmModeEnabledTentative mode
 *   - TPM responds with a mode other than the requested mode
 *   - Some other communication error occurs
 *  Otherwise, the function call succeeds.
 *
 * @param mode_val       Desired TPM mode to set.  May be one of ENABLED
 *                       or DISABLED from vb2_tpm_mode enum.
 * @returns VB2_SUCCESS, or non-zero error code.
 */
vb2_error_t vb2ex_tpm_set_mode(enum vb2_tpm_mode mode_val);

#endif  /* VBOOT_REFERENCE_2API_H_ */