123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- /* 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.
- *
- * Host functions for verified boot.
- */
- #include <stdio.h>
- #include "2sysincludes.h"
- #include "2api.h"
- #include "2common.h"
- #include "2rsa.h"
- #include "2sha.h"
- #include "host_common.h"
- #include "host_key.h"
- #include "host_key2.h"
- #include "host_keyblock.h"
- #include "vb2_common.h"
- #include "vb2_struct.h"
- #include "vboot_common.h"
- struct vb2_keyblock *vb2_create_keyblock(
- const struct vb2_packed_key *data_key,
- const struct vb2_private_key *signing_key,
- uint32_t flags)
- {
- /* Allocate key block */
- uint32_t signed_size = sizeof(struct vb2_keyblock) + data_key->key_size;
- uint32_t sig_data_size =
- (signing_key ? vb2_rsa_sig_size(signing_key->sig_alg) : 0);
- uint32_t block_size =
- signed_size + VB2_SHA512_DIGEST_SIZE + sig_data_size;
- struct vb2_keyblock *h = (struct vb2_keyblock *)calloc(block_size, 1);
- if (!h)
- return NULL;
- uint8_t *data_key_dest = (uint8_t *)(h + 1);
- uint8_t *block_chk_dest = data_key_dest + data_key->key_size;
- uint8_t *block_sig_dest = block_chk_dest + VB2_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->keyblock_size = block_size;
- h->keyblock_flags = flags;
- /* Copy data key */
- vb2_init_packed_key(&h->data_key, data_key_dest, data_key->key_size);
- vb2_copy_packed_key(&h->data_key, data_key);
- /* Set up signature structs so we can calculate the signatures */
- vb2_init_signature(&h->keyblock_hash, block_chk_dest,
- VB2_SHA512_DIGEST_SIZE, signed_size);
- if (signing_key) {
- vb2_init_signature(&h->keyblock_signature, block_sig_dest,
- sig_data_size, signed_size);
- } else {
- memset(&h->keyblock_signature, 0,
- sizeof(h->keyblock_signature));
- }
- /* Calculate hash */
- struct vb2_signature *chk =
- vb2_sha512_signature((uint8_t*)h, signed_size);
- vb2_copy_signature(&h->keyblock_hash, chk);
- free(chk);
- /* Calculate signature */
- if (signing_key) {
- struct vb2_signature *sigtmp =
- vb2_calculate_signature((uint8_t*)h,
- signed_size,
- signing_key);
- vb2_copy_signature(&h->keyblock_signature, sigtmp);
- free(sigtmp);
- }
- /* Return the header */
- return h;
- }
- /* TODO(gauravsh): This could easily be integrated into the function above
- * since the code is almost a mirror - I have kept it as such to avoid changing
- * the existing interface. */
- struct vb2_keyblock *vb2_create_keyblock_external(
- const struct vb2_packed_key *data_key,
- const char *signing_key_pem_file,
- uint32_t algorithm,
- uint32_t flags,
- const char *external_signer)
- {
- if (!signing_key_pem_file || !data_key || !external_signer)
- return NULL;
- uint32_t signed_size = sizeof(struct vb2_keyblock) + data_key->key_size;
- uint32_t sig_data_size = vb2_rsa_sig_size(algorithm);
- uint32_t block_size =
- signed_size + VB2_SHA512_DIGEST_SIZE + sig_data_size;
- /* Allocate key block */
- struct vb2_keyblock *h = (struct vb2_keyblock *)calloc(block_size, 1);
- if (!h)
- return NULL;
- uint8_t *data_key_dest = (uint8_t *)(h + 1);
- uint8_t *block_chk_dest = data_key_dest + data_key->key_size;
- uint8_t *block_sig_dest = block_chk_dest + VB2_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->keyblock_size = block_size;
- h->keyblock_flags = flags;
- /* Copy data key */
- vb2_init_packed_key(&h->data_key, data_key_dest, data_key->key_size);
- vb2_copy_packed_key(&h->data_key, data_key);
- /* Set up signature structs so we can calculate the signatures */
- vb2_init_signature(&h->keyblock_hash, block_chk_dest,
- VB2_SHA512_DIGEST_SIZE, signed_size);
- vb2_init_signature(&h->keyblock_signature, block_sig_dest,
- sig_data_size, signed_size);
- /* Calculate checksum */
- struct vb2_signature *chk =
- vb2_sha512_signature((uint8_t*)h, signed_size);
- vb2_copy_signature(&h->keyblock_hash, chk);
- free(chk);
- /* Calculate signature */
- struct vb2_signature *sigtmp =
- vb2_external_signature((uint8_t*)h, signed_size,
- signing_key_pem_file, algorithm,
- external_signer);
- free(sigtmp);
- /* Return the header */
- return h;
- }
- struct vb2_keyblock *vb2_read_keyblock(const char *filename)
- {
- uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE];
- struct vb2_workbuf wb;
- vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
- struct vb2_keyblock *block;
- uint32_t file_size;
- if (VB2_SUCCESS !=
- vb2_read_file(filename, (uint8_t **)&block, &file_size)) {
- fprintf(stderr, "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 (VB2_SUCCESS != vb2_verify_keyblock_hash(block, file_size, &wb)) {
- fprintf(stderr, "Invalid key block file: %s\n", filename);
- free(block);
- return NULL;
- }
- return block;
- }
- int vb2_write_keyblock(const char *filename,
- const struct vb2_keyblock *keyblock)
- {
- return vb2_write_file(filename, keyblock, keyblock->keyblock_size);
- }
|