Home | History | Annotate | Download | only in lib
      1 /* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
      2  * Use of this source code is governed by a BSD-style license that can be
      3  * found in the LICENSE file.
      4  *
      5  * Host functions for verified boot.
      6  */
      7 
      8 
      9 #include "cryptolib.h"
     10 #include "host_common.h"
     11 #include "host_keyblock.h"
     12 #include "vboot_common.h"
     13 
     14 
     15 VbKeyBlockHeader* KeyBlockCreate(const VbPublicKey* data_key,
     16                                  const VbPrivateKey* signing_key,
     17                                  uint64_t flags) {
     18 
     19   VbKeyBlockHeader* h;
     20   uint64_t signed_size = sizeof(VbKeyBlockHeader) + data_key->key_size;
     21   uint64_t block_size = (signed_size + SHA512_DIGEST_SIZE +
     22                          (signing_key ?
     23                           siglen_map[signing_key->algorithm] : 0));
     24   uint8_t* data_key_dest;
     25   uint8_t* block_sig_dest;
     26   uint8_t* block_chk_dest;
     27   VbSignature *sigtmp;
     28 
     29   /* Allocate key block */
     30   h = (VbKeyBlockHeader*)malloc(block_size);
     31   if (!h)
     32     return NULL;
     33   data_key_dest = (uint8_t*)(h + 1);
     34   block_chk_dest = data_key_dest + data_key->key_size;
     35   block_sig_dest = block_chk_dest + SHA512_DIGEST_SIZE;
     36 
     37   Memcpy(h->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE);
     38   h->header_version_major = KEY_BLOCK_HEADER_VERSION_MAJOR;
     39   h->header_version_minor = KEY_BLOCK_HEADER_VERSION_MINOR;
     40   h->key_block_size = block_size;
     41   h->key_block_flags = flags;
     42 
     43   /* Copy data key */
     44   PublicKeyInit(&h->data_key, data_key_dest, data_key->key_size);
     45   PublicKeyCopy(&h->data_key, data_key);
     46 
     47   /* Set up signature structs so we can calculate the signatures */
     48   SignatureInit(&h->key_block_checksum, block_chk_dest,
     49                 SHA512_DIGEST_SIZE, signed_size);
     50   if (signing_key)
     51     SignatureInit(&h->key_block_signature, block_sig_dest,
     52                   siglen_map[signing_key->algorithm], signed_size);
     53   else
     54     Memset(&h->key_block_signature, 0, sizeof(VbSignature));
     55 
     56   /* Calculate checksum */
     57   sigtmp = CalculateChecksum((uint8_t*)h, signed_size);
     58   SignatureCopy(&h->key_block_checksum, sigtmp);
     59   free(sigtmp);
     60 
     61   /* Calculate signature */
     62   if (signing_key) {
     63     sigtmp = CalculateSignature((uint8_t*)h, signed_size, signing_key);
     64     SignatureCopy(&h->key_block_signature, sigtmp);
     65     free(sigtmp);
     66   }
     67 
     68   /* Return the header */
     69   return h;
     70 }
     71 
     72 /* TODO(gauravsh): This could easily be integrated into KeyBlockCreate()
     73  * since the code is almost a mirror - I have kept it as such to avoid changing
     74  * the existing interface. */
     75 VbKeyBlockHeader* KeyBlockCreate_external(const VbPublicKey* data_key,
     76                                           const char* signing_key_pem_file,
     77                                           uint64_t algorithm,
     78                                           uint64_t flags,
     79                                           const char* external_signer) {
     80   VbKeyBlockHeader* h;
     81   uint64_t signed_size = sizeof(VbKeyBlockHeader) + data_key->key_size;
     82   uint64_t block_size = (signed_size + SHA512_DIGEST_SIZE +
     83                          siglen_map[algorithm]);
     84   uint8_t* data_key_dest;
     85   uint8_t* block_sig_dest;
     86   uint8_t* block_chk_dest;
     87   VbSignature *sigtmp;
     88 
     89   /* Allocate key block */
     90   h = (VbKeyBlockHeader*)malloc(block_size);
     91   if (!h)
     92     return NULL;
     93   if (!signing_key_pem_file || !data_key || !external_signer)
     94     return NULL;
     95 
     96   data_key_dest = (uint8_t*)(h + 1);
     97   block_chk_dest = data_key_dest + data_key->key_size;
     98   block_sig_dest = block_chk_dest + SHA512_DIGEST_SIZE;
     99 
    100   Memcpy(h->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE);
    101   h->header_version_major = KEY_BLOCK_HEADER_VERSION_MAJOR;
    102   h->header_version_minor = KEY_BLOCK_HEADER_VERSION_MINOR;
    103   h->key_block_size = block_size;
    104   h->key_block_flags = flags;
    105 
    106   /* Copy data key */
    107   PublicKeyInit(&h->data_key, data_key_dest, data_key->key_size);
    108   PublicKeyCopy(&h->data_key, data_key);
    109 
    110   /* Set up signature structs so we can calculate the signatures */
    111   SignatureInit(&h->key_block_checksum, block_chk_dest,
    112                 SHA512_DIGEST_SIZE, signed_size);
    113   SignatureInit(&h->key_block_signature, block_sig_dest,
    114                 siglen_map[algorithm], signed_size);
    115 
    116   /* Calculate checksum */
    117   sigtmp = CalculateChecksum((uint8_t*)h, signed_size);
    118   SignatureCopy(&h->key_block_checksum, sigtmp);
    119   free(sigtmp);
    120 
    121   /* Calculate signature */
    122   sigtmp = CalculateSignature_external((uint8_t*)h, signed_size,
    123                                        signing_key_pem_file, algorithm,
    124                                        external_signer);
    125   SignatureCopy(&h->key_block_signature, sigtmp);
    126   free(sigtmp);
    127 
    128   /* Return the header */
    129   return h;
    130 }
    131 
    132 /* Read a key block from a .keyblock file.  Caller owns the returned
    133  * pointer, and must free it with free().
    134  *
    135  * Returns NULL if error. */
    136 VbKeyBlockHeader* KeyBlockRead(const char* filename) {
    137 
    138   VbKeyBlockHeader* block;
    139   uint64_t file_size;
    140 
    141   block = (VbKeyBlockHeader*)ReadFile(filename, &file_size);
    142   if (!block) {
    143     VBDEBUG(("Error reading key block file: %s\n", filename));
    144     return NULL;
    145   }
    146 
    147   /* Verify the hash of the key block, since we can do that without
    148    * the public signing key. */
    149   if (0 != KeyBlockVerify(block, file_size, NULL, 1)) {
    150     VBDEBUG(("Invalid key block file: %s\n", filename));
    151     free(block);
    152     return NULL;
    153   }
    154 
    155   return block;
    156 }
    157 
    158 
    159 /* Write a key block to a file in .keyblock format. */
    160 int KeyBlockWrite(const char* filename, const VbKeyBlockHeader* key_block) {
    161 
    162   if (0 != WriteFile(filename, key_block, key_block->key_block_size)) {
    163     VBDEBUG(("KeyBlockWrite() error writing key block\n"));
    164     return 1;
    165   }
    166 
    167   return 0;
    168 }
    169