/* Copyright (c) 2011 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.
 *
 * Functions for loading a kernel from disk.
 * (Firmware portion)
 */


#include "cgptlib.h"
#include "cgptlib_internal.h"
#include "gbb_header.h"
#include "load_kernel_fw.h"
#include "rollback_index.h"
#include "utility.h"
#include "vboot_api.h"
#include "vboot_common.h"
#include "vboot_kernel.h"

#define KBUF_SIZE 65536  /* Bytes to read at start of kernel partition */
#define LOWEST_TPM_VERSION 0xffffffff

typedef enum BootMode {
  kBootRecovery = 0,  /* Recovery firmware, regardless of dev switch position */
  kBootNormal = 1,    /* Normal firmware */
  kBootDev = 2        /* Dev firmware AND dev switch is on */
} BootMode;


/* Allocates and reads GPT data from the drive.  The sector_bytes and
 * drive_sectors fields should be filled on input.  The primary and
 * secondary header and entries are filled on output.
 *
 * Returns 0 if successful, 1 if error. */
int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData* gptdata) {

  uint64_t entries_sectors = TOTAL_ENTRIES_SIZE / gptdata->sector_bytes;

  /* No data to be written yet */
  gptdata->modified = 0;

  /* Allocate all buffers */
  gptdata->primary_header = (uint8_t*)VbExMalloc(gptdata->sector_bytes);
  gptdata->secondary_header = (uint8_t*)VbExMalloc(gptdata->sector_bytes);
  gptdata->primary_entries = (uint8_t*)VbExMalloc(TOTAL_ENTRIES_SIZE);
  gptdata->secondary_entries = (uint8_t*)VbExMalloc(TOTAL_ENTRIES_SIZE);

  if (gptdata->primary_header == NULL || gptdata->secondary_header == NULL ||
      gptdata->primary_entries == NULL || gptdata->secondary_entries == NULL)
    return 1;

  /* Read data from the drive, skipping the protective MBR */
  if (0 != VbExDiskRead(disk_handle, 1, 1, gptdata->primary_header))
    return 1;
  if (0 != VbExDiskRead(disk_handle, 2, entries_sectors,
                        gptdata->primary_entries))
    return 1;
  if (0 != VbExDiskRead(disk_handle,
                        gptdata->drive_sectors - entries_sectors - 1,
                        entries_sectors, gptdata->secondary_entries))
    return 1;
  if (0 != VbExDiskRead(disk_handle, gptdata->drive_sectors - 1, 1,
                        gptdata->secondary_header))
    return 1;

  return 0;
}


/* Writes any changes for the GPT data back to the drive, then frees
 * the buffers.
 *
 * Returns 0 if successful, 1 if error. */
int WriteAndFreeGptData(VbExDiskHandle_t disk_handle, GptData* gptdata) {

  uint64_t entries_sectors = TOTAL_ENTRIES_SIZE / gptdata->sector_bytes;

  if (gptdata->primary_header) {
    if (gptdata->modified & GPT_MODIFIED_HEADER1) {
      VBDEBUG(("Updating GPT header 1\n"));
      if (0 != VbExDiskWrite(disk_handle, 1, 1, gptdata->primary_header))
        return 1;
    }
    VbExFree(gptdata->primary_header);
  }

  if (gptdata->primary_entries) {
    if (gptdata->modified & GPT_MODIFIED_ENTRIES1) {
      VBDEBUG(("Updating GPT entries 1\n"));
      if (0 != VbExDiskWrite(disk_handle, 2, entries_sectors,
                             gptdata->primary_entries))
        return 1;
    }
    VbExFree(gptdata->primary_entries);
  }

  if (gptdata->secondary_entries) {
    if (gptdata->modified & GPT_MODIFIED_ENTRIES2) {
      VBDEBUG(("Updating GPT header 2\n"));
      if (0 != VbExDiskWrite(disk_handle,
                             gptdata->drive_sectors - entries_sectors - 1,
                             entries_sectors, gptdata->secondary_entries))
        return 1;
    }
    VbExFree(gptdata->secondary_entries);
  }

  if (gptdata->secondary_header) {
    if (gptdata->modified & GPT_MODIFIED_HEADER2) {
      VBDEBUG(("Updating GPT entries 2\n"));
      if (0 != VbExDiskWrite(disk_handle, gptdata->drive_sectors - 1, 1,
                             gptdata->secondary_header))
        return 1;
    }
    VbExFree(gptdata->secondary_header);
  }

  /* Success */
  return 0;
}

