1 /* 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.
4 */
5
6 #include <openssl/pem.h>
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11
12 #include "cryptolib.h"
13 #include "host_common.h"
14 #include "signature_digest.h"
15
16
PrependDigestInfo(unsigned int algorithm,uint8_t * digest)17 uint8_t* PrependDigestInfo(unsigned int algorithm, uint8_t* digest) {
18 const int digest_size = hash_size_map[algorithm];
19 const int digestinfo_size = digestinfo_size_map[algorithm];
20 const uint8_t* digestinfo = hash_digestinfo_map[algorithm];
21 uint8_t* p = malloc(digestinfo_size + digest_size);
22 Memcpy(p, digestinfo, digestinfo_size);
23 Memcpy(p + digestinfo_size, digest, digest_size);
24 return p;
25 }
26
SignatureDigest(const uint8_t * buf,uint64_t len,unsigned int algorithm)27 uint8_t* SignatureDigest(const uint8_t* buf, uint64_t len,
28 unsigned int algorithm) {
29 uint8_t* info_digest = NULL;
30 uint8_t* digest = NULL;
31
32 if (algorithm >= kNumAlgorithms) {
33 VBDEBUG(("SignatureDigest() called with invalid algorithm!\n"));
34 } else if ((digest = DigestBuf(buf, len, algorithm))) {
35 info_digest = PrependDigestInfo(algorithm, digest);
36 }
37 free(digest);
38 return info_digest;
39 }
40
SignatureBuf(const uint8_t * buf,uint64_t len,const char * key_file,unsigned int algorithm)41 uint8_t* SignatureBuf(const uint8_t* buf, uint64_t len, const char* key_file,
42 unsigned int algorithm) {
43 FILE* key_fp = NULL;
44 RSA* key = NULL;
45 uint8_t* signature = NULL;
46 uint8_t* signature_digest = SignatureDigest(buf, len, algorithm);
47 int signature_digest_len = (hash_size_map[algorithm] +
48 digestinfo_size_map[algorithm]);
49 key_fp = fopen(key_file, "r");
50 if (!key_fp) {
51 VBDEBUG(("SignatureBuf(): Couldn't open key file: %s\n", key_file));
52 free(signature_digest);
53 return NULL;
54 }
55 if ((key = PEM_read_RSAPrivateKey(key_fp, NULL, NULL, NULL)))
56 signature = (uint8_t*) malloc(siglen_map[algorithm]);
57 else
58 VBDEBUG(("SignatureBuf(): Couldn't read private key from file: %s\n",
59 key_file));
60 if (signature) {
61 if (-1 == RSA_private_encrypt(signature_digest_len, /* Input length. */
62 signature_digest, /* Input data. */
63 signature, /* Output signature. */
64 key, /* Key to use. */
65 RSA_PKCS1_PADDING)) /* Padding to use. */
66 VBDEBUG(("SignatureBuf(): RSA_private_encrypt() failed.\n"));
67 }
68 fclose(key_fp);
69 if (key)
70 RSA_free(key);
71 free(signature_digest);
72 return signature;
73 }
74