xref: /aosp_15_r20/external/kmod/libkmod/libkmod-signature.c (revision cc4ad7da8cefe208cb129ac2aa9a357c7c72deb2)
1*cc4ad7daSAndroid Build Coastguard Worker /*
2*cc4ad7daSAndroid Build Coastguard Worker  * libkmod - module signature display
3*cc4ad7daSAndroid Build Coastguard Worker  *
4*cc4ad7daSAndroid Build Coastguard Worker  * Copyright (C) 2013 Michal Marek, SUSE
5*cc4ad7daSAndroid Build Coastguard Worker  *
6*cc4ad7daSAndroid Build Coastguard Worker  * This library is free software; you can redistribute it and/or
7*cc4ad7daSAndroid Build Coastguard Worker  * modify it under the terms of the GNU Lesser General Public
8*cc4ad7daSAndroid Build Coastguard Worker  * License as published by the Free Software Foundation; either
9*cc4ad7daSAndroid Build Coastguard Worker  * version 2.1 of the License, or (at your option) any later version.
10*cc4ad7daSAndroid Build Coastguard Worker  *
11*cc4ad7daSAndroid Build Coastguard Worker  * This library is distributed in the hope that it will be useful,
12*cc4ad7daSAndroid Build Coastguard Worker  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*cc4ad7daSAndroid Build Coastguard Worker  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14*cc4ad7daSAndroid Build Coastguard Worker  * Lesser General Public License for more details.
15*cc4ad7daSAndroid Build Coastguard Worker  *
16*cc4ad7daSAndroid Build Coastguard Worker  * You should have received a copy of the GNU Lesser General Public
17*cc4ad7daSAndroid Build Coastguard Worker  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18*cc4ad7daSAndroid Build Coastguard Worker  */
19*cc4ad7daSAndroid Build Coastguard Worker 
20*cc4ad7daSAndroid Build Coastguard Worker #include <inttypes.h>
21*cc4ad7daSAndroid Build Coastguard Worker #ifdef ENABLE_OPENSSL
22*cc4ad7daSAndroid Build Coastguard Worker #include <openssl/pkcs7.h>
23*cc4ad7daSAndroid Build Coastguard Worker #include <openssl/ssl.h>
24*cc4ad7daSAndroid Build Coastguard Worker #endif
25*cc4ad7daSAndroid Build Coastguard Worker #include <stdio.h>
26*cc4ad7daSAndroid Build Coastguard Worker #include <stdlib.h>
27*cc4ad7daSAndroid Build Coastguard Worker #include <string.h>
28*cc4ad7daSAndroid Build Coastguard Worker 
29*cc4ad7daSAndroid Build Coastguard Worker #include <shared/missing.h>
30*cc4ad7daSAndroid Build Coastguard Worker #include <shared/util.h>
31*cc4ad7daSAndroid Build Coastguard Worker 
32*cc4ad7daSAndroid Build Coastguard Worker #include "libkmod-internal.h"
33*cc4ad7daSAndroid Build Coastguard Worker 
34*cc4ad7daSAndroid Build Coastguard Worker /* These types and tables were copied from the 3.7 kernel sources.
35*cc4ad7daSAndroid Build Coastguard Worker  * As this is just description of the signature format, it should not be
36*cc4ad7daSAndroid Build Coastguard Worker  * considered derived work (so libkmod can use the LGPL license).
37*cc4ad7daSAndroid Build Coastguard Worker  */
38*cc4ad7daSAndroid Build Coastguard Worker enum pkey_algo {
39*cc4ad7daSAndroid Build Coastguard Worker 	PKEY_ALGO_DSA,
40*cc4ad7daSAndroid Build Coastguard Worker 	PKEY_ALGO_RSA,
41*cc4ad7daSAndroid Build Coastguard Worker 	PKEY_ALGO__LAST
42*cc4ad7daSAndroid Build Coastguard Worker };
43*cc4ad7daSAndroid Build Coastguard Worker 
44*cc4ad7daSAndroid Build Coastguard Worker static const char *const pkey_algo[PKEY_ALGO__LAST] = {
45*cc4ad7daSAndroid Build Coastguard Worker 	[PKEY_ALGO_DSA]		= "DSA",
46*cc4ad7daSAndroid Build Coastguard Worker 	[PKEY_ALGO_RSA]		= "RSA",
47*cc4ad7daSAndroid Build Coastguard Worker };
48*cc4ad7daSAndroid Build Coastguard Worker 
49*cc4ad7daSAndroid Build Coastguard Worker enum pkey_hash_algo {
50*cc4ad7daSAndroid Build Coastguard Worker 	PKEY_HASH_MD4,
51*cc4ad7daSAndroid Build Coastguard Worker 	PKEY_HASH_MD5,
52*cc4ad7daSAndroid Build Coastguard Worker 	PKEY_HASH_SHA1,
53*cc4ad7daSAndroid Build Coastguard Worker 	PKEY_HASH_RIPE_MD_160,
54*cc4ad7daSAndroid Build Coastguard Worker 	PKEY_HASH_SHA256,
55*cc4ad7daSAndroid Build Coastguard Worker 	PKEY_HASH_SHA384,
56*cc4ad7daSAndroid Build Coastguard Worker 	PKEY_HASH_SHA512,
57*cc4ad7daSAndroid Build Coastguard Worker 	PKEY_HASH_SHA224,
58*cc4ad7daSAndroid Build Coastguard Worker 	PKEY_HASH_SM3,
59*cc4ad7daSAndroid Build Coastguard Worker 	PKEY_HASH__LAST
60*cc4ad7daSAndroid Build Coastguard Worker };
61*cc4ad7daSAndroid Build Coastguard Worker 
62*cc4ad7daSAndroid Build Coastguard Worker const char *const pkey_hash_algo[PKEY_HASH__LAST] = {
63*cc4ad7daSAndroid Build Coastguard Worker 	[PKEY_HASH_MD4]		= "md4",
64*cc4ad7daSAndroid Build Coastguard Worker 	[PKEY_HASH_MD5]		= "md5",
65*cc4ad7daSAndroid Build Coastguard Worker 	[PKEY_HASH_SHA1]	= "sha1",
66*cc4ad7daSAndroid Build Coastguard Worker 	[PKEY_HASH_RIPE_MD_160]	= "rmd160",
67*cc4ad7daSAndroid Build Coastguard Worker 	[PKEY_HASH_SHA256]	= "sha256",
68*cc4ad7daSAndroid Build Coastguard Worker 	[PKEY_HASH_SHA384]	= "sha384",
69*cc4ad7daSAndroid Build Coastguard Worker 	[PKEY_HASH_SHA512]	= "sha512",
70*cc4ad7daSAndroid Build Coastguard Worker 	[PKEY_HASH_SHA224]	= "sha224",
71*cc4ad7daSAndroid Build Coastguard Worker 	[PKEY_HASH_SM3]		= "sm3",
72*cc4ad7daSAndroid Build Coastguard Worker };
73*cc4ad7daSAndroid Build Coastguard Worker 
74*cc4ad7daSAndroid Build Coastguard Worker enum pkey_id_type {
75*cc4ad7daSAndroid Build Coastguard Worker 	PKEY_ID_PGP,		/* OpenPGP generated key ID */
76*cc4ad7daSAndroid Build Coastguard Worker 	PKEY_ID_X509,		/* X.509 arbitrary subjectKeyIdentifier */
77*cc4ad7daSAndroid Build Coastguard Worker 	PKEY_ID_PKCS7,		/* Signature in PKCS#7 message */
78*cc4ad7daSAndroid Build Coastguard Worker 	PKEY_ID_TYPE__LAST
79*cc4ad7daSAndroid Build Coastguard Worker };
80*cc4ad7daSAndroid Build Coastguard Worker 
81*cc4ad7daSAndroid Build Coastguard Worker const char *const pkey_id_type[PKEY_ID_TYPE__LAST] = {
82*cc4ad7daSAndroid Build Coastguard Worker 	[PKEY_ID_PGP]		= "PGP",
83*cc4ad7daSAndroid Build Coastguard Worker 	[PKEY_ID_X509]		= "X509",
84*cc4ad7daSAndroid Build Coastguard Worker 	[PKEY_ID_PKCS7]		= "PKCS#7",
85*cc4ad7daSAndroid Build Coastguard Worker };
86*cc4ad7daSAndroid Build Coastguard Worker 
87*cc4ad7daSAndroid Build Coastguard Worker /*
88*cc4ad7daSAndroid Build Coastguard Worker  * Module signature information block.
89*cc4ad7daSAndroid Build Coastguard Worker  */
90*cc4ad7daSAndroid Build Coastguard Worker struct module_signature {
91*cc4ad7daSAndroid Build Coastguard Worker 	uint8_t algo;        /* Public-key crypto algorithm [enum pkey_algo] */
92*cc4ad7daSAndroid Build Coastguard Worker 	uint8_t hash;        /* Digest algorithm [enum pkey_hash_algo] */
93*cc4ad7daSAndroid Build Coastguard Worker 	uint8_t id_type;     /* Key identifier type [enum pkey_id_type] */
94*cc4ad7daSAndroid Build Coastguard Worker 	uint8_t signer_len;  /* Length of signer's name */
95*cc4ad7daSAndroid Build Coastguard Worker 	uint8_t key_id_len;  /* Length of key identifier */
96*cc4ad7daSAndroid Build Coastguard Worker 	uint8_t __pad[3];
97*cc4ad7daSAndroid Build Coastguard Worker 	uint32_t sig_len;    /* Length of signature data (big endian) */
98*cc4ad7daSAndroid Build Coastguard Worker };
99*cc4ad7daSAndroid Build Coastguard Worker 
fill_default(const char * mem,off_t size,const struct module_signature * modsig,size_t sig_len,struct kmod_signature_info * sig_info)100*cc4ad7daSAndroid Build Coastguard Worker static bool fill_default(const char *mem, off_t size,
101*cc4ad7daSAndroid Build Coastguard Worker 			 const struct module_signature *modsig, size_t sig_len,
102*cc4ad7daSAndroid Build Coastguard Worker 			 struct kmod_signature_info *sig_info)
103*cc4ad7daSAndroid Build Coastguard Worker {
104*cc4ad7daSAndroid Build Coastguard Worker 	size -= sig_len;
105*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->sig = mem + size;
106*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->sig_len = sig_len;
107*cc4ad7daSAndroid Build Coastguard Worker 
108*cc4ad7daSAndroid Build Coastguard Worker 	size -= modsig->key_id_len;
109*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->key_id = mem + size;
110*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->key_id_len = modsig->key_id_len;
111*cc4ad7daSAndroid Build Coastguard Worker 
112*cc4ad7daSAndroid Build Coastguard Worker 	size -= modsig->signer_len;
113*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->signer = mem + size;
114*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->signer_len = modsig->signer_len;
115*cc4ad7daSAndroid Build Coastguard Worker 
116*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->algo = pkey_algo[modsig->algo];
117*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->hash_algo = pkey_hash_algo[modsig->hash];
118*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->id_type = pkey_id_type[modsig->id_type];
119*cc4ad7daSAndroid Build Coastguard Worker 
120*cc4ad7daSAndroid Build Coastguard Worker 	return true;
121*cc4ad7daSAndroid Build Coastguard Worker }
122*cc4ad7daSAndroid Build Coastguard Worker 
123*cc4ad7daSAndroid Build Coastguard Worker #ifdef ENABLE_OPENSSL
124*cc4ad7daSAndroid Build Coastguard Worker 
125*cc4ad7daSAndroid Build Coastguard Worker struct pkcs7_private {
126*cc4ad7daSAndroid Build Coastguard Worker 	PKCS7 *pkcs7;
127*cc4ad7daSAndroid Build Coastguard Worker 	unsigned char *key_id;
128*cc4ad7daSAndroid Build Coastguard Worker 	BIGNUM *sno;
129*cc4ad7daSAndroid Build Coastguard Worker 	char *hash_algo;
130*cc4ad7daSAndroid Build Coastguard Worker };
131*cc4ad7daSAndroid Build Coastguard Worker 
pkcs7_free(void * s)132*cc4ad7daSAndroid Build Coastguard Worker static void pkcs7_free(void *s)
133*cc4ad7daSAndroid Build Coastguard Worker {
134*cc4ad7daSAndroid Build Coastguard Worker 	struct kmod_signature_info *si = s;
135*cc4ad7daSAndroid Build Coastguard Worker 	struct pkcs7_private *pvt = si->private;
136*cc4ad7daSAndroid Build Coastguard Worker 
137*cc4ad7daSAndroid Build Coastguard Worker 	PKCS7_free(pvt->pkcs7);
138*cc4ad7daSAndroid Build Coastguard Worker 	BN_free(pvt->sno);
139*cc4ad7daSAndroid Build Coastguard Worker 	free(pvt->key_id);
140*cc4ad7daSAndroid Build Coastguard Worker 	free(pvt->hash_algo);
141*cc4ad7daSAndroid Build Coastguard Worker 	free(pvt);
142*cc4ad7daSAndroid Build Coastguard Worker 	si->private = NULL;
143*cc4ad7daSAndroid Build Coastguard Worker }
144*cc4ad7daSAndroid Build Coastguard Worker 
x509_name_to_str(X509_NAME * name)145*cc4ad7daSAndroid Build Coastguard Worker static const char *x509_name_to_str(X509_NAME *name)
146*cc4ad7daSAndroid Build Coastguard Worker {
147*cc4ad7daSAndroid Build Coastguard Worker 	int i;
148*cc4ad7daSAndroid Build Coastguard Worker 	X509_NAME_ENTRY *e;
149*cc4ad7daSAndroid Build Coastguard Worker 	ASN1_STRING *d;
150*cc4ad7daSAndroid Build Coastguard Worker 	ASN1_OBJECT *o;
151*cc4ad7daSAndroid Build Coastguard Worker 	int nid = -1;
152*cc4ad7daSAndroid Build Coastguard Worker 	const char *str;
153*cc4ad7daSAndroid Build Coastguard Worker 
154*cc4ad7daSAndroid Build Coastguard Worker 	for (i = 0; i < X509_NAME_entry_count(name); i++) {
155*cc4ad7daSAndroid Build Coastguard Worker 		e = X509_NAME_get_entry(name, i);
156*cc4ad7daSAndroid Build Coastguard Worker 		o = X509_NAME_ENTRY_get_object(e);
157*cc4ad7daSAndroid Build Coastguard Worker 		nid = OBJ_obj2nid(o);
158*cc4ad7daSAndroid Build Coastguard Worker 		if (nid == NID_commonName)
159*cc4ad7daSAndroid Build Coastguard Worker 			break;
160*cc4ad7daSAndroid Build Coastguard Worker 	}
161*cc4ad7daSAndroid Build Coastguard Worker 	if (nid == -1)
162*cc4ad7daSAndroid Build Coastguard Worker 		return NULL;
163*cc4ad7daSAndroid Build Coastguard Worker 
164*cc4ad7daSAndroid Build Coastguard Worker 	d = X509_NAME_ENTRY_get_data(e);
165*cc4ad7daSAndroid Build Coastguard Worker 	str = (const char *)ASN1_STRING_get0_data(d);
166*cc4ad7daSAndroid Build Coastguard Worker 
167*cc4ad7daSAndroid Build Coastguard Worker 	return str;
168*cc4ad7daSAndroid Build Coastguard Worker }
169*cc4ad7daSAndroid Build Coastguard Worker 
fill_pkcs7(const char * mem,off_t size,const struct module_signature * modsig,size_t sig_len,struct kmod_signature_info * sig_info)170*cc4ad7daSAndroid Build Coastguard Worker static bool fill_pkcs7(const char *mem, off_t size,
171*cc4ad7daSAndroid Build Coastguard Worker 		       const struct module_signature *modsig, size_t sig_len,
172*cc4ad7daSAndroid Build Coastguard Worker 		       struct kmod_signature_info *sig_info)
173*cc4ad7daSAndroid Build Coastguard Worker {
174*cc4ad7daSAndroid Build Coastguard Worker 	const char *pkcs7_raw;
175*cc4ad7daSAndroid Build Coastguard Worker 	PKCS7 *pkcs7;
176*cc4ad7daSAndroid Build Coastguard Worker 	STACK_OF(PKCS7_SIGNER_INFO) *sis;
177*cc4ad7daSAndroid Build Coastguard Worker 	PKCS7_SIGNER_INFO *si;
178*cc4ad7daSAndroid Build Coastguard Worker 	PKCS7_ISSUER_AND_SERIAL *is;
179*cc4ad7daSAndroid Build Coastguard Worker 	X509_NAME *issuer;
180*cc4ad7daSAndroid Build Coastguard Worker 	ASN1_INTEGER *sno;
181*cc4ad7daSAndroid Build Coastguard Worker 	ASN1_OCTET_STRING *sig;
182*cc4ad7daSAndroid Build Coastguard Worker 	BIGNUM *sno_bn;
183*cc4ad7daSAndroid Build Coastguard Worker 	X509_ALGOR *dig_alg;
184*cc4ad7daSAndroid Build Coastguard Worker 	X509_ALGOR *sig_alg;
185*cc4ad7daSAndroid Build Coastguard Worker 	const ASN1_OBJECT *o;
186*cc4ad7daSAndroid Build Coastguard Worker 	BIO *in;
187*cc4ad7daSAndroid Build Coastguard Worker 	int len;
188*cc4ad7daSAndroid Build Coastguard Worker 	unsigned char *key_id_str;
189*cc4ad7daSAndroid Build Coastguard Worker 	struct pkcs7_private *pvt;
190*cc4ad7daSAndroid Build Coastguard Worker 	const char *issuer_str;
191*cc4ad7daSAndroid Build Coastguard Worker 	char *hash_algo;
192*cc4ad7daSAndroid Build Coastguard Worker 	int hash_algo_len;
193*cc4ad7daSAndroid Build Coastguard Worker 
194*cc4ad7daSAndroid Build Coastguard Worker 	size -= sig_len;
195*cc4ad7daSAndroid Build Coastguard Worker 	pkcs7_raw = mem + size;
196*cc4ad7daSAndroid Build Coastguard Worker 
197*cc4ad7daSAndroid Build Coastguard Worker 	in = BIO_new_mem_buf(pkcs7_raw, sig_len);
198*cc4ad7daSAndroid Build Coastguard Worker 
199*cc4ad7daSAndroid Build Coastguard Worker 	pkcs7 = d2i_PKCS7_bio(in, NULL);
200*cc4ad7daSAndroid Build Coastguard Worker 	if (pkcs7 == NULL) {
201*cc4ad7daSAndroid Build Coastguard Worker 		BIO_free(in);
202*cc4ad7daSAndroid Build Coastguard Worker 		return false;
203*cc4ad7daSAndroid Build Coastguard Worker 	}
204*cc4ad7daSAndroid Build Coastguard Worker 
205*cc4ad7daSAndroid Build Coastguard Worker 	BIO_free(in);
206*cc4ad7daSAndroid Build Coastguard Worker 
207*cc4ad7daSAndroid Build Coastguard Worker 	sis = PKCS7_get_signer_info(pkcs7);
208*cc4ad7daSAndroid Build Coastguard Worker 	if (sis == NULL)
209*cc4ad7daSAndroid Build Coastguard Worker 		goto err;
210*cc4ad7daSAndroid Build Coastguard Worker 
211*cc4ad7daSAndroid Build Coastguard Worker 	si = sk_PKCS7_SIGNER_INFO_value(sis, 0);
212*cc4ad7daSAndroid Build Coastguard Worker 	if (si == NULL)
213*cc4ad7daSAndroid Build Coastguard Worker 		goto err;
214*cc4ad7daSAndroid Build Coastguard Worker 
215*cc4ad7daSAndroid Build Coastguard Worker 	is = si->issuer_and_serial;
216*cc4ad7daSAndroid Build Coastguard Worker 	if (is == NULL)
217*cc4ad7daSAndroid Build Coastguard Worker 		goto err;
218*cc4ad7daSAndroid Build Coastguard Worker 	issuer = is->issuer;
219*cc4ad7daSAndroid Build Coastguard Worker 	sno = is->serial;
220*cc4ad7daSAndroid Build Coastguard Worker 
221*cc4ad7daSAndroid Build Coastguard Worker 	sig = si->enc_digest;
222*cc4ad7daSAndroid Build Coastguard Worker 	if (sig == NULL)
223*cc4ad7daSAndroid Build Coastguard Worker 		goto err;
224*cc4ad7daSAndroid Build Coastguard Worker 
225*cc4ad7daSAndroid Build Coastguard Worker 	PKCS7_SIGNER_INFO_get0_algs(si, NULL, &dig_alg, &sig_alg);
226*cc4ad7daSAndroid Build Coastguard Worker 
227*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->sig = (const char *)ASN1_STRING_get0_data(sig);
228*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->sig_len = ASN1_STRING_length(sig);
229*cc4ad7daSAndroid Build Coastguard Worker 
230*cc4ad7daSAndroid Build Coastguard Worker 	sno_bn = ASN1_INTEGER_to_BN(sno, NULL);
231*cc4ad7daSAndroid Build Coastguard Worker 	if (sno_bn == NULL)
232*cc4ad7daSAndroid Build Coastguard Worker 		goto err;
233*cc4ad7daSAndroid Build Coastguard Worker 
234*cc4ad7daSAndroid Build Coastguard Worker 	len = BN_num_bytes(sno_bn);
235*cc4ad7daSAndroid Build Coastguard Worker 	key_id_str = malloc(len);
236*cc4ad7daSAndroid Build Coastguard Worker 	if (key_id_str == NULL)
237*cc4ad7daSAndroid Build Coastguard Worker 		goto err2;
238*cc4ad7daSAndroid Build Coastguard Worker 	BN_bn2bin(sno_bn, key_id_str);
239*cc4ad7daSAndroid Build Coastguard Worker 
240*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->key_id = (const char *)key_id_str;
241*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->key_id_len = len;
242*cc4ad7daSAndroid Build Coastguard Worker 
243*cc4ad7daSAndroid Build Coastguard Worker 	issuer_str = x509_name_to_str(issuer);
244*cc4ad7daSAndroid Build Coastguard Worker 	if (issuer_str != NULL) {
245*cc4ad7daSAndroid Build Coastguard Worker 		sig_info->signer = issuer_str;
246*cc4ad7daSAndroid Build Coastguard Worker 		sig_info->signer_len = strlen(issuer_str);
247*cc4ad7daSAndroid Build Coastguard Worker 	}
248*cc4ad7daSAndroid Build Coastguard Worker 
249*cc4ad7daSAndroid Build Coastguard Worker 	X509_ALGOR_get0(&o, NULL, NULL, dig_alg);
250*cc4ad7daSAndroid Build Coastguard Worker 
251*cc4ad7daSAndroid Build Coastguard Worker 	// Use OBJ_obj2txt to calculate string length
252*cc4ad7daSAndroid Build Coastguard Worker 	hash_algo_len = OBJ_obj2txt(NULL, 0, o, 0);
253*cc4ad7daSAndroid Build Coastguard Worker 	if (hash_algo_len < 0)
254*cc4ad7daSAndroid Build Coastguard Worker 		goto err3;
255*cc4ad7daSAndroid Build Coastguard Worker 	hash_algo = malloc(hash_algo_len + 1);
256*cc4ad7daSAndroid Build Coastguard Worker 	if (hash_algo == NULL)
257*cc4ad7daSAndroid Build Coastguard Worker 		goto err3;
258*cc4ad7daSAndroid Build Coastguard Worker 	hash_algo_len = OBJ_obj2txt(hash_algo, hash_algo_len + 1, o, 0);
259*cc4ad7daSAndroid Build Coastguard Worker 	if (hash_algo_len < 0)
260*cc4ad7daSAndroid Build Coastguard Worker 		goto err4;
261*cc4ad7daSAndroid Build Coastguard Worker 
262*cc4ad7daSAndroid Build Coastguard Worker 	// Assign libcrypto hash algo string or number
263*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->hash_algo = hash_algo;
264*cc4ad7daSAndroid Build Coastguard Worker 
265*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->id_type = pkey_id_type[modsig->id_type];
266*cc4ad7daSAndroid Build Coastguard Worker 
267*cc4ad7daSAndroid Build Coastguard Worker 	pvt = malloc(sizeof(*pvt));
268*cc4ad7daSAndroid Build Coastguard Worker 	if (pvt == NULL)
269*cc4ad7daSAndroid Build Coastguard Worker 		goto err4;
270*cc4ad7daSAndroid Build Coastguard Worker 
271*cc4ad7daSAndroid Build Coastguard Worker 	pvt->pkcs7 = pkcs7;
272*cc4ad7daSAndroid Build Coastguard Worker 	pvt->key_id = key_id_str;
273*cc4ad7daSAndroid Build Coastguard Worker 	pvt->sno = sno_bn;
274*cc4ad7daSAndroid Build Coastguard Worker 	pvt->hash_algo = hash_algo;
275*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->private = pvt;
276*cc4ad7daSAndroid Build Coastguard Worker 
277*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->free = pkcs7_free;
278*cc4ad7daSAndroid Build Coastguard Worker 
279*cc4ad7daSAndroid Build Coastguard Worker 	return true;
280*cc4ad7daSAndroid Build Coastguard Worker err4:
281*cc4ad7daSAndroid Build Coastguard Worker 	free(hash_algo);
282*cc4ad7daSAndroid Build Coastguard Worker err3:
283*cc4ad7daSAndroid Build Coastguard Worker 	free(key_id_str);
284*cc4ad7daSAndroid Build Coastguard Worker err2:
285*cc4ad7daSAndroid Build Coastguard Worker 	BN_free(sno_bn);
286*cc4ad7daSAndroid Build Coastguard Worker err:
287*cc4ad7daSAndroid Build Coastguard Worker 	PKCS7_free(pkcs7);
288*cc4ad7daSAndroid Build Coastguard Worker 	return false;
289*cc4ad7daSAndroid Build Coastguard Worker }
290*cc4ad7daSAndroid Build Coastguard Worker 
291*cc4ad7daSAndroid Build Coastguard Worker #else /* ENABLE OPENSSL */
292*cc4ad7daSAndroid Build Coastguard Worker 
fill_pkcs7(const char * mem,off_t size,const struct module_signature * modsig,size_t sig_len,struct kmod_signature_info * sig_info)293*cc4ad7daSAndroid Build Coastguard Worker static bool fill_pkcs7(const char *mem, off_t size,
294*cc4ad7daSAndroid Build Coastguard Worker 		       const struct module_signature *modsig, size_t sig_len,
295*cc4ad7daSAndroid Build Coastguard Worker 		       struct kmod_signature_info *sig_info)
296*cc4ad7daSAndroid Build Coastguard Worker {
297*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->hash_algo = "unknown";
298*cc4ad7daSAndroid Build Coastguard Worker 	sig_info->id_type = pkey_id_type[modsig->id_type];
299*cc4ad7daSAndroid Build Coastguard Worker 	return true;
300*cc4ad7daSAndroid Build Coastguard Worker }
301*cc4ad7daSAndroid Build Coastguard Worker 
302*cc4ad7daSAndroid Build Coastguard Worker #endif /* ENABLE OPENSSL */
303*cc4ad7daSAndroid Build Coastguard Worker 
304*cc4ad7daSAndroid Build Coastguard Worker #define SIG_MAGIC "~Module signature appended~\n"
305*cc4ad7daSAndroid Build Coastguard Worker 
306*cc4ad7daSAndroid Build Coastguard Worker /*
307*cc4ad7daSAndroid Build Coastguard Worker  * A signed module has the following layout:
308*cc4ad7daSAndroid Build Coastguard Worker  *
309*cc4ad7daSAndroid Build Coastguard Worker  * [ module                  ]
310*cc4ad7daSAndroid Build Coastguard Worker  * [ signer's name           ]
311*cc4ad7daSAndroid Build Coastguard Worker  * [ key identifier          ]
312*cc4ad7daSAndroid Build Coastguard Worker  * [ signature data          ]
313*cc4ad7daSAndroid Build Coastguard Worker  * [ struct module_signature ]
314*cc4ad7daSAndroid Build Coastguard Worker  * [ SIG_MAGIC               ]
315*cc4ad7daSAndroid Build Coastguard Worker  */
316*cc4ad7daSAndroid Build Coastguard Worker 
kmod_module_signature_info(const struct kmod_file * file,struct kmod_signature_info * sig_info)317*cc4ad7daSAndroid Build Coastguard Worker bool kmod_module_signature_info(const struct kmod_file *file, struct kmod_signature_info *sig_info)
318*cc4ad7daSAndroid Build Coastguard Worker {
319*cc4ad7daSAndroid Build Coastguard Worker 	const char *mem;
320*cc4ad7daSAndroid Build Coastguard Worker 	off_t size;
321*cc4ad7daSAndroid Build Coastguard Worker 	const struct module_signature *modsig;
322*cc4ad7daSAndroid Build Coastguard Worker 	size_t sig_len;
323*cc4ad7daSAndroid Build Coastguard Worker 
324*cc4ad7daSAndroid Build Coastguard Worker 	size = kmod_file_get_size(file);
325*cc4ad7daSAndroid Build Coastguard Worker 	mem = kmod_file_get_contents(file);
326*cc4ad7daSAndroid Build Coastguard Worker 	if (size < (off_t)strlen(SIG_MAGIC))
327*cc4ad7daSAndroid Build Coastguard Worker 		return false;
328*cc4ad7daSAndroid Build Coastguard Worker 	size -= strlen(SIG_MAGIC);
329*cc4ad7daSAndroid Build Coastguard Worker 	if (memcmp(SIG_MAGIC, mem + size, strlen(SIG_MAGIC)) != 0)
330*cc4ad7daSAndroid Build Coastguard Worker 		return false;
331*cc4ad7daSAndroid Build Coastguard Worker 
332*cc4ad7daSAndroid Build Coastguard Worker 	if (size < (off_t)sizeof(struct module_signature))
333*cc4ad7daSAndroid Build Coastguard Worker 		return false;
334*cc4ad7daSAndroid Build Coastguard Worker 	size -= sizeof(struct module_signature);
335*cc4ad7daSAndroid Build Coastguard Worker 	modsig = (struct module_signature *)(mem + size);
336*cc4ad7daSAndroid Build Coastguard Worker 	if (modsig->algo >= PKEY_ALGO__LAST ||
337*cc4ad7daSAndroid Build Coastguard Worker 			modsig->hash >= PKEY_HASH__LAST ||
338*cc4ad7daSAndroid Build Coastguard Worker 			modsig->id_type >= PKEY_ID_TYPE__LAST)
339*cc4ad7daSAndroid Build Coastguard Worker 		return false;
340*cc4ad7daSAndroid Build Coastguard Worker 	sig_len = be32toh(get_unaligned(&modsig->sig_len));
341*cc4ad7daSAndroid Build Coastguard Worker 	if (sig_len == 0 ||
342*cc4ad7daSAndroid Build Coastguard Worker 	    size < (int64_t)(modsig->signer_len + modsig->key_id_len + sig_len))
343*cc4ad7daSAndroid Build Coastguard Worker 		return false;
344*cc4ad7daSAndroid Build Coastguard Worker 
345*cc4ad7daSAndroid Build Coastguard Worker 	switch (modsig->id_type) {
346*cc4ad7daSAndroid Build Coastguard Worker 	case PKEY_ID_PKCS7:
347*cc4ad7daSAndroid Build Coastguard Worker 		return fill_pkcs7(mem, size, modsig, sig_len, sig_info);
348*cc4ad7daSAndroid Build Coastguard Worker 	default:
349*cc4ad7daSAndroid Build Coastguard Worker 		return fill_default(mem, size, modsig, sig_len, sig_info);
350*cc4ad7daSAndroid Build Coastguard Worker 	}
351*cc4ad7daSAndroid Build Coastguard Worker }
352*cc4ad7daSAndroid Build Coastguard Worker 
kmod_module_signature_info_free(struct kmod_signature_info * sig_info)353*cc4ad7daSAndroid Build Coastguard Worker void kmod_module_signature_info_free(struct kmod_signature_info *sig_info)
354*cc4ad7daSAndroid Build Coastguard Worker {
355*cc4ad7daSAndroid Build Coastguard Worker 	if (sig_info->free)
356*cc4ad7daSAndroid Build Coastguard Worker 		sig_info->free(sig_info);
357*cc4ad7daSAndroid Build Coastguard Worker }
358