blob: 81c666ea3d606b427169b56d34d29c586460ca96 [file] [log] [blame]
Gaurav Shah8bf29d82010-01-28 19:43:24 -08001/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
Gaurav Shah8bf29d82010-01-28 19:43:24 -08004 */
5
6#include "signature_digest.h"
Gaurav Shahf5564fa2010-03-02 15:40:01 -08007#define OPENSSL_NO_SHA
8#include <openssl/engine.h>
9#include <openssl/pem.h>
10#include <openssl/rsa.h>
Gaurav Shah8bf29d82010-01-28 19:43:24 -080011
12#include <stdio.h>
13#include <stdlib.h>
14#include <unistd.h>
15
Gaurav Shah5411c7a2010-03-31 10:56:49 -070016#include "cryptolib.h"
Randall Spangler32a65262011-06-27 10:49:11 -070017#include "host_common.h"
18
Gaurav Shah8bf29d82010-01-28 19:43:24 -080019
Gaurav Shah47b593d2010-08-17 15:48:22 -070020uint8_t* PrependDigestInfo(unsigned int algorithm, uint8_t* digest) {
Gaurav Shah8bf29d82010-01-28 19:43:24 -080021 const int digest_size = hash_size_map[algorithm];
22 const int digestinfo_size = digestinfo_size_map[algorithm];
23 const uint8_t* digestinfo = hash_digestinfo_map[algorithm];
Randall Spangler32a65262011-06-27 10:49:11 -070024 uint8_t* p = malloc(digestinfo_size + digest_size);
Gaurav Shahf5564fa2010-03-02 15:40:01 -080025 Memcpy(p, digestinfo, digestinfo_size);
26 Memcpy(p + digestinfo_size, digest, digest_size);
Gaurav Shah8bf29d82010-01-28 19:43:24 -080027 return p;
28}
29
Gaurav Shah47b593d2010-08-17 15:48:22 -070030uint8_t* SignatureDigest(const uint8_t* buf, uint64_t len,
31 unsigned int algorithm) {
Gaurav Shah8bf29d82010-01-28 19:43:24 -080032 uint8_t* info_digest = NULL;
Gaurav Shahf5564fa2010-03-02 15:40:01 -080033 uint8_t* digest = NULL;
Gaurav Shah8bf29d82010-01-28 19:43:24 -080034
Gaurav Shah8bf29d82010-01-28 19:43:24 -080035 if (algorithm >= kNumAlgorithms) {
Bill Richardsonabf05502010-07-01 10:22:06 -070036 VBDEBUG(("SignatureDigest() called with invalid algorithm!\n"));
Gaurav Shahf5564fa2010-03-02 15:40:01 -080037 } else if ((digest = DigestBuf(buf, len, algorithm))) {
38 info_digest = PrependDigestInfo(algorithm, digest);
Gaurav Shah8bf29d82010-01-28 19:43:24 -080039 }
Randall Spangler32a65262011-06-27 10:49:11 -070040 free(digest);
Gaurav Shahf5564fa2010-03-02 15:40:01 -080041 return info_digest;
42}
Gaurav Shah8bf29d82010-01-28 19:43:24 -080043
Gaurav Shah456678b2010-03-10 18:38:45 -080044uint8_t* SignatureBuf(const uint8_t* buf, uint64_t len, const char* key_file,
Gaurav Shah47b593d2010-08-17 15:48:22 -070045 unsigned int algorithm) {
Gaurav Shahf5564fa2010-03-02 15:40:01 -080046 FILE* key_fp = NULL;
47 RSA* key = NULL;
48 uint8_t* signature = NULL;
49 uint8_t* signature_digest = SignatureDigest(buf, len, algorithm);
50 int signature_digest_len = (hash_size_map[algorithm] +
51 digestinfo_size_map[algorithm]);
52 key_fp = fopen(key_file, "r");
53 if (!key_fp) {
Bill Richardsonabf05502010-07-01 10:22:06 -070054 VBDEBUG(("SignatureBuf(): Couldn't open key file: %s\n", key_file));
Randall Spangler32a65262011-06-27 10:49:11 -070055 free(signature_digest);
Gaurav Shahf5564fa2010-03-02 15:40:01 -080056 return NULL;
57 }
58 if ((key = PEM_read_RSAPrivateKey(key_fp, NULL, NULL, NULL)))
Randall Spangler32a65262011-06-27 10:49:11 -070059 signature = (uint8_t*) malloc(siglen_map[algorithm]);
Gaurav Shahf5564fa2010-03-02 15:40:01 -080060 else
Bill Richardsonabf05502010-07-01 10:22:06 -070061 VBDEBUG(("SignatureBuf(): Couldn't read private key from file: %s\n",
62 key_file));
Gaurav Shahf5564fa2010-03-02 15:40:01 -080063 if (signature) {
64 if (-1 == RSA_private_encrypt(signature_digest_len, /* Input length. */
65 signature_digest, /* Input data. */
66 signature, /* Output signature. */
67 key, /* Key to use. */
68 RSA_PKCS1_PADDING)) /* Padding to use. */
Bill Richardsonabf05502010-07-01 10:22:06 -070069 VBDEBUG(("SignatureBuf(): RSA_private_encrypt() failed.\n"));
Gaurav Shahf5564fa2010-03-02 15:40:01 -080070 }
Gaurav Shah259de402010-03-12 17:42:03 -080071 fclose(key_fp);
Gaurav Shahf5564fa2010-03-02 15:40:01 -080072 if (key)
73 RSA_free(key);
Randall Spangler32a65262011-06-27 10:49:11 -070074 free(signature_digest);
Gaurav Shahf5564fa2010-03-02 15:40:01 -080075 return signature;
Gaurav Shah8bf29d82010-01-28 19:43:24 -080076}