summaryrefslogtreecommitdiff
path: root/firmware/lib/vboot_kernel.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/lib/vboot_kernel.c')
-rw-r--r--firmware/lib/vboot_kernel.c88
1 files changed, 60 insertions, 28 deletions
diff --git a/firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c
index be5389a4..cf6f92bc 100644
--- a/firmware/lib/vboot_kernel.c
+++ b/firmware/lib/vboot_kernel.c
@@ -7,8 +7,10 @@
*/
#include "sysincludes.h"
+#include "2sysincludes.h"
#include "2common.h"
+#include "2rsa.h"
#include "2sha.h"
#include "cgptlib.h"
#include "cgptlib_internal.h"
@@ -19,6 +21,7 @@
#include "load_kernel_fw.h"
#include "rollback_index.h"
#include "utility.h"
+#include "vb2_common.h"
#include "vboot_api.h"
#include "vboot_common.h"
#include "vboot_kernel.h"
@@ -37,14 +40,14 @@ VbError_t LoadKernel(LoadKernelParams *params, VbCommonParams *cparams)
VbSharedDataHeader *shared =
(VbSharedDataHeader *)params->shared_data_blob;
VbSharedDataKernelCall *shcall = NULL;
- VbNvContext* vnc = params->nv_context;
- VbPublicKey* kernel_subkey = NULL;
+ VbNvContext *vnc = params->nv_context;
+ VbPublicKey *kernel_subkey = NULL;
int free_kernel_subkey = 0;
GptData gpt;
uint64_t part_start, part_size;
uint64_t blba;
uint64_t kbuf_sectors;
- uint8_t* kbuf = NULL;
+ uint8_t *kbuf = NULL;
int found_partitions = 0;
int good_partition = -1;
int good_partition_key_block_valid = 0;
@@ -58,6 +61,9 @@ VbError_t LoadKernel(LoadKernelParams *params, VbCommonParams *cparams)
VbError_t retval = VBERROR_UNKNOWN;
int recovery = VBNV_RECOVERY_LK_UNSPECIFIED;
+ uint8_t *workbuf = NULL;
+ struct vb2_workbuf wb;
+
/* Sanity Checks */
if (!params->bytes_per_lba ||
!params->streaming_lba_count) {
@@ -141,17 +147,34 @@ VbError_t LoadKernel(LoadKernelParams *params, VbCommonParams *cparams)
}
/* Allocate kernel header buffers */
- kbuf = (uint8_t*)VbExMalloc(KBUF_SIZE);
+ kbuf = (uint8_t *)VbExMalloc(KBUF_SIZE);
if (!kbuf)
goto bad_gpt;
+ /* Allocate work buffer */
+ workbuf = (uint8_t *)
+ VbExMalloc(VB2_VERIFY_KERNEL_PREAMBLE_WORKBUF_BYTES);
+ if (!workbuf)
+ goto bad_gpt;
+ vb2_workbuf_init(&wb, workbuf,
+ VB2_VERIFY_KERNEL_PREAMBLE_WORKBUF_BYTES);
+
+ /* Unpack kernel subkey */
+ struct vb2_public_key kernel_subkey2;
+ if (VB2_SUCCESS != vb2_unpack_key(&kernel_subkey2,
+ (const uint8_t *)kernel_subkey,
+ kernel_subkey->key_offset +
+ kernel_subkey->key_size)) {
+ VBDEBUG(("Unable to unpack kernel subkey\n"));
+ goto bad_gpt;
+ }
+
/* Loop over candidate kernel partitions */
while (GPT_SUCCESS ==
GptNextKernelEntry(&gpt, &part_start, &part_size)) {
VbSharedDataKernelPart *shpart = NULL;
VbKeyBlockHeader *key_block;
VbKernelPreambleHeader *preamble;
- RSAPublicKey *data_key = NULL;
VbExStream_t stream = NULL;
uint64_t key_version;
uint32_t combined_version;
@@ -197,8 +220,9 @@ VbError_t LoadKernel(LoadKernelParams *params, VbCommonParams *cparams)
/* Verify the key block. */
key_block = (VbKeyBlockHeader*)kbuf;
- if (0 != KeyBlockVerify(key_block, KBUF_SIZE,
- kernel_subkey, 0)) {
+ struct vb2_keyblock *keyblock2 = (struct vb2_keyblock *)kbuf;
+ if (VB2_SUCCESS != vb2_verify_keyblock(keyblock2, KBUF_SIZE,
+ &kernel_subkey2, &wb)) {
VBDEBUG(("Verifying key block signature failed.\n"));
shpart->check_result = VBSD_LKP_CHECK_KEY_BLOCK_SIG;
key_block_valid = 0;
@@ -222,8 +246,9 @@ VbError_t LoadKernel(LoadKernelParams *params, VbCommonParams *cparams)
* Allow the kernel if the SHA-512 hash of the key
* block is valid.
*/
- if (0 != KeyBlockVerify(key_block, KBUF_SIZE,
- kernel_subkey, 1)) {
+ if (VB2_SUCCESS !=
+ vb2_verify_keyblock_hash(keyblock2, KBUF_SIZE,
+ &wb)) {
VBDEBUG(("Verifying key block hash failed.\n"));
shpart->check_result =
VBSD_LKP_CHECK_KEY_BLOCK_HASH;
@@ -309,20 +334,29 @@ VbError_t LoadKernel(LoadKernelParams *params, VbCommonParams *cparams)
}
/* Get key for preamble/data verification from the key block. */
- data_key = PublicKeyToRSA(&key_block->data_key);
- if (!data_key) {
- VBDEBUG(("Data key bad.\n"));
+ struct vb2_public_key data_key2;
+ if (VB2_SUCCESS !=
+ vb2_unpack_key(&data_key2,
+ (const uint8_t *)&keyblock2->data_key,
+ keyblock2->data_key.key_offset +
+ keyblock2->data_key.key_size)) {
+ VBDEBUG(("Unable to unpack kernel data key\n"));
shpart->check_result = VBSD_LKP_CHECK_DATA_KEY_PARSE;
goto bad_kernel;
}
/* Verify the preamble, which follows the key block */
preamble = (VbKernelPreambleHeader *)
- (kbuf + key_block->key_block_size);
- if ((0 != VerifyKernelPreamble(
- preamble,
- KBUF_SIZE - key_block->key_block_size,
- data_key))) {
+ (kbuf + key_block->key_block_size);
+ struct vb2_kernel_preamble *preamble2 =
+ (struct vb2_kernel_preamble *)
+ (kbuf + key_block->key_block_size);
+
+ if (VB2_SUCCESS != vb2_verify_kernel_preamble(
+ preamble2,
+ KBUF_SIZE - key_block->key_block_size,
+ &data_key2,
+ &wb)) {
VBDEBUG(("Preamble verification failed.\n"));
shpart->check_result = VBSD_LKP_CHECK_VERIFY_PREAMBLE;
goto bad_kernel;
@@ -442,18 +476,17 @@ VbError_t LoadKernel(LoadKernelParams *params, VbCommonParams *cparams)
stream = NULL;
/* Verify kernel data */
- if (0 != VerifyData((const uint8_t *)params->kernel_buffer,
- params->kernel_buffer_size,
- &preamble->body_signature, data_key)) {
+ struct vb2_signature *body_sig = (struct vb2_signature *)
+ &preamble->body_signature;
+ if (VB2_SUCCESS != vb2_verify_data(
+ (const uint8_t *)params->kernel_buffer,
+ params->kernel_buffer_size,
+ body_sig, &data_key2, &wb)) {
VBDEBUG(("Kernel data verification failed.\n"));
shpart->check_result = VBSD_LKP_CHECK_VERIFY_DATA;
goto bad_kernel;
}
- /* Done with the kernel signing key, so can free it now */
- RSAPublicKeyFree(data_key);
- data_key = NULL;
-
/*
* If we're still here, the kernel is valid. Save the first
* good partition we find; that's the one we'll boot.
@@ -517,8 +550,6 @@ bad_kernel:
/* Handle errors parsing this kernel */
if (NULL != stream)
VbExStreamClose(stream);
- if (NULL != data_key)
- RSAPublicKeyFree(data_key);
VBDEBUG(("Marking kernel as invalid.\n"));
GptUpdateKernelEntry(&gpt, GPT_UPDATE_ENTRY_BAD);
@@ -527,8 +558,9 @@ bad_kernel:
} /* while(GptNextKernelEntry) */
bad_gpt:
-
- /* Free kernel buffer */
+ /* Free buffers */
+ if (workbuf)
+ VbExFree(workbuf);
if (kbuf)
VbExFree(kbuf);