Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(313)

Unified Diff: host/lib/host_signature.c

Issue 2745007: Major refactoring of structures, with unit tests. (Closed) Base URL: ssh://gitrw.chromium.org/vboot_reference.git
Patch Set: Implemented LoadFirmware2() Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: host/lib/host_signature.c
diff --git a/host/lib/host_signature.c b/host/lib/host_signature.c
new file mode 100644
index 0000000000000000000000000000000000000000..935e77310c6f01bcf183f7fb7cf654c433600f6e
--- /dev/null
+++ b/host/lib/host_signature.c
@@ -0,0 +1,135 @@
+/* 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 signature generation.
+ */
+
+/* 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 "cryptolib.h"
+#include "file_keys.h"
+#include "utility.h"
+#include "vboot_common.h"
+#include "host_common.h"
+
+
+VbSignature* SignatureAlloc(uint64_t sig_size, uint64_t data_size) {
+ VbSignature* sig = (VbSignature*)Malloc(sizeof(VbSignature) + sig_size);
+ if (!sig)
+ return NULL;
+
+ sig->sig_offset = sizeof(VbSignature);
+ sig->sig_size = sig_size;
+ sig->data_size = data_size;
+ return sig;
+}
+
+
+void SignatureInit(VbSignature* sig, uint8_t* sig_data,
+ uint64_t sig_size, uint64_t data_size) {
+ sig->sig_offset = OffsetOf(sig, sig_data);
+ sig->sig_size = sig_size;
+ sig->data_size = data_size;
+}
+
+
+int SignatureCopy(VbSignature* dest, const VbSignature* src) {
+ if (dest->sig_size < src->sig_size)
+ return 1;
+ dest->sig_size = src->sig_size;
+ dest->data_size = src->data_size;
+ Memcpy(GetSignatureData(dest), GetSignatureDataC(src), src->sig_size);
+ return 0;
+}
+
+
+VbSignature* CalculateChecksum(const uint8_t* data, uint64_t size) {
+
+ uint8_t* header_checksum;
+ VbSignature* sig;
+
+ header_checksum = DigestBuf(data, size, SHA512_DIGEST_ALGORITHM);
+ if (!header_checksum)
+ return NULL;
+
+ sig = SignatureAlloc(SHA512_DIGEST_SIZE, 0);
+ if (!sig) {
+ Free(header_checksum);
+ return NULL;
+ }
+ sig->sig_offset = sizeof(VbSignature);
+ sig->sig_size = SHA512_DIGEST_SIZE;
+ sig->data_size = size;
+
+ /* Signature data immediately follows the header */
+ Memcpy(GetSignatureData(sig), header_checksum, SHA512_DIGEST_SIZE);
+ Free(header_checksum);
+ return sig;
+}
+
+
+VbSignature* CalculateSignature(const uint8_t* data, uint64_t size,
+ const VbPrivateKey* key) {
+
+ uint8_t* digest;
+ int digest_size = hash_size_map[key->algorithm];
+
+ const uint8_t* digestinfo = hash_digestinfo_map[key->algorithm];
+ int digestinfo_size = digestinfo_size_map[key->algorithm];
+
+ uint8_t* signature_digest;
+ int signature_digest_len = digest_size + digestinfo_size;
+
+ VbSignature* sig;
+ int rv;
+
+ /* Calculate the digest */
+ /* TODO: rename param 3 of DigestBuf to hash_type */
+ digest = DigestBuf(data, size, hash_type_map[key->algorithm]);
+ if (!digest)
+ return NULL;
+
+ /* Prepend the digest info to the digest */
+ signature_digest = Malloc(signature_digest_len);
+ if (!signature_digest) {
+ Free(digest);
+ return NULL;
+ }
+ Memcpy(signature_digest, digestinfo, digestinfo_size);
+ Memcpy(signature_digest + digestinfo_size, digest, digest_size);
+ Free(digest);
+
+ /* Allocate output signature */
+ sig = SignatureAlloc(siglen_map[key->algorithm], size);
+ if (!sig) {
+ Free(signature_digest);
+ return NULL;
+ }
+
+ /* Sign the signature_digest into our output buffer */
+ rv = RSA_private_encrypt(signature_digest_len, /* Input length */
+ signature_digest, /* Input data */
+ GetSignatureData(sig), /* Output sig */
+ key->rsa_private_key, /* Key to use */
+ RSA_PKCS1_PADDING); /* Padding to use */
+ Free(signature_digest);
+
+ if (-1 == rv) {
+ debug("SignatureBuf(): RSA_private_encrypt() failed.\n");
+ Free(sig);
+ return NULL;
+ }
+
+ /* Return the signature */
+ return sig;
+}

Powered by Google App Engine
This is Rietveld 408576698