More cleanup

Review URL: http://codereview.chromium.org/2718012
This commit is contained in:
Randall Spangler
2010-06-11 16:14:18 -07:00
parent 729b87258b
commit 83c88cfa69
9 changed files with 144 additions and 192 deletions

View File

@@ -95,7 +95,6 @@ int GptUpdateKernelEntry(GptData* gpt, uint32_t update_type) {
GptEntry* e = entries + gpt->current_kernel; GptEntry* e = entries + gpt->current_kernel;
uint64_t previous_attr = e->attributes; uint64_t previous_attr = e->attributes;
/* TODO: need a better return code for these errors? */
if (gpt->current_kernel == CGPT_KERNEL_ENTRY_NOT_FOUND) if (gpt->current_kernel == CGPT_KERNEL_ENTRY_NOT_FOUND)
return GPT_ERROR_INVALID_UPDATE_TYPE; return GPT_ERROR_INVALID_UPDATE_TYPE;
if (!IsKernelEntry(e)) if (!IsKernelEntry(e))

View File

@@ -60,7 +60,7 @@ int CheckHeader(GptHeader *h, int is_secondary, uint64_t drive_sectors) {
if (h->reserved_zero) if (h->reserved_zero)
return 1; return 1;
/* TODO: Padding must be set to zero. */ /* Could check that padding is zero, but that doesn't matter to us. */
/* If entry size is different than our struct, we won't be able to /* If entry size is different than our struct, we won't be able to
* parse it. Technically, any size 2^N where N>=7 is valid. */ * parse it. Technically, any size 2^N where N>=7 is valid. */

View File

@@ -24,6 +24,10 @@ enum {
#define GPT_MODIFIED_ENTRIES1 0x04 #define GPT_MODIFIED_ENTRIES1 0x04
#define GPT_MODIFIED_ENTRIES2 0x08 #define GPT_MODIFIED_ENTRIES2 0x08
#define TOTAL_ENTRIES_SIZE 16384 /* Size of GptData.primary_entries
* and secondary_entries: 128
* bytes/entry * 128 entries. */
/* The 'update_type' of GptUpdateKernelEntry() /* The 'update_type' of GptUpdateKernelEntry()
* We expose TRY and BAD only because those are what verified boot needs. * We expose TRY and BAD only because those are what verified boot needs.
* For more precise control on GPT attribute bits, please refer to * For more precise control on GPT attribute bits, please refer to

View File

@@ -44,7 +44,6 @@
CGPT_ATTRIBUTE_PRIORITY_OFFSET) CGPT_ATTRIBUTE_PRIORITY_OFFSET)
/* Defines ChromeOS-specific limitation on GPT */ /* Defines ChromeOS-specific limitation on GPT */
/* TODO: Move these to cgptlib_internal.h */
#define MIN_SIZE_OF_HEADER 92 #define MIN_SIZE_OF_HEADER 92
#define MAX_SIZE_OF_HEADER 512 #define MAX_SIZE_OF_HEADER 512
#define MIN_SIZE_OF_ENTRY 128 #define MIN_SIZE_OF_ENTRY 128
@@ -52,7 +51,6 @@
#define SIZE_OF_ENTRY_MULTIPLE 8 #define SIZE_OF_ENTRY_MULTIPLE 8
#define MIN_NUMBER_OF_ENTRIES 32 #define MIN_NUMBER_OF_ENTRIES 32
#define MAX_NUMBER_OF_ENTRIES 512 #define MAX_NUMBER_OF_ENTRIES 512
#define TOTAL_ENTRIES_SIZE 16384 /* usual case is 128 bytes * 128 entries */
/* Defines GPT sizes */ /* Defines GPT sizes */
#define GPT_PMBR_SECTOR 1 /* size (in sectors) of PMBR */ #define GPT_PMBR_SECTOR 1 /* size (in sectors) of PMBR */

View File

@@ -13,16 +13,20 @@
#include "cryptolib.h" #include "cryptolib.h"
#include "vboot_struct.h" #include "vboot_struct.h"
/* Error Codes for VerifyFirmware. */ /* Error Codes for all common functions. */
#define VBOOT_SUCCESS 0 enum {
#define VBOOT_INVALID_IMAGE 1 VBOOT_SUCCESS = 0,
#define VBOOT_KEY_SIGNATURE_FAILED 2 VBOOT_KEY_BLOCK_INVALID, /* Key block internal structure is
#define VBOOT_INVALID_ALGORITHM 3 * invalid, or not a key block */
#define VBOOT_PREAMBLE_SIGNATURE_FAILED 4 VBOOT_KEY_BLOCK_SIGNATURE, /* Key block signature check failed */
#define VBOOT_SIGNATURE_FAILED 5 VBOOT_KEY_BLOCK_HASH, /* Key block hash check failed */
#define VBOOT_WRONG_MAGIC 6 VBOOT_PUBLIC_KEY_INVALID, /* Invalid public key passed to a
#define VBOOT_ERROR_MAX 7 /* Generic catch-all. */ * signature verficiation function. */
VBOOT_PREAMBLE_INVALID, /* Preamble internal structure is
* invalid */
VBOOT_PREAMBLE_SIGNATURE, /* Preamble signature check failed */
VBOOT_ERROR_MAX,
};
extern char* kVbootErrors[VBOOT_ERROR_MAX]; extern char* kVbootErrors[VBOOT_ERROR_MAX];

View File

@@ -12,12 +12,7 @@
#include <stdint.h> #include <stdint.h>
#include "cgptlib.h" #include "cgptlib.h"
#include "cryptolib.h"
#include "load_kernel_fw.h" #include "load_kernel_fw.h"
#include "vboot_common.h"
/* TODO: temporary hack */
void FakePartitionAttributes(GptData* gpt);
/* Allocates and reads GPT data from the drive. The sector_bytes and /* Allocates and reads GPT data from the drive. The sector_bytes and
* drive_sectors fields should be filled on input. The primary and * drive_sectors fields should be filled on input. The primary and
@@ -28,7 +23,7 @@ int AllocAndReadGptData(GptData* gptdata);
/* Writes any changes for the GPT data back to the drive, then frees the /* Writes any changes for the GPT data back to the drive, then frees the
* buffers. */ * buffers. */
void WriteAndFreeGptData(GptData* gptdata); int WriteAndFreeGptData(GptData* gptdata);
/* Alternate LoadKernel() implementation; see load_kernel_fw.h */ /* Alternate LoadKernel() implementation; see load_kernel_fw.h */
int LoadKernel2(LoadKernelParams* params); int LoadKernel2(LoadKernelParams* params);

View File

@@ -13,6 +13,7 @@
#include "kernel_image_fw.h" #include "kernel_image_fw.h"
#include "rollback_index.h" #include "rollback_index.h"
#include "utility.h" #include "utility.h"
#include "vboot_kernel.h"
#define GPT_ENTRIES_SIZE 16384 /* Bytes to read for GPT entries */ #define GPT_ENTRIES_SIZE 16384 /* Bytes to read for GPT entries */
@@ -20,134 +21,9 @@
// TODO: for testing // TODO: for testing
#include <stdio.h> #include <stdio.h>
#include <inttypes.h> /* For PRIu64 macro */ #include <inttypes.h> /* For PRIu64 macro */
#endif
/* TODO: Remove this terrible hack which fakes partition attributes
* for the kernel partitions so that GptNextKernelEntry() won't
* choke. */
#include "cgptlib_internal.h" #include "cgptlib_internal.h"
void FakePartitionAttributes(GptData* gpt) {
GptHeader* h = (GptHeader*)gpt->primary_header;
GptEntry* entries = (GptEntry*)gpt->primary_entries;
GptEntry* e;
int i;
for (i = 0, e = entries; i < h->number_of_entries; i++, e++) {
if (!IsKernelEntry(e))
continue;
#ifdef PRINT_DEBUG_INFO
printf("%2d %08x %04x %04x %02x %02x %02x %02x %02x %02x %02x %02x",
i,
e->type.u.Uuid.time_low,
e->type.u.Uuid.time_mid,
e->type.u.Uuid.time_high_and_version,
e->type.u.Uuid.clock_seq_high_and_reserved,
e->type.u.Uuid.clock_seq_low,
e->type.u.Uuid.node[0],
e->type.u.Uuid.node[1],
e->type.u.Uuid.node[2],
e->type.u.Uuid.node[3],
e->type.u.Uuid.node[4],
e->type.u.Uuid.node[5]
);
printf(" %8" PRIu64 " %8" PRIu64"\n", e->starting_lba,
e->ending_lba - e->starting_lba + 1);
printf("Hacking attributes for kernel partition %d\n", i);
#endif #endif
SetEntryPriority(e, 2);
SetEntrySuccessful(e, 1);
}
}
/* 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(GptData* gptdata) {
uint64_t entries_sectors = GPT_ENTRIES_SIZE / gptdata->sector_bytes;
/* No data to be written yet */
gptdata->modified = 0;
/* Allocate all buffers */
gptdata->primary_header = (uint8_t*)Malloc(gptdata->sector_bytes);
gptdata->secondary_header = (uint8_t*)Malloc(gptdata->sector_bytes);
gptdata->primary_entries = (uint8_t*)Malloc(GPT_ENTRIES_SIZE);
gptdata->secondary_entries = (uint8_t*)Malloc(GPT_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 != BootDeviceReadLBA(1, 1, gptdata->primary_header))
return 1;
if (0 != BootDeviceReadLBA(2, entries_sectors, gptdata->primary_entries))
return 1;
if (0 != BootDeviceReadLBA(gptdata->drive_sectors - entries_sectors - 1,
entries_sectors, gptdata->secondary_entries))
return 1;
if (0 != BootDeviceReadLBA(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(GptData* gptdata) {
uint64_t entries_sectors = GPT_ENTRIES_SIZE / gptdata->sector_bytes;
if (gptdata->primary_header) {
if (gptdata->modified & GPT_MODIFIED_HEADER1) {
if (0 != BootDeviceWriteLBA(1, 1, gptdata->primary_header))
return 1;
}
Free(gptdata->primary_header);
}
if (gptdata->primary_entries) {
if (gptdata->modified & GPT_MODIFIED_ENTRIES1) {
if (0 != BootDeviceWriteLBA(2, entries_sectors,
gptdata->primary_entries))
return 1;
}
Free(gptdata->primary_entries);
}
if (gptdata->secondary_entries) {
if (gptdata->modified & GPT_MODIFIED_ENTRIES2) {
if (0 != BootDeviceWriteLBA(gptdata->drive_sectors - entries_sectors - 1,
entries_sectors, gptdata->secondary_entries))
return 1;
}
Free(gptdata->secondary_entries);
}
if (gptdata->secondary_header) {
if (gptdata->modified & GPT_MODIFIED_HEADER2) {
if (0 != BootDeviceWriteLBA(gptdata->drive_sectors - 1, 1,
gptdata->secondary_header))
return 1;
}
Free(gptdata->secondary_header);
}
/* Success */
return 0;
}
#define KBUF_SIZE 65536 /* Bytes to read at start of kernel partition */ #define KBUF_SIZE 65536 /* Bytes to read at start of kernel partition */
@@ -194,9 +70,6 @@ int LoadKernel(LoadKernelParams* params) {
if (GPT_SUCCESS != GptInit(&gpt)) if (GPT_SUCCESS != GptInit(&gpt))
break; break;
/* TODO: TERRIBLE KLUDGE - fake partition attributes */
FakePartitionAttributes(&gpt);
/* Allocate kernel header and image work buffers */ /* Allocate kernel header and image work buffers */
kbuf = (uint8_t*)Malloc(KBUF_SIZE); kbuf = (uint8_t*)Malloc(KBUF_SIZE);
if (!kbuf) if (!kbuf)

View File

@@ -6,21 +6,19 @@
* (Firmware portion) * (Firmware portion)
*/ */
/* TODO: change all 'return 0', 'return 1' into meaningful return codes */
#include "vboot_common.h" #include "vboot_common.h"
#include "utility.h" #include "utility.h"
#include <stdio.h> /* TODO: FOR TESTING */
char* kVbootErrors[VBOOT_ERROR_MAX] = { char* kVbootErrors[VBOOT_ERROR_MAX] = {
"Success.", "Success.",
"Invalid Image.", "Key block invalid.",
"Kernel Key Signature Failed.", "Key block signature failed.",
"Invalid Kernel Verification Algorithm.", "Key block hash failed.",
"Preamble Signature Failed.", "Public key invalid.",
"Kernel Signature Failed.", "Preamble invalid.",
"Wrong Kernel Magic.", "Preamble signature check failed.",
}; };
@@ -132,15 +130,15 @@ int KeyBlockVerify(const VbKeyBlockHeader* block, uint64_t size,
/* Sanity checks before attempting signature of data */ /* Sanity checks before attempting signature of data */
if (SafeMemcmp(block->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE)) { if (SafeMemcmp(block->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE)) {
debug("Not a valid verified boot key block.\n"); debug("Not a valid verified boot key block.\n");
return 1; return VBOOT_KEY_BLOCK_INVALID;
} }
if (block->header_version_major != KEY_BLOCK_HEADER_VERSION_MAJOR) { if (block->header_version_major != KEY_BLOCK_HEADER_VERSION_MAJOR) {
debug("Incompatible key block header version.\n"); debug("Incompatible key block header version.\n");
return 1; return VBOOT_KEY_BLOCK_INVALID;
} }
if (size < block->key_block_size) { if (size < block->key_block_size) {
debug("Not enough data for key block.\n"); debug("Not enough data for key block.\n");
return 1; return VBOOT_KEY_BLOCK_INVALID;
} }
/* Check signature or hash, depending on whether we have a key. */ /* Check signature or hash, depending on whether we have a key. */
@@ -153,18 +151,17 @@ int KeyBlockVerify(const VbKeyBlockHeader* block, uint64_t size,
if (VerifySignatureInside(block, block->key_block_size, sig)) { if (VerifySignatureInside(block, block->key_block_size, sig)) {
debug("Key block signature off end of block\n"); debug("Key block signature off end of block\n");
return 1; return VBOOT_KEY_BLOCK_INVALID;
} }
if (!((rsa = PublicKeyToRSA(key)))) { if (!((rsa = PublicKeyToRSA(key)))) {
debug("Invalid public key\n"); debug("Invalid public key\n");
return 1; return VBOOT_PUBLIC_KEY_INVALID;
} }
rv = VerifyData((const uint8_t*)block, sig, rsa); rv = VerifyData((const uint8_t*)block, sig, rsa);
RSAPublicKeyFree(rsa); RSAPublicKeyFree(rsa);
if (rv) if (rv)
return rv; return VBOOT_KEY_BLOCK_SIGNATURE;
} else { } else {
/* Check hash */ /* Check hash */
@@ -175,11 +172,11 @@ int KeyBlockVerify(const VbKeyBlockHeader* block, uint64_t size,
if (VerifySignatureInside(block, block->key_block_size, sig)) { if (VerifySignatureInside(block, block->key_block_size, sig)) {
debug("Key block hash off end of block\n"); debug("Key block hash off end of block\n");
return 1; return VBOOT_KEY_BLOCK_INVALID;
} }
if (sig->sig_size != SHA512_DIGEST_SIZE) { if (sig->sig_size != SHA512_DIGEST_SIZE) {
debug("Wrong hash size for key block.\n"); debug("Wrong hash size for key block.\n");
return 1; return VBOOT_KEY_BLOCK_INVALID;
} }
header_checksum = DigestBuf((const uint8_t*)block, sig->data_size, header_checksum = DigestBuf((const uint8_t*)block, sig->data_size,
@@ -189,28 +186,28 @@ int KeyBlockVerify(const VbKeyBlockHeader* block, uint64_t size,
Free(header_checksum); Free(header_checksum);
if (rv) { if (rv) {
debug("Invalid key block hash.\n"); debug("Invalid key block hash.\n");
return 1; return VBOOT_KEY_BLOCK_HASH;
} }
} }
/* Verify we signed enough data */ /* Verify we signed enough data */
if (sig->data_size < sizeof(VbKeyBlockHeader)) { if (sig->data_size < sizeof(VbKeyBlockHeader)) {
debug("Didn't sign enough data\n"); debug("Didn't sign enough data\n");
return 1; return VBOOT_KEY_BLOCK_INVALID;
} }
/* Verify data key is inside the block and inside signed data */ /* Verify data key is inside the block and inside signed data */
if (VerifyPublicKeyInside(block, block->key_block_size, &block->data_key)) { if (VerifyPublicKeyInside(block, block->key_block_size, &block->data_key)) {
debug("Data key off end of key block\n"); debug("Data key off end of key block\n");
return 1; return VBOOT_KEY_BLOCK_INVALID;
} }
if (VerifyPublicKeyInside(block, sig->data_size, &block->data_key)) { if (VerifyPublicKeyInside(block, sig->data_size, &block->data_key)) {
debug("Data key off end of signed data\n"); debug("Data key off end of signed data\n");
return 1; return VBOOT_KEY_BLOCK_INVALID;
} }
/* Success */ /* Success */
return 0; return VBOOT_SUCCESS;
} }
@@ -219,51 +216,49 @@ int VerifyFirmwarePreamble2(const VbFirmwarePreambleHeader* preamble,
const VbSignature* sig = &preamble->preamble_signature; const VbSignature* sig = &preamble->preamble_signature;
/* TODO: caller needs to make sure key version is valid */
/* Sanity checks before attempting signature of data */ /* Sanity checks before attempting signature of data */
if (preamble->header_version_major != if (preamble->header_version_major !=
FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR) { FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR) {
debug("Incompatible firmware preamble header version.\n"); debug("Incompatible firmware preamble header version.\n");
return 1; return VBOOT_PREAMBLE_INVALID;
} }
if (size < preamble->preamble_size) { if (size < preamble->preamble_size) {
debug("Not enough data for preamble.\n"); debug("Not enough data for preamble.\n");
return 1; return VBOOT_PREAMBLE_INVALID;
} }
/* Check signature */ /* Check signature */
if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) { if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) {
debug("Preamble signature off end of preamble\n"); debug("Preamble signature off end of preamble\n");
return 1; return VBOOT_PREAMBLE_INVALID;
} }
if (VerifyData((const uint8_t*)preamble, sig, key)) { if (VerifyData((const uint8_t*)preamble, sig, key)) {
debug("Preamble signature validation failed\n"); debug("Preamble signature validation failed\n");
return 1; return VBOOT_PREAMBLE_SIGNATURE;
} }
/* Verify we signed enough data */ /* Verify we signed enough data */
if (sig->data_size < sizeof(VbFirmwarePreambleHeader)) { if (sig->data_size < sizeof(VbFirmwarePreambleHeader)) {
debug("Didn't sign enough data\n"); debug("Didn't sign enough data\n");
return 1; return VBOOT_PREAMBLE_INVALID;
} }
/* Verify body signature is inside the block */ /* Verify body signature is inside the block */
if (VerifySignatureInside(preamble, preamble->preamble_size, if (VerifySignatureInside(preamble, preamble->preamble_size,
&preamble->body_signature)) { &preamble->body_signature)) {
debug("Firmware body signature off end of preamble\n"); debug("Firmware body signature off end of preamble\n");
return 1; return VBOOT_PREAMBLE_INVALID;
} }
/* Verify kernel subkey is inside the block */ /* Verify kernel subkey is inside the block */
if (VerifyPublicKeyInside(preamble, preamble->preamble_size, if (VerifyPublicKeyInside(preamble, preamble->preamble_size,
&preamble->kernel_subkey)) { &preamble->kernel_subkey)) {
debug("Kernel subkey off end of preamble\n"); debug("Kernel subkey off end of preamble\n");
return 1; return VBOOT_PREAMBLE_INVALID;
} }
/* Success */ /* Success */
return 0; return VBOOT_SUCCESS;
} }
@@ -272,41 +267,39 @@ int VerifyKernelPreamble2(const VbKernelPreambleHeader* preamble,
const VbSignature* sig = &preamble->preamble_signature; const VbSignature* sig = &preamble->preamble_signature;
/* TODO: caller needs to make sure key version is valid */
/* Sanity checks before attempting signature of data */ /* Sanity checks before attempting signature of data */
if (preamble->header_version_major != KERNEL_PREAMBLE_HEADER_VERSION_MAJOR) { if (preamble->header_version_major != KERNEL_PREAMBLE_HEADER_VERSION_MAJOR) {
debug("Incompatible kernel preamble header version.\n"); debug("Incompatible kernel preamble header version.\n");
return 1; return VBOOT_PREAMBLE_INVALID;
} }
if (size < preamble->preamble_size) { if (size < preamble->preamble_size) {
debug("Not enough data for preamble.\n"); debug("Not enough data for preamble.\n");
return 1; return VBOOT_PREAMBLE_INVALID;
} }
/* Check signature */ /* Check signature */
if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) { if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) {
debug("Preamble signature off end of preamble\n"); debug("Preamble signature off end of preamble\n");
return 1; return VBOOT_PREAMBLE_INVALID;
} }
if (VerifyData((const uint8_t*)preamble, sig, key)) { if (VerifyData((const uint8_t*)preamble, sig, key)) {
debug("Preamble signature validation failed\n"); debug("Preamble signature validation failed\n");
return 1; return VBOOT_PREAMBLE_SIGNATURE;
} }
/* Verify we signed enough data */ /* Verify we signed enough data */
if (sig->data_size < sizeof(VbKernelPreambleHeader)) { if (sig->data_size < sizeof(VbKernelPreambleHeader)) {
debug("Didn't sign enough data\n"); debug("Didn't sign enough data\n");
return 1; return VBOOT_PREAMBLE_INVALID;
} }
/* Verify body signature is inside the block */ /* Verify body signature is inside the block */
if (VerifySignatureInside(preamble, preamble->preamble_size, if (VerifySignatureInside(preamble, preamble->preamble_size,
&preamble->body_signature)) { &preamble->body_signature)) {
debug("Kernel body signature off end of preamble\n"); debug("Kernel body signature off end of preamble\n");
return 1; return VBOOT_PREAMBLE_INVALID;
} }
/* Success */ /* Success */
return 0; return VBOOT_SUCCESS;
} }

View File

@@ -13,9 +13,98 @@
#include "load_kernel_fw.h" #include "load_kernel_fw.h"
#include "rollback_index.h" #include "rollback_index.h"
#include "utility.h" #include "utility.h"
#include "vboot_common.h"
#define KBUF_SIZE 65536 /* Bytes to read at start of kernel partition */ #define KBUF_SIZE 65536 /* Bytes to read at start of kernel partition */
/* 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(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*)Malloc(gptdata->sector_bytes);
gptdata->secondary_header = (uint8_t*)Malloc(gptdata->sector_bytes);
gptdata->primary_entries = (uint8_t*)Malloc(TOTAL_ENTRIES_SIZE);
gptdata->secondary_entries = (uint8_t*)Malloc(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 != BootDeviceReadLBA(1, 1, gptdata->primary_header))
return 1;
if (0 != BootDeviceReadLBA(2, entries_sectors, gptdata->primary_entries))
return 1;
if (0 != BootDeviceReadLBA(gptdata->drive_sectors - entries_sectors - 1,
entries_sectors, gptdata->secondary_entries))
return 1;
if (0 != BootDeviceReadLBA(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(GptData* gptdata) {
uint64_t entries_sectors = TOTAL_ENTRIES_SIZE / gptdata->sector_bytes;
if (gptdata->primary_header) {
if (gptdata->modified & GPT_MODIFIED_HEADER1) {
if (0 != BootDeviceWriteLBA(1, 1, gptdata->primary_header))
return 1;
}
Free(gptdata->primary_header);
}
if (gptdata->primary_entries) {
if (gptdata->modified & GPT_MODIFIED_ENTRIES1) {
if (0 != BootDeviceWriteLBA(2, entries_sectors,
gptdata->primary_entries))
return 1;
}
Free(gptdata->primary_entries);
}
if (gptdata->secondary_entries) {
if (gptdata->modified & GPT_MODIFIED_ENTRIES2) {
if (0 != BootDeviceWriteLBA(gptdata->drive_sectors - entries_sectors - 1,
entries_sectors, gptdata->secondary_entries))
return 1;
}
Free(gptdata->secondary_entries);
}
if (gptdata->secondary_header) {
if (gptdata->modified & GPT_MODIFIED_HEADER2) {
if (0 != BootDeviceWriteLBA(gptdata->drive_sectors - 1, 1,
gptdata->secondary_header))
return 1;
}
Free(gptdata->secondary_header);
}
/* Success */
return 0;
}
int LoadKernel2(LoadKernelParams* params) { int LoadKernel2(LoadKernelParams* params) {
VbPublicKey* kernel_subkey = (VbPublicKey*)params->header_sign_key_blob; VbPublicKey* kernel_subkey = (VbPublicKey*)params->header_sign_key_blob;
@@ -65,9 +154,6 @@ int LoadKernel2(LoadKernelParams* params) {
if (GPT_SUCCESS != GptInit(&gpt)) if (GPT_SUCCESS != GptInit(&gpt))
break; break;
/* TODO: TERRIBLE KLUDGE - fake partition attributes */
FakePartitionAttributes(&gpt);
/* Allocate kernel header buffers */ /* Allocate kernel header buffers */
kbuf = (uint8_t*)Malloc(KBUF_SIZE); kbuf = (uint8_t*)Malloc(KBUF_SIZE);
if (!kbuf) if (!kbuf)