Index: host/lib/host_key.c |
diff --git a/host/lib/host_key.c b/host/lib/host_key.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..5730a3f60ec0cb5e95a78b749054958333ac4a34 |
--- /dev/null |
+++ b/host/lib/host_key.c |
@@ -0,0 +1,145 @@ |
+/* 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 keys. |
+ */ |
+ |
+/* TODO: change all 'return 0', 'return 1' into meaningful return codes */ |
+ |
+#define OPENSSL_NO_SHA |
+#include <openssl/engine.h> |
+#include <openssl/pem.h> |
+#include <openssl/rsa.h> |
+ |
+#include <stdio.h> |
+#include <stdlib.h> |
+#include <unistd.h> |
+ |
+#include "host_key.h" |
+ |
+#include "cryptolib.h" |
+#include "file_keys.h" |
+#include "utility.h" |
+#include "vboot_common.h" |
+ |
+ |
+VbPrivateKey* PrivateKeyRead(const char* filename, uint64_t algorithm) { |
+ |
+ VbPrivateKey* key; |
+ RSA* rsa_key; |
+ FILE* f; |
+ |
+ if (algorithm >= kNumAlgorithms) { |
+ debug("PrivateKeyRead() called with invalid algorithm!\n"); |
+ return NULL; |
+ } |
+ |
+ /* Read private key */ |
+ f = fopen(filename, "r"); |
+ if (!f) { |
+ debug("PrivateKeyRead(): Couldn't open key file: %s\n", filename); |
+ return NULL; |
+ } |
+ rsa_key = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL); |
+ fclose(f); |
+ if (!rsa_key) { |
+ debug("PrivateKeyRead(): Couldn't read private key from file: %s\n", |
+ 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); |
+} |
+ |
+ |
+void PublicKeyInit(VbPublicKey* key, uint8_t* key_data, uint64_t key_size) { |
+ key->key_offset = OffsetOf(key, key_data); |
+ key->key_size = key_size; |
+ key->algorithm = kNumAlgorithms; /* Key not present yet */ |
+ key->key_version = 0; |
+} |
+ |
+ |
+/* Allocate a new public key with space for a [key_size] byte key. */ |
gauravsh
2010/06/10 14:44:13
nit: there's a possibility of confusion with what
|
+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; |
+} |
+ |
+ |
+/* Copy a public key from [src] to [dest]. |
+ * |
+ * Returns zero if success, non-zero if error. */ |
+int PublicKeyCopy(VbPublicKey* dest, const VbPublicKey* src) { |
+ if (dest->key_size < src->key_size) |
gauravsh
2010/06/10 14:44:13
shouldn't we always return an error if dest key_si
|
+ return 1; |
+ |
+ dest->key_size = src->key_size; |
+ dest->algorithm = src->algorithm; |
+ dest->key_version = src->key_version; |
+ Memcpy(GetPublicKeyData(dest), GetPublicKeyDataC(src), src->key_size); |
+ return 0; |
+} |
+ |
+ |
+VbPublicKey* PublicKeyRead(const char* filename, uint64_t algorithm, |
+ uint64_t version) { |
+ |
+ VbPublicKey* key; |
+ uint8_t* key_data; |
+ uint64_t key_size; |
+ |
+ if (algorithm >= kNumAlgorithms) { |
+ debug("PublicKeyRead() called with invalid algorithm!\n"); |
+ return NULL; |
+ } |
+ if (version > 0xFFFF) { |
+ /* Currently, TPM only supports 16-bit version */ |
+ debug("PublicKeyRead() called with invalid version!\n"); |
+ return NULL; |
+ } |
+ |
+ key_data = BufferFromFile(filename, &key_size); |
+ if (!key_data) |
+ return NULL; |
+ |
+ /* TODO: sanity-check key length based on algorithm */ |
+ |
+ 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; |
+} |