blob: 4dba95a66afe354cee073b633642abaca1b3525c [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"
Gaurav Shahf5564fa2010-03-02 15:40:01 -080017#include "utility.h"
Gaurav Shah8bf29d82010-01-28 19:43:24 -080018
Gaurav Shah08df9b82010-02-23 16:16:23 -080019uint8_t* PrependDigestInfo(int algorithm, uint8_t* digest) {
Gaurav Shah8bf29d82010-01-28 19:43:24 -080020 const int digest_size = hash_size_map[algorithm];
21 const int digestinfo_size = digestinfo_size_map[algorithm];
22 const uint8_t* digestinfo = hash_digestinfo_map[algorithm];
Gaurav Shahf5564fa2010-03-02 15:40:01 -080023 uint8_t* p = Malloc(digestinfo_size + digest_size);
24 Memcpy(p, digestinfo, digestinfo_size);
25 Memcpy(p + digestinfo_size, digest, digest_size);
Gaurav Shah8bf29d82010-01-28 19:43:24 -080026 return p;
27}
28
Gaurav Shah456678b2010-03-10 18:38:45 -080029uint8_t* SignatureDigest(const uint8_t* buf, uint64_t len, int algorithm) {
Gaurav Shah8bf29d82010-01-28 19:43:24 -080030 uint8_t* info_digest = NULL;
Gaurav Shahf5564fa2010-03-02 15:40:01 -080031 uint8_t* digest = NULL;
Gaurav Shah8bf29d82010-01-28 19:43:24 -080032
Gaurav Shah8bf29d82010-01-28 19:43:24 -080033 if (algorithm >= kNumAlgorithms) {
Gaurav Shahf3dd1a62010-04-05 15:50:00 -070034 debug("SignatureDigest() called with invalid algorithm!\n");
Gaurav Shahf5564fa2010-03-02 15:40:01 -080035 } else if ((digest = DigestBuf(buf, len, algorithm))) {
36 info_digest = PrependDigestInfo(algorithm, digest);
Gaurav Shah8bf29d82010-01-28 19:43:24 -080037 }
Gaurav Shahf5564fa2010-03-02 15:40:01 -080038 Free(digest);
39 return info_digest;
40}
Gaurav Shah8bf29d82010-01-28 19:43:24 -080041
Gaurav Shah456678b2010-03-10 18:38:45 -080042uint8_t* SignatureBuf(const uint8_t* buf, uint64_t len, const char* key_file,
Gaurav Shahf5564fa2010-03-02 15:40:01 -080043 int algorithm) {
44 FILE* key_fp = NULL;
45 RSA* key = NULL;
46 uint8_t* signature = NULL;
47 uint8_t* signature_digest = SignatureDigest(buf, len, algorithm);
48 int signature_digest_len = (hash_size_map[algorithm] +
49 digestinfo_size_map[algorithm]);
50 key_fp = fopen(key_file, "r");
51 if (!key_fp) {
Gaurav Shahf3dd1a62010-04-05 15:50:00 -070052 debug("SignatureBuf(): Couldn't open key file: %s\n", key_file);
Gaurav Shah259de402010-03-12 17:42:03 -080053 Free(signature_digest);
Gaurav Shahf5564fa2010-03-02 15:40:01 -080054 return NULL;
55 }
56 if ((key = PEM_read_RSAPrivateKey(key_fp, NULL, NULL, NULL)))
57 signature = (uint8_t*) Malloc(siglen_map[algorithm]);
58 else
Gaurav Shahf3dd1a62010-04-05 15:50:00 -070059 debug("SignatureBuf(): Couldn't read private key from file: %s\n",
Gaurav Shahf5564fa2010-03-02 15:40:01 -080060 key_file);
61 if (signature) {
62 if (-1 == RSA_private_encrypt(signature_digest_len, /* Input length. */
63 signature_digest, /* Input data. */
64 signature, /* Output signature. */
65 key, /* Key to use. */
66 RSA_PKCS1_PADDING)) /* Padding to use. */
Gaurav Shahf3dd1a62010-04-05 15:50:00 -070067 debug("SignatureBuf(): RSA_private_encrypt() failed.\n");
Gaurav Shahf5564fa2010-03-02 15:40:01 -080068 }
Gaurav Shah259de402010-03-12 17:42:03 -080069 fclose(key_fp);
Gaurav Shahf5564fa2010-03-02 15:40:01 -080070 if (key)
71 RSA_free(key);
72 Free(signature_digest);
73 return signature;
Gaurav Shah8bf29d82010-01-28 19:43:24 -080074}