/* disable MSVC warning on const logical expression (as in } while(0);) */
__pragma(warning(disable: 4127))

int LoadKernel(LoadKernelParams* params) {
  VbSharedDataHeader* shared = (VbSharedDataHeader*)params->shared_data_blob;
  VbSharedDataKernelCall* shcall = NULL;
  VbNvContext* vnc = params->nv_context;
  GoogleBinaryBlockHeader* gbb = (GoogleBinaryBlockHeader*)params->gbb_data;
  VbPublicKey* kernel_subkey;
  GptData gpt;
  uint64_t part_start, part_size;
  uint64_t blba;
  uint64_t kbuf_sectors;
  uint8_t* kbuf = NULL;
  int found_partitions = 0;
  int good_partition = -1;
  int good_partition_key_block_valid = 0;
  uint32_t tpm_version = 0;
  uint64_t lowest_version = LOWEST_TPM_VERSION;
  int rec_switch, dev_switch;
  BootMode boot_mode;
  uint32_t test_err = 0;
  uint32_t status;

  int retval = LOAD_KERNEL_RECOVERY;
  int recovery = VBNV_RECOVERY_RO_UNSPECIFIED;

  /* Setup NV storage */
  VbNvSetup(vnc);

  /* Sanity Checks */
  if (!params ||
      !params->bytes_per_lba ||
      !params->ending_lba ||
      !params->kernel_buffer ||
      !params->kernel_buffer_size) {
    VBDEBUG(("LoadKernel() called with invalid params\n"));
    goto LoadKernelExit;
  }

  /* Clear output params in case we fail */
  params->partition_number = 0;
  params->bootloader_address = 0;
  params->bootloader_size = 0;

  /* Calculate switch positions and boot mode */
  rec_switch = (BOOT_FLAG_RECOVERY & params->boot_flags ? 1 : 0);
  dev_switch = (BOOT_FLAG_DEVELOPER & params->boot_flags ? 1 : 0);
  if (rec_switch)
    boot_mode = kBootRecovery;
  else if (BOOT_FLAG_DEV_FIRMWARE & params->boot_flags)
    boot_mode = kBootDev;
  else {
    /* Normal firmware */
    boot_mode = kBootNormal;
    dev_switch = 0;  /* Always do a fully verified boot */
  }

  /* Set up tracking for this call.  This wraps around if called many times,
   * so we need to initialize the call entry each time. */
  shcall = shared->lk_calls + (shared->lk_call_count
                               & (VBSD_MAX_KERNEL_CALLS - 1));
  Memset(shcall, 0, sizeof(VbSharedDataKernelCall));
  shcall->boot_flags = (uint32_t)params->boot_flags;
  shcall->boot_mode = boot_mode;
  shcall->sector_size = (uint32_t)params->bytes_per_lba;
  shcall->sector_count = params->ending_lba + 1;
  shared->lk_call_count++;

  /* Handle test errors */
  VbNvGet(vnc, VBNV_TEST_ERROR_FUNC, &test_err);
  if (VBNV_TEST_ERROR_LOAD_KERNEL == test_err) {
    /* Get error code */
    VbNvGet(vnc, VBNV_TEST_ERROR_NUM, &test_err);
    shcall->test_error_num = (uint8_t)test_err;
    /* Clear test params so we don't repeat the error */
    VbNvSet(vnc, VBNV_TEST_ERROR_FUNC, 0);
    VbNvSet(vnc, VBNV_TEST_ERROR_NUM, 0);
    /* Handle error codes */
    switch (test_err) {
      case LOAD_KERNEL_RECOVERY:
        recovery = VBNV_RECOVERY_RW_TEST_LK;
        goto LoadKernelExit;
      case LOAD_KERNEL_NOT_FOUND:
      case LOAD_KERNEL_INVALID:
      case LOAD_KERNEL_REBOOT:
        retval = test_err;
        goto LoadKernelExit;
      default:
        break;
    }
  }

  /* Initialization */
  blba = params->bytes_per_lba;
  kbuf_sectors = KBUF_SIZE / blba;
  if (0 == kbuf_sectors) {
    VBDEBUG(("LoadKernel() called with sector size > KBUF_SIZE\n"));
    goto LoadKernelExit;
  }

  if (kBootDev == boot_mode && !dev_switch) {
      /* Dev firmware should be signed such that it never boots with the dev
       * switch is off; so something is terribly wrong. */
    VBDEBUG(("LoadKernel() called with dev firmware but dev switch off\n"));
    shcall->check_result = VBSD_LKC_CHECK_DEV_SWITCH_MISMATCH;
    recovery = VBNV_RECOVERY_RW_DEV_MISMATCH;
    goto LoadKernelExit;
  }

  if (kBootRecovery == boot_mode) {
    /* Use the recovery key to verify the kernel */
    kernel_subkey = (VbPublicKey*)((uint8_t*)gbb + gbb->recovery_key_offset);

    /* Let the TPM know if we're in recovery mode */
    if (0 != RollbackKernelRecovery(dev_switch)) {
      VBDEBUG(("Error setting up TPM for recovery kernel\n"));
      shcall->flags |= VBSD_LK_FLAG_REC_TPM_INIT_ERROR;
      /* Ignore return code, since we need to boot recovery mode to
       * fix the TPM. */
    }

    /* Read the key indices from the TPM; ignore any errors */
    RollbackFirmwareRead(&shared->fw_version_tpm);
    RollbackKernelRead(&shared->kernel_version_tpm);
  } else {
    /* Use the kernel subkey passed from LoadFirmware(). */
    kernel_subkey = &shared->kernel_subkey;

    /* Read current kernel key index from TPM.  Assumes TPM is already
     * initialized. */
    status = RollbackKernelRead(&tpm_version);
    if (0 != status) {
      VBDEBUG(("Unable to get kernel versions from TPM\n"));
      if (status == TPM_E_MUST_REBOOT)
        retval = LOAD_KERNEL_REBOOT;
      else
        recovery = VBNV_RECOVERY_RW_TPM_ERROR;
      goto LoadKernelExit;
    }
    shared->kernel_version_tpm = tpm_version;
  }

  do {
    /* Read GPT data */
    gpt.sector_bytes = (uint32_t)blba;
    gpt.drive_sectors = params->ending_lba + 1;
    if (0 != AllocAndReadGptData(params->disk_handle, &gpt)) {
      VBDEBUG(("Unable to read GPT data\n"));
      shcall->check_result = VBSD_LKC_CHECK_GPT_READ_ERROR;
      break;
    }

    /* Initialize GPT library */
    if (GPT_SUCCESS != GptInit(&gpt)) {
      VBDEBUG(("Error parsing GPT\n"));
      shcall->check_result = VBSD_LKC_CHECK_GPT_PARSE_ERROR;
      break;
    }

    /* Allocate kernel header buffers */
    kbuf = (uint8_t*)VbExMalloc(KBUF_SIZE);
    if (!kbuf)
      break;

    /* 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;
      uint64_t key_version;
      uint64_t combined_version;
      uint64_t body_offset;
      uint64_t body_offset_sectors;
      uint64_t body_sectors;
      int key_block_valid = 1;

      VBDEBUG(("Found kernel entry at %" PRIu64 " size %" PRIu64 "\n",
              part_start, part_size));

      /* Set up tracking for this partition.  This wraps around if called
       * many times, so initialize the partition entry each time. */
      shpart = shcall->parts + (shcall->kernel_parts_found
                                & (VBSD_MAX_KERNEL_PARTS - 1));
      Memset(shpart, 0, sizeof(VbSharedDataKernelPart));
      shpart->sector_start = part_start;
      shpart->sector_count = part_size;
      /* TODO: GPT partitions start at 1, but cgptlib starts them at 0.
       * Adjust here, until cgptlib is fixed. */
      shpart->gpt_index = (uint8_t)(gpt.current_kernel + 1);
      shcall->kernel_parts_found++;

      /* Found at least one kernel partition. */
      found_partitions++;

      /* Read the first part of the kernel partition. */
      if (part_size < kbuf_sectors) {
        VBDEBUG(("Partition too small to hold kernel.\n"));
        shpart->check_result = VBSD_LKP_CHECK_TOO_SMALL;
        goto bad_kernel;
      }

      if (0 != VbExDiskRead(params->disk_handle, part_start, kbuf_sectors,
                            kbuf)) {
        VBDEBUG(("Unable to read start of partition.\n"));
        shpart->check_result = VBSD_LKP_CHECK_READ_START;
        goto bad_kernel;
      }

      /* Verify the key block. */
      key_block = (VbKeyBlockHeader*)kbuf;
      if (0 != KeyBlockVerify(key_block, KBUF_SIZE, kernel_subkey, 0)) {
        VBDEBUG(("Verifying key block signature failed.\n"));
        shpart->check_result = VBSD_LKP_CHECK_KEY_BLOCK_SIG;

        key_block_valid = 0;

        /* If we're not in developer mode, this kernel is bad. */
        if (kBootDev != boot_mode)
          goto bad_kernel;

        /* In developer mode, we can continue if the SHA-512 hash of the key
         * block is valid. */
        if (0 != KeyBlockVerify(key_block, KBUF_SIZE, kernel_subkey, 1)) {
          VBDEBUG(("Verifying key block hash failed.\n"));
          shpart->check_result = VBSD_LKP_CHECK_KEY_BLOCK_HASH;
          goto bad_kernel;
        }
      }

      /* Check the key block flags against the current boot mode. */
      if (!(key_block->key_block_flags &
            (dev_switch ? KEY_BLOCK_FLAG_DEVELOPER_1 :
             KEY_BLOCK_FLAG_DEVELOPER_0))) {
        VBDEBUG(("Key block developer flag mismatch.\n"));
        shpart->check_result = VBSD_LKP_CHECK_DEV_MISMATCH;
        key_block_valid = 0;
      }
      if (!(key_block->key_block_flags &
            (rec_switch ? KEY_BLOCK_FLAG_RECOVERY_1 :
             KEY_BLOCK_FLAG_RECOVERY_0))) {
        VBDEBUG(("Key block recovery flag mismatch.\n"));
        shpart->check_result = VBSD_LKP_CHECK_REC_MISMATCH;
        key_block_valid = 0;
      }

      /* Check for rollback of key version except in recovery mode. */
      key_version = key_block->data_key.key_version;
      if (kBootRecovery != boot_mode) {
        if (key_version < (tpm_version >> 16)) {
          VBDEBUG(("Key version too old.\n"));
          shpart->check_result = VBSD_LKP_CHECK_KEY_ROLLBACK;
          key_block_valid = 0;
        }
      }

      /* If we're not in developer mode, require the key block to be valid. */
      if (kBootDev != boot_mode && !key_block_valid) {
        VBDEBUG(("Key block is invalid.\n"));
        goto bad_kernel;
      }

      /* Get the key for preamble/data verification from the key block. */
      data_key = PublicKeyToRSA(&key_block->data_key);
      if (!data_key) {
        VBDEBUG(("Data key bad.\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))) {
        VBDEBUG(("Preamble verification failed.\n"));
        shpart->check_result = VBSD_LKP_CHECK_VERIFY_PREAMBLE;
        goto bad_kernel;
      }

      /* If the key block is valid and we're not in recovery mode, check for
       * rollback of the kernel version. */
      combined_version = ((key_version << 16) |
                          (preamble->kernel_version & 0xFFFF));
      shpart->combined_version = (uint32_t)combined_version;
      if (key_block_valid && kBootRecovery != boot_mode) {
        if (combined_version < tpm_version) {
          VBDEBUG(("Kernel version too low.\n"));
          shpart->check_result = VBSD_LKP_CHECK_KERNEL_ROLLBACK;
          /* If we're not in developer mode, kernel version must be valid. */
          if (kBootDev != boot_mode)
            goto bad_kernel;
        }
      }

      VBDEBUG(("Kernel preamble is good.\n"));
      shpart->check_result = VBSD_LKP_CHECK_PREAMBLE_VALID;

      /* Check for lowest version from a valid header. */
      if (key_block_valid && lowest_version > combined_version)
        lowest_version = combined_version;
      else {
        VBDEBUG(("Key block valid: %d\n", key_block_valid));
        VBDEBUG(("Combined version: %" PRIu64 "\n", combined_version));
      }

      /* If we already have a good kernel, no need to read another
       * one; we only needed to look at the versions to check for
       * rollback.  So skip to the next kernel preamble. */
      if (-1 != good_partition)
        continue;

      /* Verify body load address matches what we expect */
      if ((preamble->body_load_address != (size_t)params->kernel_buffer) &&
          !(params->boot_flags & BOOT_FLAG_SKIP_ADDR_CHECK)) {
        VBDEBUG(("Wrong body load address.\n"));
        shpart->check_result = VBSD_LKP_CHECK_BODY_ADDRESS;
        goto bad_kernel;
      }

      /* Verify kernel body starts at a multiple of the sector size. */
      body_offset = key_block->key_block_size + preamble->preamble_size;
      if (0 != body_offset % blba) {
        VBDEBUG(("Kernel body not at multiple of sector size.\n"));
        shpart->check_result = VBSD_LKP_CHECK_BODY_OFFSET;
        goto bad_kernel;
      }
      body_offset_sectors = body_offset / blba;

      /* Verify kernel body fits in the buffer */
      body_sectors = (preamble->body_signature.data_size + blba - 1) / blba;
      if (body_sectors * blba > params->kernel_buffer_size) {
        VBDEBUG(("Kernel body doesn't fit in memory.\n"));
        shpart->check_result = VBSD_LKP_CHECK_BODY_EXCEEDS_MEM;
        goto bad_kernel;
      }

      /* Verify kernel body fits in the partition */
      if (body_offset_sectors + body_sectors > part_size) {
        VBDEBUG(("Kernel body doesn't fit in partition.\n"));
        shpart->check_result = VBSD_LKP_CHECK_BODY_EXCEEDS_PART;
        goto bad_kernel;
      }

      /* Read the kernel data */
      VBPERFSTART("VB_RKD");
      if (0 != VbExDiskRead(params->disk_handle,
                            part_start + body_offset_sectors,
                            body_sectors, params->kernel_buffer)) {
        VBDEBUG(("Unable to read kernel data.\n"));
        VBPERFEND("VB_RKD");
        shpart->check_result = VBSD_LKP_CHECK_READ_DATA;
        goto bad_kernel;
      }
      VBPERFEND("VB_RKD");

      /* Verify kernel data */
      if (0 != VerifyData((const uint8_t*)params->kernel_buffer,
                          params->kernel_buffer_size,
                          &preamble->body_signature, data_key)) {
        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 */
      VBDEBUG(("Partition is good.\n"));
      shpart->check_result = VBSD_LKP_CHECK_KERNEL_GOOD;
      if (key_block_valid)
        shpart->flags |= VBSD_LKP_FLAG_KEY_BLOCK_VALID;

      good_partition_key_block_valid = key_block_valid;
      /* TODO: GPT partitions start at 1, but cgptlib starts them at 0.
       * Adjust here, until cgptlib is fixed. */
      good_partition = gpt.current_kernel + 1;
      params->partition_number = gpt.current_kernel + 1;
      GetCurrentKernelUniqueGuid(&gpt, &params->partition_guid);
      /* TODO: GetCurrentKernelUniqueGuid() should take a destination size, or
       * the dest should be a struct, so we know it's big enough. */
      params->bootloader_address = preamble->bootloader_address;
      params->bootloader_size = preamble->bootloader_size;

      /* Update GPT to note this is the kernel we're trying */
      GptUpdateKernelEntry(&gpt, GPT_UPDATE_ENTRY_TRY);

      /* If we're in recovery mode or we're about to boot a dev-signed kernel,
       * there's no rollback protection, so we can stop at the first valid
       * kernel. */
      if (kBootRecovery == boot_mode || !key_block_valid) {
        VBDEBUG(("In recovery mode or dev-signed kernel\n"));
        break;
      }

      /* Otherwise, we do care about the key index in the TPM.  If the good
       * partition's key version is the same as the tpm, then the TPM doesn't
       * need updating; we can stop now.  Otherwise, we'll check all the other
       * headers to see if they contain a newer key. */
      if (combined_version == tpm_version) {
        VBDEBUG(("Same kernel version\n"));
        break;
      }

      /* Continue, so that we skip the error handling code below */
      continue;

   bad_kernel:
      /* Handle errors parsing this kernel */
      if (NULL != data_key)
        RSAPublicKeyFree(data_key);

      VBDEBUG(("Marking kernel as invalid.\n"));
      GptUpdateKernelEntry(&gpt, GPT_UPDATE_ENTRY_BAD);


    } /* while(GptNextKernelEntry) */
  } while(0);

  /* Free kernel buffer */
  if (kbuf)
    VbExFree(kbuf);

  /* Write and free GPT data */
  WriteAndFreeGptData(params->disk_handle, &gpt);

  /* Handle finding a good partition */
  if (good_partition >= 0) {
    VBDEBUG(("Good_partition >= 0\n"));
    shcall->check_result = VBSD_LKC_CHECK_GOOD_PARTITION;

    /* See if we need to update the TPM */
    if ((kBootNormal == boot_mode) &&
        !((1 == shared->firmware_index) && (shared->flags & VBSD_FWB_TRIED))) {
      /* We only update the TPM in normal mode.  We don't advance the
       * TPM if we're trying a new firmware B, because that firmware
       * may have a key change and roll forward the TPM too soon. */
      VBDEBUG(("Checking if TPM kernel version needs advancing\n"));

      if ((lowest_version > tpm_version) &&
          (lowest_version != LOWEST_TPM_VERSION)) {
        status = RollbackKernelWrite((uint32_t)lowest_version);
        if (0 != status) {
          VBDEBUG(("Error writing kernel versions to TPM.\n"));
          if (status == TPM_E_MUST_REBOOT)
            retval = LOAD_KERNEL_REBOOT;
          else
            recovery = VBNV_RECOVERY_RW_TPM_ERROR;
          goto LoadKernelExit;
        }
        shared->kernel_version_tpm = (uint32_t)lowest_version;
      }
    }

    /* Lock the kernel versions */
    status = RollbackKernelLock();
    if (0 != status) {
      VBDEBUG(("Error locking kernel versions.\n"));
      /* Don't reboot to recovery mode if we're already there */
      if (kBootRecovery != boot_mode) {
        if (status == TPM_E_MUST_REBOOT)
          retval = LOAD_KERNEL_REBOOT;
        else
          recovery = VBNV_RECOVERY_RW_TPM_ERROR;
        goto LoadKernelExit;
      }
    }

    /* Success! */
    retval = LOAD_KERNEL_SUCCESS;
  } else {
    shcall->check_result = (found_partitions > 0
                            ? VBSD_LKC_CHECK_INVALID_PARTITIONS
                            : VBSD_LKC_CHECK_NO_PARTITIONS);

    /* TODO: differentiate between finding an invalid kernel
     * (found_partitions>0) and not finding one at all.  Right now we
     * treat them the same, and return LOAD_KERNEL_INVALID for both. */
    retval = LOAD_KERNEL_INVALID;
  }

LoadKernelExit:

  /* Store recovery request, if any, then tear down non-volatile storage */
  VbNvSet(vnc, VBNV_RECOVERY_REQUEST, LOAD_KERNEL_RECOVERY == retval ?
          recovery : VBNV_RECOVERY_NOT_REQUESTED);
  VbNvTeardown(vnc);

  shcall->return_code = (uint8_t)retval;

  /* Save whether the good partition's key block was fully verified */
  if (good_partition_key_block_valid)
    shared->flags |= VBSD_KERNEL_KEY_VERIFIED;

  /* Store how much shared data we used, if any */
  params->shared_data_size = shared->data_used;

  return retval;
}
