mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-26 19:25:02 +00:00
vboot currently uses the |SHA256_CTX| name, which is claimed by OpenSSL. To work around this, it defines OPENSSL_NO_SHA, but that can't be done at compile time: The OPENSSL_NO_* defines are set by OpenSSL to reflect the configuration that it was built with so that users of OpenSSL can disable features as needed. They can affect the contents of structures any thus the ABI of the library. If these defines are set outside of OpenSSL, then the library and the code that uses it will have incompatible ABIs. At that point it's only functioning by blind luck. This change renames the name-collisions so that this hack isn't needed. This is the same change as was made internally in cl/85758149. BUG=none BRANCH=none TEST=emerge-samus coreboot; make runtests Change-Id: I709da2507f341896d89d50129ce30ffb111a20d1 Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/263506 Reviewed-by: Randall Spangler <rspangler@chromium.org>
263 lines
6.0 KiB
C
263 lines
6.0 KiB
C
/* 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 keys.
|
|
*/
|
|
|
|
/* TODO: change all 'return 0', 'return 1' into meaningful return codes */
|
|
|
|
#include <openssl/pem.h>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
#include "cryptolib.h"
|
|
#include "host_common.h"
|
|
#include "host_key.h"
|
|
#include "host_misc.h"
|
|
#include "vboot_common.h"
|
|
|
|
|
|
VbPrivateKey* PrivateKeyReadPem(const char* filename, uint64_t algorithm) {
|
|
|
|
VbPrivateKey* key;
|
|
RSA* rsa_key;
|
|
FILE* f;
|
|
|
|
if (algorithm >= kNumAlgorithms) {
|
|
VBDEBUG(("%s() called with invalid algorithm!\n", __FUNCTION__));
|
|
return NULL;
|
|
}
|
|
|
|
/* Read private key */
|
|
f = fopen(filename, "r");
|
|
if (!f) {
|
|
VBDEBUG(("%s(): Couldn't open key file: %s\n", __FUNCTION__, filename));
|
|
return NULL;
|
|
}
|
|
rsa_key = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL);
|
|
fclose(f);
|
|
if (!rsa_key) {
|
|
VBDEBUG(("%s(): Couldn't read private key from file: %s\n", __FUNCTION__,
|
|
filename));
|
|
return NULL;
|
|
}
|
|
|
|
/* Store key and algorithm in our struct */
|
|
key = (VbPrivateKey*)malloc(sizeof(VbPrivateKey));
|
|
if (!key) {
|
|
RSA_free(rsa_key);
|
|
return NULL;
|
|
}
|
|
key->rsa_private_key = rsa_key;
|
|
key->algorithm = algorithm;
|
|
|
|
/* Return the key */
|
|
return key;
|
|
}
|
|
|
|
|
|
void PrivateKeyFree(VbPrivateKey* key) {
|
|
if (!key)
|
|
return;
|
|
if (key->rsa_private_key)
|
|
RSA_free(key->rsa_private_key);
|
|
free(key);
|
|
}
|
|
|
|
|
|
/* Write a private key to a file in .vbprivk format. */
|
|
int PrivateKeyWrite(const char* filename, const VbPrivateKey* key) {
|
|
uint8_t *outbuf = 0;
|
|
int buflen;
|
|
FILE *f;
|
|
|
|
buflen = i2d_RSAPrivateKey(key->rsa_private_key, &outbuf);
|
|
if (buflen <= 0) {
|
|
VbExError("Unable to write private key buffer\n");
|
|
return 1;
|
|
}
|
|
|
|
f = fopen(filename, "wb");
|
|
if (!f) {
|
|
VbExError("Unable to open file %s\n", filename);
|
|
free(outbuf);
|
|
return 1;
|
|
}
|
|
|
|
if (1 != fwrite(&key->algorithm, sizeof(key->algorithm), 1, f)) {
|
|
VbExError("Unable to write to file %s\n", filename);
|
|
fclose(f);
|
|
free(outbuf);
|
|
unlink(filename); /* Delete any partial file */
|
|
}
|
|
|
|
if (1 != fwrite(outbuf, buflen, 1, f)) {
|
|
VbExError("Unable to write to file %s\n", filename);
|
|
fclose(f);
|
|
unlink(filename); /* Delete any partial file */
|
|
free(outbuf);
|
|
}
|
|
|
|
fclose(f);
|
|
free(outbuf);
|
|
return 0;
|
|
}
|
|
|
|
VbPrivateKey* PrivateKeyRead(const char* filename) {
|
|
VbPrivateKey *key;
|
|
uint64_t filelen = 0;
|
|
uint8_t *buffer;
|
|
const unsigned char *start;
|
|
|
|
buffer = ReadFile(filename, &filelen);
|
|
if (!buffer) {
|
|
VbExError("unable to read from file %s\n", filename);
|
|
return 0;
|
|
}
|
|
|
|
key = (VbPrivateKey*)malloc(sizeof(VbPrivateKey));
|
|
if (!key) {
|
|
VbExError("Unable to allocate VbPrivateKey\n");
|
|
free(buffer);
|
|
return 0;
|
|
}
|
|
|
|
key->algorithm = *(typeof(key->algorithm) *)buffer;
|
|
start = buffer + sizeof(key->algorithm);
|
|
|
|
key->rsa_private_key = d2i_RSAPrivateKey(0, &start,
|
|
filelen - sizeof(key->algorithm));
|
|
|
|
if (!key->rsa_private_key) {
|
|
VbExError("Unable to parse RSA private key\n");
|
|
free(buffer);
|
|
free(key);
|
|
return 0;
|
|
}
|
|
|
|
free(buffer);
|
|
return key;
|
|
}
|
|
|
|
|
|
/* Allocate a new public key with space for a [key_size] byte key. */
|
|
VbPublicKey* PublicKeyAlloc(uint64_t key_size, uint64_t algorithm,
|
|
uint64_t version) {
|
|
VbPublicKey* key = (VbPublicKey*)malloc(sizeof(VbPublicKey) + key_size);
|
|
if (!key)
|
|
return NULL;
|
|
|
|
key->algorithm = algorithm;
|
|
key->key_version = version;
|
|
key->key_size = key_size;
|
|
key->key_offset = sizeof(VbPublicKey);
|
|
return key;
|
|
}
|
|
|
|
VbPublicKey* PublicKeyReadKeyb(const char* filename, uint64_t algorithm,
|
|
uint64_t version) {
|
|
VbPublicKey* key;
|
|
uint8_t* key_data;
|
|
uint64_t key_size;
|
|
uint64_t expected_key_size;
|
|
|
|
if (algorithm >= kNumAlgorithms) {
|
|
VBDEBUG(("PublicKeyReadKeyb() called with invalid algorithm!\n"));
|
|
return NULL;
|
|
}
|
|
if (version > 0xFFFF) {
|
|
/* Currently, TPM only supports 16-bit version */
|
|
VBDEBUG(("PublicKeyReadKeyb() called with invalid version!\n"));
|
|
return NULL;
|
|
}
|
|
|
|
key_data = ReadFile(filename, &key_size);
|
|
if (!key_data)
|
|
return NULL;
|
|
|
|
if (!RSAProcessedKeySize(algorithm, &expected_key_size) ||
|
|
expected_key_size != key_size) {
|
|
VBDEBUG(("PublicKeyReadKeyb() wrong key size for algorithm\n"));
|
|
free(key_data);
|
|
return NULL;
|
|
}
|
|
|
|
key = PublicKeyAlloc(key_size, algorithm, version);
|
|
if (!key) {
|
|
free(key_data);
|
|
return NULL;
|
|
}
|
|
Memcpy(GetPublicKeyData(key), key_data, key_size);
|
|
|
|
free(key_data);
|
|
return key;
|
|
}
|
|
|
|
|
|
int PublicKeyLooksOkay(VbPublicKey *key, uint64_t file_size)
|
|
{
|
|
uint64_t key_size;
|
|
|
|
/* Sanity-check key data */
|
|
if (0 != VerifyPublicKeyInside(key, file_size, key)) {
|
|
VBDEBUG(("PublicKeyRead() not a VbPublicKey\n"));
|
|
return 0;
|
|
}
|
|
if (key->algorithm >= kNumAlgorithms) {
|
|
VBDEBUG(("PublicKeyRead() invalid algorithm\n"));
|
|
return 0;
|
|
}
|
|
if (key->key_version > 0xFFFF) {
|
|
VBDEBUG(("PublicKeyRead() invalid version\n"));
|
|
return 0; /* Currently, TPM only supports 16-bit version */
|
|
}
|
|
if (!RSAProcessedKeySize(key->algorithm, &key_size) ||
|
|
key_size != key->key_size) {
|
|
VBDEBUG(("PublicKeyRead() wrong key size for algorithm\n"));
|
|
return 0;
|
|
}
|
|
|
|
/* Success */
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
VbPublicKey* PublicKeyRead(const char* filename) {
|
|
VbPublicKey* key;
|
|
uint64_t file_size;
|
|
|
|
key = (VbPublicKey*)ReadFile(filename, &file_size);
|
|
if (!key)
|
|
return NULL;
|
|
|
|
if (PublicKeyLooksOkay(key, file_size))
|
|
return key;
|
|
|
|
/* Error */
|
|
free(key);
|
|
return NULL;
|
|
}
|
|
|
|
int PublicKeyWrite(const char* filename, const VbPublicKey* key) {
|
|
VbPublicKey* kcopy;
|
|
int rv;
|
|
|
|
/* Copy the key, so its data is contiguous with the header */
|
|
kcopy = PublicKeyAlloc(key->key_size, 0, 0);
|
|
if (!kcopy)
|
|
return 1;
|
|
if (0 != PublicKeyCopy(kcopy, key)) {
|
|
free(kcopy);
|
|
return 1;
|
|
}
|
|
|
|
/* Write the copy, then free it */
|
|
rv = WriteFile(filename, kcopy, kcopy->key_offset + kcopy->key_size);
|
|
free(kcopy);
|
|
return rv;
|
|
}
|