| 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;
|
| +}
|
|
|