xref: /aosp_15_r20/external/vboot_reference/host/lib/signature_digest.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
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