diff options
Diffstat (limited to 'bdb/host.c')
-rw-r--r-- | bdb/host.c | 347 |
1 files changed, 0 insertions, 347 deletions
diff --git a/bdb/host.c b/bdb/host.c deleted file mode 100644 index 24d94652..00000000 --- a/bdb/host.c +++ /dev/null @@ -1,347 +0,0 @@ -/* Copyright (c) 2015 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 signing - */ - -#include <stdio.h> -#include <string.h> -#include <unistd.h> - -#include "bdb.h" -#include "host.h" - -char *strzcpy(char *dest, const char *src, size_t size) -{ - strncpy(dest, src, size); - dest[size - 1] = 0; - return dest; -} - -uint8_t *read_file(const char *filename, uint32_t *size_ptr) -{ - FILE *f; - uint8_t *buf; - long size; - - *size_ptr = 0; - - f = fopen(filename, "rb"); - if (!f) { - fprintf(stderr, "Unable to open file %s\n", filename); - return NULL; - } - - fseek(f, 0, SEEK_END); - size = ftell(f); - rewind(f); - - if (size < 0 || size > UINT32_MAX) { - fclose(f); - return NULL; - } - - buf = malloc(size); - if (!buf) { - fclose(f); - return NULL; - } - - if (1 != fread(buf, size, 1, f)) { - fprintf(stderr, "Unable to read file %s\n", filename); - fclose(f); - free(buf); - return NULL; - } - - fclose(f); - - *size_ptr = size; - return buf; -} - -int write_file(const char *filename, const void *buf, uint32_t size) -{ - FILE *f = fopen(filename, "wb"); - - if (!f) { - fprintf(stderr, "Unable to open file %s\n", filename); - return 1; - } - - if (1 != fwrite(buf, size, 1, f)) { - fprintf(stderr, "Unable to write to file %s\n", filename); - fclose(f); - unlink(filename); /* Delete any partial file */ - return 1; - } - - fclose(f); - return 0; -} - -struct rsa_st *read_pem(const char *filename) -{ - struct rsa_st *pem; - FILE *f; - - /* Read private key */ - f = fopen(filename, "rb"); - if (!f) { - fprintf(stderr, "%s: unable to read key from %s\n", - __func__, filename); - return NULL; - } - - pem = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL); - fclose(f); - - return pem; -} - -struct bdb_key *bdb_create_key(const char *filename, - uint32_t key_version, - const char *desc) -{ - uint32_t sig_alg; - size_t key_size = sizeof(struct bdb_key); - struct bdb_key *k; - uint8_t *kdata; - uint32_t kdata_size = 0; - - /* - * Read key data. Somewhat lame assumption that we can determine the - * signature algorithm from the key size, but it's true right now. - */ - kdata = read_file(filename, &kdata_size); - if (kdata_size == BDB_RSA4096_KEY_DATA_SIZE) { - sig_alg = BDB_SIG_ALG_RSA4096; - } else if (kdata_size == BDB_RSA3072B_KEY_DATA_SIZE) { - sig_alg = BDB_SIG_ALG_RSA3072B; - } else { - fprintf(stderr, "%s: bad key size from %s\n", - __func__, filename); - return NULL; - } - key_size += kdata_size; - - /* Allocate buffer */ - k = (struct bdb_key *)calloc(key_size, 1); - if (!k) { - free(kdata); - return NULL; - } - - k->struct_magic = BDB_KEY_MAGIC; - k->struct_major_version = BDB_KEY_VERSION_MAJOR; - k->struct_minor_version = BDB_KEY_VERSION_MINOR; - k->struct_size = key_size; - k->hash_alg = BDB_HASH_ALG_SHA256; - k->sig_alg = sig_alg; - k->key_version = key_version; - - /* Copy description, if any */ - if (desc) - strzcpy(k->description, desc, sizeof(k->description)); - - /* Copy key data */ - memcpy(k->key_data, kdata, kdata_size); - free(kdata); - - return k; -} - -struct bdb_sig *bdb_create_sig(const void *data, - size_t size, - struct rsa_st *key, - uint32_t sig_alg, - const char *desc) -{ - static const uint8_t info[] = { - 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, - 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, - 0x00, 0x04, 0x20 - }; - - size_t sig_size = sizeof(struct bdb_sig); - uint8_t digest[sizeof(info) + BDB_SHA256_DIGEST_SIZE]; - struct bdb_sig *sig; - - if (size >= UINT32_MAX) - return NULL; - - switch(sig_alg) { - case BDB_SIG_ALG_RSA4096: - sig_size += BDB_RSA4096_SIG_SIZE; - break; - case BDB_SIG_ALG_RSA3072B: - sig_size += BDB_RSA3072B_SIG_SIZE; - break; - default: - fprintf(stderr, "%s: bad signature algorithm %d\n", - __func__, sig_alg); - return NULL; - } - - /* Allocate buffer */ - sig = (struct bdb_sig *)calloc(sig_size, 1); - if (!sig) - return NULL; - - sig->struct_magic = BDB_SIG_MAGIC; - sig->struct_major_version = BDB_SIG_VERSION_MAJOR; - sig->struct_minor_version = BDB_SIG_VERSION_MINOR; - sig->struct_size = sig_size; - sig->hash_alg = BDB_HASH_ALG_SHA256; - sig->sig_alg = sig_alg; - sig->signed_size = size; - - /* Copy description, if any */ - if (desc) - strzcpy(sig->description, desc, sizeof(sig->description)); - - /* Calculate info-padded digest */ - memcpy(digest, info, sizeof(info)); - if (bdb_sha256(digest + sizeof(info), data, size)) { - free(sig); - return NULL; - } - - /* RSA-encrypt the signature */ - if (RSA_private_encrypt(sizeof(digest), - digest, - sig->sig_data, - key, - RSA_PKCS1_PADDING) == -1) { - free(sig); - return NULL; - } - return sig; -} - -struct bdb_header *bdb_create(struct bdb_create_params *p) -{ - size_t bdb_size = 0; - size_t sig_size = sizeof(struct bdb_sig) + BDB_RSA4096_SIG_SIZE; - size_t hashes_size = sizeof(struct bdb_hash) * p->num_hashes; - uint8_t *buf, *bnext; - struct bdb_header *h; - struct bdb_sig *sig; - struct bdb_data *data; - const void *oem; - - /* We can do some checks before we even allocate the buffer */ - - /* Make sure OEM sizes are aligned */ - if ((p->oem_area_0_size & 3) || (p->oem_area_1_size & 3)) { - fprintf(stderr, "%s: OEM areas not 32-bit aligned\n", - __func__); - return NULL; - } - - /* Hash count must fit in uint8_t */ - if (p->num_hashes > 255) { - fprintf(stderr, "%s: too many hashes\n", __func__); - return NULL; - } - - /* Calculate BDB size */ - bdb_size = sizeof(struct bdb_header); - bdb_size += p->bdbkey->struct_size; - bdb_size += p->oem_area_0_size; - bdb_size += p->subkey->struct_size; - bdb_size += sig_size; - bdb_size += sizeof(struct bdb_data); - bdb_size += p->oem_area_1_size; - bdb_size += sizeof(struct bdb_hash) * p->num_hashes; - bdb_size += sig_size; - - /* Make sure it fits */ - if (bdb_size > UINT32_MAX) { - fprintf(stderr, "%s: BDB size > UINT32_MAX\n", __func__); - return NULL; - } - - /* Allocate a buffer */ - bnext = buf = calloc(bdb_size, 1); - if (!buf) { - fprintf(stderr, "%s: can't allocate buffer\n", __func__); - return NULL; - } - - /* Fill in the header */ - h = (struct bdb_header *)bnext; - h->struct_magic = BDB_HEADER_MAGIC; - h->struct_major_version = BDB_HEADER_VERSION_MAJOR; - h->struct_minor_version = BDB_HEADER_VERSION_MINOR; - h->struct_size = sizeof(*h); - h->bdb_load_address = p->bdb_load_address; - h->bdb_size = bdb_size; - h->signed_size = p->oem_area_0_size + p->subkey->struct_size; - h->oem_area_0_size = p->oem_area_0_size; - bnext += h->struct_size; - - /* Copy BDB key */ - memcpy(bnext, p->bdbkey, p->bdbkey->struct_size); - bnext += p->bdbkey->struct_size; - - /* Copy OEM area 0 */ - oem = bnext; - if (p->oem_area_0_size) { - memcpy(bnext, p->oem_area_0, p->oem_area_0_size); - bnext += p->oem_area_0_size; - } - - /* Copy subkey */ - memcpy(bnext, p->subkey, p->subkey->struct_size); - bnext += p->subkey->struct_size; - - /* - * Create header signature using private BDB key. - * - * TODO: create the header signature in a totally separate step. That - * way, the private BDB key is not required each time a BDB is created. - */ - sig = bdb_create_sig(oem, h->signed_size, p->private_bdbkey, - p->bdbkey->sig_alg, p->header_sig_description); - memcpy(bnext, sig, sig->struct_size); - bnext += sig->struct_size; - - /* Fill in the data */ - data = (struct bdb_data *)bnext; - data->struct_magic = BDB_DATA_MAGIC; - data->struct_major_version = BDB_DATA_VERSION_MAJOR; - data->struct_minor_version = BDB_DATA_VERSION_MINOR; - data->struct_size = sizeof(struct bdb_data); - data->data_version = p->data_version; - data->oem_area_1_size = p->oem_area_1_size; - data->num_hashes = p->num_hashes; - data->hash_entry_size = sizeof(struct bdb_hash); - data->signed_size = data->struct_size + data->oem_area_1_size + - hashes_size; - if (p->data_description) { - strzcpy(data->description, p->data_description, - sizeof(data->description)); - } - bnext += data->struct_size; - - /* Copy OEM area 1 */ - oem = bnext; - if (p->oem_area_1_size) { - memcpy(bnext, p->oem_area_1, p->oem_area_1_size); - bnext += p->oem_area_1_size; - } - - /* Copy hashes */ - memcpy(bnext, p->hash, hashes_size); - bnext += hashes_size; - - /* Create data signature using private subkey */ - sig = bdb_create_sig(data, data->signed_size, p->private_subkey, - p->subkey->sig_alg, p->data_sig_description); - memcpy(bnext, sig, sig->struct_size); - - /* Return the BDB */ - return h; -} |