diff options
author | Randall Spangler <rspangler@chromium.org> | 2010-06-11 11:16:20 -0700 |
---|---|---|
committer | Randall Spangler <rspangler@chromium.org> | 2010-06-11 11:16:20 -0700 |
commit | 729b87258b5dd499ce3c910499c010d3840628df (patch) | |
tree | 8945cb5f12badf7bd7663dd9a7d94faf3769a53a | |
parent | 7d6898dbaa8d530dd534d4680e274f7059e4a389 (diff) | |
download | vboot-729b87258b5dd499ce3c910499c010d3840628df.tar.gz |
Clean up of key block functions
No substantial new code, just making the old code consistent.
Review URL: http://codereview.chromium.org/2729021
-rw-r--r-- | host/Makefile | 1 | ||||
-rw-r--r-- | host/include/host_common.h | 9 | ||||
-rw-r--r-- | host/include/host_keyblock.h | 35 | ||||
-rw-r--r-- | host/lib/host_common.c | 52 | ||||
-rw-r--r-- | host/lib/host_keyblock.c | 106 | ||||
-rw-r--r-- | host/linktest/main.c | 6 | ||||
-rw-r--r-- | tests/vboot_common3_tests.c | 62 | ||||
-rw-r--r-- | utility/vbutil_kernel.c | 2 | ||||
-rw-r--r-- | utility/vbutil_keyblock.c | 14 | ||||
-rw-r--r-- | vboot_firmware/lib/include/vboot_common.h | 2 | ||||
-rw-r--r-- | vboot_firmware/lib/vboot_common.c | 2 | ||||
-rw-r--r-- | vboot_firmware/lib/vboot_firmware.c | 2 | ||||
-rw-r--r-- | vboot_firmware/lib/vboot_kernel.c | 2 | ||||
-rw-r--r-- | vboot_firmware/linktest/main.c | 2 |
14 files changed, 194 insertions, 103 deletions
diff --git a/host/Makefile b/host/Makefile index fd3e77e7..f0bdf855 100644 --- a/host/Makefile +++ b/host/Makefile @@ -21,6 +21,7 @@ INCLUDES += \ LIB_SRCS = \ ./lib/host_common.c \ ./lib/host_key.c \ + ./lib/host_keyblock.c \ ./lib/host_misc.c \ ./lib/host_signature.c diff --git a/host/include/host_common.h b/host/include/host_common.h index ad71ab52..056fbc42 100644 --- a/host/include/host_common.h +++ b/host/include/host_common.h @@ -12,20 +12,13 @@ #include "cryptolib.h" #include "host_key.h" +#include "host_keyblock.h" #include "host_misc.h" #include "host_signature.h" #include "utility.h" #include "vboot_struct.h" -/* Create a key block header containing [data_key] and [flags], signed - * by [signing_key]. Caller owns the returned pointer, and must free - * it with Free(). */ -VbKeyBlockHeader* CreateKeyBlock(const VbPublicKey* data_key, - const VbPrivateKey* signing_key, - uint64_t flags); - - /* Creates a firmware preamble, signed with [signing_key]. * Caller owns the returned pointer, and must free it with Free(). * diff --git a/host/include/host_keyblock.h b/host/include/host_keyblock.h new file mode 100644 index 00000000..02281436 --- /dev/null +++ b/host/include/host_keyblock.h @@ -0,0 +1,35 @@ +/* Copyright (c) 2010 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. + * + * Host-side functions for verified boot. + */ + +#ifndef VBOOT_REFERENCE_HOST_KEYBLOCK_H_ +#define VBOOT_REFERENCE_HOST_KEYBLOCK_H_ + +#include <stdint.h> + +#include "host_key.h" +#include "vboot_struct.h" + + +/* Create a key block header containing [data_key] and [flags], signed + * by [signing_key]. Caller owns the returned pointer, and must free + * it with Free(). */ +VbKeyBlockHeader* KeyBlockCreate(const VbPublicKey* data_key, + const VbPrivateKey* signing_key, + uint64_t flags); + + +/* Read a key block from a .keyblock file. Caller owns the returned + * pointer, and must free it with Free(). + * + * Returns NULL if error. */ +VbKeyBlockHeader* KeyBlockRead(const char* filename); + + +/* Write a key block to a file in .keyblock format. */ +int KeyBlockWrite(const char* filename, const VbKeyBlockHeader* key_block); + +#endif /* VBOOT_REFERENCE_HOST_KEYBLOCK_H_ */ diff --git a/host/lib/host_common.c b/host/lib/host_common.c index 03efd2a4..3d0a23db 100644 --- a/host/lib/host_common.c +++ b/host/lib/host_common.c @@ -14,58 +14,6 @@ #include "vboot_common.h" -VbKeyBlockHeader* CreateKeyBlock(const VbPublicKey* data_key, - const VbPrivateKey* signing_key, - uint64_t flags) { - - VbKeyBlockHeader* h; - uint64_t signed_size = sizeof(VbKeyBlockHeader) + data_key->key_size; - uint64_t block_size = (signed_size + SHA512_DIGEST_SIZE + - siglen_map[signing_key->algorithm]); - uint8_t* data_key_dest; - uint8_t* block_sig_dest; - uint8_t* block_chk_dest; - VbSignature *sigtmp; - - /* Allocate key block */ - h = (VbKeyBlockHeader*)Malloc(block_size); - if (!h) - return NULL; - data_key_dest = (uint8_t*)(h + 1); - block_chk_dest = data_key_dest + data_key->key_size; - block_sig_dest = block_chk_dest + SHA512_DIGEST_SIZE; - - Memcpy(h->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE); - h->header_version_major = KEY_BLOCK_HEADER_VERSION_MAJOR; - h->header_version_minor = KEY_BLOCK_HEADER_VERSION_MINOR; - h->key_block_size = block_size; - h->key_block_flags = flags; - - /* Copy data key */ - PublicKeyInit(&h->data_key, data_key_dest, data_key->key_size); - PublicKeyCopy(&h->data_key, data_key); - - /* Set up signature structs so we can calculate the signatures */ - SignatureInit(&h->key_block_checksum, block_chk_dest, - SHA512_DIGEST_SIZE, signed_size); - SignatureInit(&h->key_block_signature, block_sig_dest, - siglen_map[signing_key->algorithm], signed_size); - - /* Calculate checksum */ - sigtmp = CalculateChecksum((uint8_t*)h, signed_size); - SignatureCopy(&h->key_block_checksum, sigtmp); - Free(sigtmp); - - /* Calculate signature */ - sigtmp = CalculateSignature((uint8_t*)h, signed_size, signing_key); - SignatureCopy(&h->key_block_signature, sigtmp); - Free(sigtmp); - - /* Return the header */ - return h; -} - - VbFirmwarePreambleHeader* CreateFirmwarePreamble( uint64_t firmware_version, const VbPublicKey* kernel_subkey, diff --git a/host/lib/host_keyblock.c b/host/lib/host_keyblock.c new file mode 100644 index 00000000..af59059f --- /dev/null +++ b/host/lib/host_keyblock.c @@ -0,0 +1,106 @@ +/* Copyright (c) 2010 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. + * + * Host functions for verified boot. + */ + +/* TODO: change all 'return 0', 'return 1' into meaningful return codes */ + +#include "host_keyblock.h" + +#include "cryptolib.h" +#include "host_common.h" +#include "utility.h" +#include "vboot_common.h" + + +VbKeyBlockHeader* KeyBlockCreate(const VbPublicKey* data_key, + const VbPrivateKey* signing_key, + uint64_t flags) { + + VbKeyBlockHeader* h; + uint64_t signed_size = sizeof(VbKeyBlockHeader) + data_key->key_size; + uint64_t block_size = (signed_size + SHA512_DIGEST_SIZE + + siglen_map[signing_key->algorithm]); + uint8_t* data_key_dest; + uint8_t* block_sig_dest; + uint8_t* block_chk_dest; + VbSignature *sigtmp; + + /* Allocate key block */ + h = (VbKeyBlockHeader*)Malloc(block_size); + if (!h) + return NULL; + data_key_dest = (uint8_t*)(h + 1); + block_chk_dest = data_key_dest + data_key->key_size; + block_sig_dest = block_chk_dest + SHA512_DIGEST_SIZE; + + Memcpy(h->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE); + h->header_version_major = KEY_BLOCK_HEADER_VERSION_MAJOR; + h->header_version_minor = KEY_BLOCK_HEADER_VERSION_MINOR; + h->key_block_size = block_size; + h->key_block_flags = flags; + + /* Copy data key */ + PublicKeyInit(&h->data_key, data_key_dest, data_key->key_size); + PublicKeyCopy(&h->data_key, data_key); + + /* Set up signature structs so we can calculate the signatures */ + SignatureInit(&h->key_block_checksum, block_chk_dest, + SHA512_DIGEST_SIZE, signed_size); + SignatureInit(&h->key_block_signature, block_sig_dest, + siglen_map[signing_key->algorithm], signed_size); + + /* Calculate checksum */ + sigtmp = CalculateChecksum((uint8_t*)h, signed_size); + SignatureCopy(&h->key_block_checksum, sigtmp); + Free(sigtmp); + + /* Calculate signature */ + sigtmp = CalculateSignature((uint8_t*)h, signed_size, signing_key); + SignatureCopy(&h->key_block_signature, sigtmp); + Free(sigtmp); + + /* Return the header */ + return h; +} + + +/* Read a key block from a .keyblock file. Caller owns the returned + * pointer, and must free it with Free(). + * + * Returns NULL if error. */ +VbKeyBlockHeader* KeyBlockRead(const char* filename) { + + VbKeyBlockHeader* block; + uint64_t file_size; + + block = (VbKeyBlockHeader*)ReadFile(filename, &file_size); + if (!block) { + debug("Error reading key block file: %s\n", filename); + return NULL; + } + + /* Verify the hash of the key block, since we can do that without + * the public signing key. */ + if (0 != KeyBlockVerify(block, file_size, NULL)) { + debug("Invalid key block file: filename\n", filename); + Free(block); + return NULL; + } + + return block; +} + + +/* Write a key block to a file in .keyblock format. */ +int KeyBlockWrite(const char* filename, const VbKeyBlockHeader* key_block) { + + if (0 != WriteFile(filename, key_block, key_block->key_block_size)) { + debug("KeyBlockWrite() error writing key block\n"); + return 1; + } + + return 0; +} diff --git a/host/linktest/main.c b/host/linktest/main.c index f1030ce7..b8db1211 100644 --- a/host/linktest/main.c +++ b/host/linktest/main.c @@ -14,6 +14,11 @@ int main(void) PublicKeyReadKeyb(0, 0, 0); PublicKeyWrite(0, 0); + /* host_keyblock.h */ + KeyBlockCreate(0, 0, 0); + KeyBlockRead(0); + KeyBlockWrite(0, 0); + /* host_misc.h */ ReadFile(0, 0); WriteFile(0, 0, 0); @@ -26,7 +31,6 @@ int main(void) CalculateSignature(0, 0, 0); /* host_common.h */ - CreateKeyBlock(0, 0, 0); CreateFirmwarePreamble(0, 0, 0, 0); CreateKernelPreamble(0, 0, 0, 0, 0, 0, 0); diff --git a/tests/vboot_common3_tests.c b/tests/vboot_common3_tests.c index 1cfdd519..f3ac92a7 100644 --- a/tests/vboot_common3_tests.c +++ b/tests/vboot_common3_tests.c @@ -26,7 +26,7 @@ static void ReChecksumKeyBlock(VbKeyBlockHeader *h) { } -static void VerifyKeyBlockTest(const VbPublicKey* public_key, +static void KeyBlockVerifyTest(const VbPublicKey* public_key, const VbPrivateKey* private_key, const VbPublicKey* data_key) { @@ -34,81 +34,81 @@ static void VerifyKeyBlockTest(const VbPublicKey* public_key, VbKeyBlockHeader *h; uint64_t hsize; - hdr = CreateKeyBlock(data_key, private_key, 0x1234); - TEST_NEQ((size_t)hdr, 0, "VerifyKeyBlock() prerequisites"); + hdr = KeyBlockCreate(data_key, private_key, 0x1234); + TEST_NEQ((size_t)hdr, 0, "KeyBlockVerify() prerequisites"); if (!hdr) return; hsize = hdr->key_block_size; h = (VbKeyBlockHeader*)Malloc(hsize + 1024); - TEST_EQ(VerifyKeyBlock(hdr, hsize, NULL), 0, - "VerifyKeyBlock() ok using checksum"); - TEST_EQ(VerifyKeyBlock(hdr, hsize, public_key), 0, - "VerifyKeyBlock() ok using key"); + TEST_EQ(KeyBlockVerify(hdr, hsize, NULL), 0, + "KeyBlockVerify() ok using checksum"); + TEST_EQ(KeyBlockVerify(hdr, hsize, public_key), 0, + "KeyBlockVerify() ok using key"); - TEST_NEQ(VerifyKeyBlock(hdr, hsize - 1, NULL), 0, "VerifyKeyBlock() size--"); - TEST_EQ(VerifyKeyBlock(hdr, hsize + 1, NULL), 0, "VerifyKeyBlock() size++"); + TEST_NEQ(KeyBlockVerify(hdr, hsize - 1, NULL), 0, "KeyBlockVerify() size--"); + TEST_EQ(KeyBlockVerify(hdr, hsize + 1, NULL), 0, "KeyBlockVerify() size++"); Memcpy(h, hdr, hsize); h->magic[0] &= 0x12; - TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, "VerifyKeyBlock() magic"); + TEST_NEQ(KeyBlockVerify(h, hsize, NULL), 0, "KeyBlockVerify() magic"); /* Care about major version but not minor */ Memcpy(h, hdr, hsize); h->header_version_major++; ReChecksumKeyBlock(h); - TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, "VerifyKeyBlock() major++"); + TEST_NEQ(KeyBlockVerify(h, hsize, NULL), 0, "KeyBlockVerify() major++"); Memcpy(h, hdr, hsize); h->header_version_major--; ReChecksumKeyBlock(h); - TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, "VerifyKeyBlock() major--"); + TEST_NEQ(KeyBlockVerify(h, hsize, NULL), 0, "KeyBlockVerify() major--"); Memcpy(h, hdr, hsize); h->header_version_minor++; ReChecksumKeyBlock(h); - TEST_EQ(VerifyKeyBlock(h, hsize, NULL), 0, "VerifyKeyBlock() minor++"); + TEST_EQ(KeyBlockVerify(h, hsize, NULL), 0, "KeyBlockVerify() minor++"); Memcpy(h, hdr, hsize); h->header_version_minor--; ReChecksumKeyBlock(h); - TEST_EQ(VerifyKeyBlock(h, hsize, NULL), 0, "VerifyKeyBlock() minor--"); + TEST_EQ(KeyBlockVerify(h, hsize, NULL), 0, "KeyBlockVerify() minor--"); /* Check hash */ Memcpy(h, hdr, hsize); h->key_block_checksum.sig_offset = hsize; ReChecksumKeyBlock(h); - TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, - "VerifyKeyBlock() checksum off end"); + TEST_NEQ(KeyBlockVerify(h, hsize, NULL), 0, + "KeyBlockVerify() checksum off end"); Memcpy(h, hdr, hsize); h->key_block_checksum.sig_size /= 2; ReChecksumKeyBlock(h); - TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, - "VerifyKeyBlock() checksum too small"); + TEST_NEQ(KeyBlockVerify(h, hsize, NULL), 0, + "KeyBlockVerify() checksum too small"); Memcpy(h, hdr, hsize); GetPublicKeyData(&h->data_key)[0] ^= 0x34; - TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, - "VerifyKeyBlock() checksum mismatch"); + TEST_NEQ(KeyBlockVerify(h, hsize, NULL), 0, + "KeyBlockVerify() checksum mismatch"); /* Check signature */ Memcpy(h, hdr, hsize); h->key_block_signature.sig_offset = hsize; ReChecksumKeyBlock(h); - TEST_NEQ(VerifyKeyBlock(h, hsize, public_key), 0, - "VerifyKeyBlock() sig off end"); + TEST_NEQ(KeyBlockVerify(h, hsize, public_key), 0, + "KeyBlockVerify() sig off end"); Memcpy(h, hdr, hsize); h->key_block_signature.sig_size--; ReChecksumKeyBlock(h); - TEST_NEQ(VerifyKeyBlock(h, hsize, public_key), 0, - "VerifyKeyBlock() sig too small"); + TEST_NEQ(KeyBlockVerify(h, hsize, public_key), 0, + "KeyBlockVerify() sig too small"); Memcpy(h, hdr, hsize); GetPublicKeyData(&h->data_key)[0] ^= 0x34; - TEST_NEQ(VerifyKeyBlock(h, hsize, public_key), 0, - "VerifyKeyBlock() sig mismatch"); + TEST_NEQ(KeyBlockVerify(h, hsize, public_key), 0, + "KeyBlockVerify() sig mismatch"); /* Check that we signed header and data key */ Memcpy(h, hdr, hsize); @@ -116,14 +116,14 @@ static void VerifyKeyBlockTest(const VbPublicKey* public_key, h->data_key.key_offset = 0; h->data_key.key_size = 0; ReChecksumKeyBlock(h); - TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, - "VerifyKeyBlock() didn't sign header"); + TEST_NEQ(KeyBlockVerify(h, hsize, NULL), 0, + "KeyBlockVerify() didn't sign header"); Memcpy(h, hdr, hsize); h->data_key.key_offset = hsize; ReChecksumKeyBlock(h); - TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, - "VerifyKeyBlock() data key off end"); + TEST_NEQ(KeyBlockVerify(h, hsize, NULL), 0, + "KeyBlockVerify() data key off end"); /* TODO: verify parser can support a bigger header (i.e., one where * data_key.key_offset is bigger than expected). */ @@ -283,7 +283,7 @@ int main(int argc, char* argv[]) { return 1; } - VerifyKeyBlockTest(signing_public_key, signing_private_key, data_public_key); + KeyBlockVerifyTest(signing_public_key, signing_private_key, data_public_key); VerifyFirmwarePreambleTest(signing_public_key, signing_private_key, data_public_key); diff --git a/utility/vbutil_kernel.c b/utility/vbutil_kernel.c index 32f844c6..a9f7be4c 100644 --- a/utility/vbutil_kernel.c +++ b/utility/vbutil_kernel.c @@ -326,7 +326,7 @@ static int Verify(const char* infile, const char* signpubkey) { /* Verify key block */ key_block = (VbKeyBlockHeader*)blob; - if (0 != VerifyKeyBlock(key_block, blob_size, sign_key)) { + if (0 != KeyBlockVerify(key_block, blob_size, sign_key)) { error("Error verifying key block.\n"); return 1; } diff --git a/utility/vbutil_keyblock.c b/utility/vbutil_keyblock.c index 860a07ce..43c5f061 100644 --- a/utility/vbutil_keyblock.c +++ b/utility/vbutil_keyblock.c @@ -99,11 +99,11 @@ static int Pack(const char* outfile, const char* datapubkey, return 1; } - block = CreateKeyBlock(data_key, signing_key, flags); + block = KeyBlockCreate(data_key, signing_key, flags); Free(data_key); Free(signing_key); - if (0 != WriteFile(outfile, block, block->key_block_size)) { + if (0 != KeyBlockWrite(outfile, block)) { fprintf(stderr, "vbutil_keyblock: Error writing key block.\n"); return 1; } @@ -117,7 +117,6 @@ static int Unpack(const char* infile, const char* datapubkey, VbPublicKey* data_key; VbPublicKey* sign_key; VbKeyBlockHeader* block; - uint64_t block_size; if (!infile || !signpubkey) { fprintf(stderr, "vbutil_keyblock: Must specify filename and signpubkey\n"); @@ -130,12 +129,17 @@ static int Unpack(const char* infile, const char* datapubkey, return 1; } - block = (VbKeyBlockHeader*)ReadFile(infile, &block_size); + block = KeyBlockRead(infile); if (!block) { fprintf(stderr, "vbutil_keyblock: Error reading key block.\n"); return 1; } - if (0 != VerifyKeyBlock(block, block_size, sign_key)) { + /* Verify the block with the signing public key, since + * KeyBlockRead() only verified the hash. */ + /* TODO: should just print a warning, since self-signed key blocks + * won't have a public key; signpubkey should also be an optional + * argument. */ + if (0 != KeyBlockVerify(block, block->key_block_size, sign_key)) { fprintf(stderr, "vbutil_keyblock: Error verifying key block.\n"); return 1; } diff --git a/vboot_firmware/lib/include/vboot_common.h b/vboot_firmware/lib/include/vboot_common.h index b1d15c00..41c6500b 100644 --- a/vboot_firmware/lib/include/vboot_common.h +++ b/vboot_firmware/lib/include/vboot_common.h @@ -67,7 +67,7 @@ int VerifyData(const uint8_t* data, const VbSignature* sig, * key [key]. If [key]==NULL, uses only the block checksum to verify * the key block. Header fields are also checked for sanity. Does not * verify key index or key block flags. */ -int VerifyKeyBlock(const VbKeyBlockHeader* block, uint64_t size, +int KeyBlockVerify(const VbKeyBlockHeader* block, uint64_t size, const VbPublicKey *key); diff --git a/vboot_firmware/lib/vboot_common.c b/vboot_firmware/lib/vboot_common.c index df3068ad..fb643bdc 100644 --- a/vboot_firmware/lib/vboot_common.c +++ b/vboot_firmware/lib/vboot_common.c @@ -124,7 +124,7 @@ int VerifyData(const uint8_t* data, const VbSignature *sig, } -int VerifyKeyBlock(const VbKeyBlockHeader* block, uint64_t size, +int KeyBlockVerify(const VbKeyBlockHeader* block, uint64_t size, const VbPublicKey *key) { const VbSignature* sig; diff --git a/vboot_firmware/lib/vboot_firmware.c b/vboot_firmware/lib/vboot_firmware.c index 9220550c..bcfc814d 100644 --- a/vboot_firmware/lib/vboot_firmware.c +++ b/vboot_firmware/lib/vboot_firmware.c @@ -64,7 +64,7 @@ int LoadFirmware2(LoadFirmwareParams* params) { key_block = (VbKeyBlockHeader*)params->verification_block_1; vblock_size = params->verification_size_1; } - if ((0 != VerifyKeyBlock(key_block, vblock_size, root_key))) + if ((0 != KeyBlockVerify(key_block, vblock_size, root_key))) continue; /* Check for rollback of key version. */ diff --git a/vboot_firmware/lib/vboot_kernel.c b/vboot_firmware/lib/vboot_kernel.c index bcf9e171..ca8ba99c 100644 --- a/vboot_firmware/lib/vboot_kernel.c +++ b/vboot_firmware/lib/vboot_kernel.c @@ -92,7 +92,7 @@ int LoadKernel2(LoadKernelParams* params) { /* Verify the key block */ key_block = (VbKeyBlockHeader*)kbuf; - if ((0 != VerifyKeyBlock(key_block, KBUF_SIZE, kernel_subkey))) + if ((0 != KeyBlockVerify(key_block, KBUF_SIZE, kernel_subkey))) continue; /* Check the key block flags against the current boot mode */ diff --git a/vboot_firmware/linktest/main.c b/vboot_firmware/linktest/main.c index 99cdccdd..a3bbbd21 100644 --- a/vboot_firmware/linktest/main.c +++ b/vboot_firmware/linktest/main.c @@ -79,7 +79,7 @@ int main(void) VerifySignatureInside(0, 0, 0); PublicKeyToRSA(0); VerifyData(0, 0, 0); - VerifyKeyBlock(0, 0, 0); + KeyBlockVerify(0, 0, 0); VerifyFirmwarePreamble2(0, 0, 0); VerifyKernelPreamble2(0, 0, 0); |