1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2010 The ChromiumOS Authors
2*8617a60dSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
3*8617a60dSAndroid Build Coastguard Worker * found in the LICENSE file.
4*8617a60dSAndroid Build Coastguard Worker */
5*8617a60dSAndroid Build Coastguard Worker
6*8617a60dSAndroid Build Coastguard Worker #include <openssl/pem.h>
7*8617a60dSAndroid Build Coastguard Worker
8*8617a60dSAndroid Build Coastguard Worker #include <stdio.h>
9*8617a60dSAndroid Build Coastguard Worker #include <stdlib.h>
10*8617a60dSAndroid Build Coastguard Worker #include <unistd.h>
11*8617a60dSAndroid Build Coastguard Worker
12*8617a60dSAndroid Build Coastguard Worker #include "2common.h"
13*8617a60dSAndroid Build Coastguard Worker #include "2rsa.h"
14*8617a60dSAndroid Build Coastguard Worker #include "2sha.h"
15*8617a60dSAndroid Build Coastguard Worker #include "2sysincludes.h"
16*8617a60dSAndroid Build Coastguard Worker #include "host_common.h"
17*8617a60dSAndroid Build Coastguard Worker #include "host_signature21.h"
18*8617a60dSAndroid Build Coastguard Worker #include "signature_digest.h"
19*8617a60dSAndroid Build Coastguard Worker
PrependDigestInfo(enum vb2_hash_algorithm hash_alg,uint8_t * digest)20*8617a60dSAndroid Build Coastguard Worker uint8_t* PrependDigestInfo(enum vb2_hash_algorithm hash_alg, uint8_t* digest)
21*8617a60dSAndroid Build Coastguard Worker {
22*8617a60dSAndroid Build Coastguard Worker const int digest_size = vb2_digest_size(hash_alg);
23*8617a60dSAndroid Build Coastguard Worker uint32_t digestinfo_size = 0;
24*8617a60dSAndroid Build Coastguard Worker const uint8_t* digestinfo = NULL;
25*8617a60dSAndroid Build Coastguard Worker
26*8617a60dSAndroid Build Coastguard Worker if (VB2_SUCCESS != vb2_digest_info(hash_alg, &digestinfo,
27*8617a60dSAndroid Build Coastguard Worker &digestinfo_size))
28*8617a60dSAndroid Build Coastguard Worker return NULL;
29*8617a60dSAndroid Build Coastguard Worker
30*8617a60dSAndroid Build Coastguard Worker uint8_t* p = malloc(digestinfo_size + digest_size);
31*8617a60dSAndroid Build Coastguard Worker memcpy(p, digestinfo, digestinfo_size);
32*8617a60dSAndroid Build Coastguard Worker memcpy(p + digestinfo_size, digest, digest_size);
33*8617a60dSAndroid Build Coastguard Worker return p;
34*8617a60dSAndroid Build Coastguard Worker }
35*8617a60dSAndroid Build Coastguard Worker
SignatureDigest(const uint8_t * buf,uint64_t len,unsigned int algorithm)36*8617a60dSAndroid Build Coastguard Worker uint8_t* SignatureDigest(const uint8_t* buf, uint64_t len,
37*8617a60dSAndroid Build Coastguard Worker unsigned int algorithm)
38*8617a60dSAndroid Build Coastguard Worker {
39*8617a60dSAndroid Build Coastguard Worker uint8_t* info_digest = NULL;
40*8617a60dSAndroid Build Coastguard Worker
41*8617a60dSAndroid Build Coastguard Worker struct vb2_hash hash;
42*8617a60dSAndroid Build Coastguard Worker
43*8617a60dSAndroid Build Coastguard Worker if (algorithm >= VB2_ALG_COUNT) {
44*8617a60dSAndroid Build Coastguard Worker fprintf(stderr,
45*8617a60dSAndroid Build Coastguard Worker "SignatureDigest(): Called with invalid algorithm!\n");
46*8617a60dSAndroid Build Coastguard Worker return NULL;
47*8617a60dSAndroid Build Coastguard Worker }
48*8617a60dSAndroid Build Coastguard Worker
49*8617a60dSAndroid Build Coastguard Worker if (VB2_SUCCESS == vb2_hash_calculate(false, buf, len,
50*8617a60dSAndroid Build Coastguard Worker vb2_crypto_to_hash(algorithm),
51*8617a60dSAndroid Build Coastguard Worker &hash)) {
52*8617a60dSAndroid Build Coastguard Worker info_digest = PrependDigestInfo(hash.algo, hash.raw);
53*8617a60dSAndroid Build Coastguard Worker }
54*8617a60dSAndroid Build Coastguard Worker return info_digest;
55*8617a60dSAndroid Build Coastguard Worker }
56*8617a60dSAndroid Build Coastguard Worker
SignatureBuf(const uint8_t * buf,uint64_t len,const char * key_file,unsigned int algorithm)57*8617a60dSAndroid Build Coastguard Worker uint8_t* SignatureBuf(const uint8_t* buf, uint64_t len, const char* key_file,
58*8617a60dSAndroid Build Coastguard Worker unsigned int algorithm)
59*8617a60dSAndroid Build Coastguard Worker {
60*8617a60dSAndroid Build Coastguard Worker const enum vb2_hash_algorithm hash_alg = vb2_crypto_to_hash(algorithm);
61*8617a60dSAndroid Build Coastguard Worker FILE* key_fp = NULL;
62*8617a60dSAndroid Build Coastguard Worker RSA* key = NULL;
63*8617a60dSAndroid Build Coastguard Worker uint8_t* signature = NULL;
64*8617a60dSAndroid Build Coastguard Worker uint8_t* signature_digest = SignatureDigest(buf, len, algorithm);
65*8617a60dSAndroid Build Coastguard Worker if (!signature_digest) {
66*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "SignatureBuf(): "
67*8617a60dSAndroid Build Coastguard Worker "Couldn't get signature digest\n");
68*8617a60dSAndroid Build Coastguard Worker return NULL;
69*8617a60dSAndroid Build Coastguard Worker }
70*8617a60dSAndroid Build Coastguard Worker
71*8617a60dSAndroid Build Coastguard Worker const int digest_size = vb2_digest_size(hash_alg);
72*8617a60dSAndroid Build Coastguard Worker
73*8617a60dSAndroid Build Coastguard Worker uint32_t digestinfo_size = 0;
74*8617a60dSAndroid Build Coastguard Worker const uint8_t* digestinfo = NULL;
75*8617a60dSAndroid Build Coastguard Worker if (VB2_SUCCESS != vb2_digest_info(hash_alg, &digestinfo,
76*8617a60dSAndroid Build Coastguard Worker &digestinfo_size)) {
77*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "SignatureBuf(): Couldn't get digest info\n");
78*8617a60dSAndroid Build Coastguard Worker free(signature_digest);
79*8617a60dSAndroid Build Coastguard Worker return NULL;
80*8617a60dSAndroid Build Coastguard Worker }
81*8617a60dSAndroid Build Coastguard Worker
82*8617a60dSAndroid Build Coastguard Worker int signature_digest_len = digest_size + digestinfo_size;
83*8617a60dSAndroid Build Coastguard Worker
84*8617a60dSAndroid Build Coastguard Worker key_fp = fopen(key_file, "r");
85*8617a60dSAndroid Build Coastguard Worker if (!key_fp) {
86*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "SignatureBuf(): Couldn't open key file: %s\n",
87*8617a60dSAndroid Build Coastguard Worker key_file);
88*8617a60dSAndroid Build Coastguard Worker free(signature_digest);
89*8617a60dSAndroid Build Coastguard Worker return NULL;
90*8617a60dSAndroid Build Coastguard Worker }
91*8617a60dSAndroid Build Coastguard Worker if ((key = PEM_read_RSAPrivateKey(key_fp, NULL, NULL, NULL)))
92*8617a60dSAndroid Build Coastguard Worker signature = (uint8_t *)malloc(
93*8617a60dSAndroid Build Coastguard Worker vb2_rsa_sig_size(vb2_crypto_to_signature(algorithm)));
94*8617a60dSAndroid Build Coastguard Worker else
95*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "SignatureBuf(): "
96*8617a60dSAndroid Build Coastguard Worker "Couldn't read private key from: %s\n", key_file);
97*8617a60dSAndroid Build Coastguard Worker if (signature) {
98*8617a60dSAndroid Build Coastguard Worker if (-1 == RSA_private_encrypt(
99*8617a60dSAndroid Build Coastguard Worker signature_digest_len, /* Input length. */
100*8617a60dSAndroid Build Coastguard Worker signature_digest, /* Input data. */
101*8617a60dSAndroid Build Coastguard Worker signature, /* Output signature. */
102*8617a60dSAndroid Build Coastguard Worker key, /* Key to use. */
103*8617a60dSAndroid Build Coastguard Worker RSA_PKCS1_PADDING)) /* Padding to use. */
104*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "SignatureBuf(): "
105*8617a60dSAndroid Build Coastguard Worker "RSA_private_encrypt() failed.\n");
106*8617a60dSAndroid Build Coastguard Worker }
107*8617a60dSAndroid Build Coastguard Worker fclose(key_fp);
108*8617a60dSAndroid Build Coastguard Worker if (key)
109*8617a60dSAndroid Build Coastguard Worker RSA_free(key);
110*8617a60dSAndroid Build Coastguard Worker free(signature_digest);
111*8617a60dSAndroid Build Coastguard Worker return signature;
112*8617a60dSAndroid Build Coastguard Worker }
113