blob: 96cc5529762b98216c98e94d5c7fa43330eaeb96 [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 Shah8bf29d82010-01-28 19:43:24 -080016#include "padding.h"
17#include "sha.h"
Gaurav Shah290e0782010-02-05 14:37:30 -080018#include "sha_utility.h"
Gaurav Shahf5564fa2010-03-02 15:40:01 -080019#include "utility.h"
Gaurav Shah8bf29d82010-01-28 19:43:24 -080020
Gaurav Shah08df9b82010-02-23 16:16:23 -080021uint8_t* PrependDigestInfo(int algorithm, uint8_t* digest) {
Gaurav Shah8bf29d82010-01-28 19:43:24 -080022 const int digest_size = hash_size_map[algorithm];
23 const int digestinfo_size = digestinfo_size_map[algorithm];
24 const uint8_t* digestinfo = hash_digestinfo_map[algorithm];
Gaurav Shahf5564fa2010-03-02 15:40:01 -080025 uint8_t* p = Malloc(digestinfo_size + digest_size);
26 Memcpy(p, digestinfo, digestinfo_size);
27 Memcpy(p + digestinfo_size, digest, digest_size);
Gaurav Shah8bf29d82010-01-28 19:43:24 -080028 return p;
29}
30
Gaurav Shahf5564fa2010-03-02 15:40:01 -080031uint8_t* SignatureDigest(const uint8_t* buf, int len, 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) {
Gaurav Shahf5564fa2010-03-02 15:40:01 -080036 fprintf(stderr, "SignatureDigest() called with invalid algorithm!\n");
37 } else if ((digest = DigestBuf(buf, len, algorithm))) {
38 info_digest = PrependDigestInfo(algorithm, digest);
Gaurav Shah8bf29d82010-01-28 19:43:24 -080039 }
Gaurav Shahf5564fa2010-03-02 15:40:01 -080040 Free(digest);
41 return info_digest;
42}
Gaurav Shah8bf29d82010-01-28 19:43:24 -080043
Gaurav Shahf5564fa2010-03-02 15:40:01 -080044uint8_t* SignatureBuf(const uint8_t* buf, int len, const char* key_file,
45 int algorithm) {
46 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) {
54 fprintf(stderr, "SignatureBuf(): Couldn't open key file: %s\n", key_file);
55 return NULL;
56 }
57 if ((key = PEM_read_RSAPrivateKey(key_fp, NULL, NULL, NULL)))
58 signature = (uint8_t*) Malloc(siglen_map[algorithm]);
59 else
60 fprintf(stderr, "SignatureBuf(): Couldn't read private key from file: %s\n",
61 key_file);
62 if (signature) {
63 if (-1 == RSA_private_encrypt(signature_digest_len, /* Input length. */
64 signature_digest, /* Input data. */
65 signature, /* Output signature. */
66 key, /* Key to use. */
67 RSA_PKCS1_PADDING)) /* Padding to use. */
68 fprintf(stderr, "SignatureBuf(): RSA_private_encrypt() failed.\n");
69 }
70 if (key)
71 RSA_free(key);
72 Free(signature_digest);
73 return signature;
Gaurav Shah8bf29d82010-01-28 19:43:24 -080074}