123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- /* 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.
- */
- #include <openssl/pem.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include "2sysincludes.h"
- #include "2common.h"
- #include "2rsa.h"
- #include "2sha.h"
- #include "host_common.h"
- #include "host_signature2.h"
- #include "signature_digest.h"
- uint8_t* PrependDigestInfo(enum vb2_hash_algorithm hash_alg, uint8_t* digest)
- {
- const int digest_size = vb2_digest_size(hash_alg);
- uint32_t digestinfo_size = 0;
- const uint8_t* digestinfo = NULL;
- if (VB2_SUCCESS != vb2_digest_info(hash_alg, &digestinfo,
- &digestinfo_size))
- return NULL;
- uint8_t* p = malloc(digestinfo_size + digest_size);
- memcpy(p, digestinfo, digestinfo_size);
- memcpy(p + digestinfo_size, digest, digest_size);
- return p;
- }
- uint8_t* SignatureDigest(const uint8_t* buf, uint64_t len,
- unsigned int algorithm)
- {
- uint8_t* info_digest = NULL;
- uint8_t digest[VB2_SHA512_DIGEST_SIZE]; /* Longest digest */
- if (algorithm >= VB2_ALG_COUNT) {
- fprintf(stderr, "SignatureDigest(): "
- "Called with invalid algorithm!\n");
- } else if (VB2_SUCCESS ==
- vb2_digest_buffer(buf, len, vb2_crypto_to_hash(algorithm),
- digest, sizeof(digest))) {
- info_digest = PrependDigestInfo(algorithm, digest);
- }
- return info_digest;
- }
- uint8_t* SignatureBuf(const uint8_t* buf, uint64_t len, const char* key_file,
- unsigned int algorithm)
- {
- const enum vb2_hash_algorithm hash_alg = vb2_crypto_to_hash(algorithm);
- FILE* key_fp = NULL;
- RSA* key = NULL;
- uint8_t* signature = NULL;
- uint8_t* signature_digest = SignatureDigest(buf, len, algorithm);
- if (!signature_digest) {
- fprintf(stderr, "SignatureBuf(): "
- "Couldn't get signature digest\n");
- return NULL;
- }
- const int digest_size = vb2_digest_size(hash_alg);
- uint32_t digestinfo_size = 0;
- const uint8_t* digestinfo = NULL;
- if (VB2_SUCCESS != vb2_digest_info(hash_alg, &digestinfo,
- &digestinfo_size)) {
- fprintf(stderr, "SignatureBuf(): Couldn't get digest info\n");
- free(signature_digest);
- return NULL;
- }
- int signature_digest_len = digest_size + digestinfo_size;
- key_fp = fopen(key_file, "r");
- if (!key_fp) {
- fprintf(stderr, "SignatureBuf(): Couldn't open key file: %s\n",
- key_file);
- free(signature_digest);
- return NULL;
- }
- if ((key = PEM_read_RSAPrivateKey(key_fp, NULL, NULL, NULL)))
- signature = (uint8_t *)malloc(
- vb2_rsa_sig_size(vb2_crypto_to_signature(algorithm)));
- else
- fprintf(stderr, "SignatureBuf(): "
- "Couldn't read private key from: %s\n", key_file);
- if (signature) {
- if (-1 == RSA_private_encrypt(
- signature_digest_len, /* Input length. */
- signature_digest, /* Input data. */
- signature, /* Output signature. */
- key, /* Key to use. */
- RSA_PKCS1_PADDING)) /* Padding to use. */
- fprintf(stderr, "SignatureBuf(): "
- "RSA_private_encrypt() failed.\n");
- }
- fclose(key_fp);
- if (key)
- RSA_free(key);
- free(signature_digest);
- return signature;
- }
|