xref: /OK3568_Linux_fs/kernel/security/integrity/digsig.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2011 Intel Corporation
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Author:
6*4882a593Smuzhiyun  * Dmitry Kasatkin <dmitry.kasatkin@intel.com>
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/err.h>
10*4882a593Smuzhiyun #include <linux/sched.h>
11*4882a593Smuzhiyun #include <linux/slab.h>
12*4882a593Smuzhiyun #include <linux/cred.h>
13*4882a593Smuzhiyun #include <linux/kernel_read_file.h>
14*4882a593Smuzhiyun #include <linux/key-type.h>
15*4882a593Smuzhiyun #include <linux/digsig.h>
16*4882a593Smuzhiyun #include <linux/vmalloc.h>
17*4882a593Smuzhiyun #include <crypto/public_key.h>
18*4882a593Smuzhiyun #include <keys/system_keyring.h>
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #include "integrity.h"
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun static struct key *keyring[INTEGRITY_KEYRING_MAX];
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = {
25*4882a593Smuzhiyun #ifndef CONFIG_INTEGRITY_TRUSTED_KEYRING
26*4882a593Smuzhiyun 	"_evm",
27*4882a593Smuzhiyun 	"_ima",
28*4882a593Smuzhiyun #else
29*4882a593Smuzhiyun 	".evm",
30*4882a593Smuzhiyun 	".ima",
31*4882a593Smuzhiyun #endif
32*4882a593Smuzhiyun 	".platform",
33*4882a593Smuzhiyun };
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
36*4882a593Smuzhiyun #define restrict_link_to_ima restrict_link_by_builtin_and_secondary_trusted
37*4882a593Smuzhiyun #else
38*4882a593Smuzhiyun #define restrict_link_to_ima restrict_link_by_builtin_trusted
39*4882a593Smuzhiyun #endif
40*4882a593Smuzhiyun 
integrity_keyring_from_id(const unsigned int id)41*4882a593Smuzhiyun static struct key *integrity_keyring_from_id(const unsigned int id)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun 	if (id >= INTEGRITY_KEYRING_MAX)
44*4882a593Smuzhiyun 		return ERR_PTR(-EINVAL);
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun 	if (!keyring[id]) {
47*4882a593Smuzhiyun 		keyring[id] =
48*4882a593Smuzhiyun 			request_key(&key_type_keyring, keyring_name[id], NULL);
49*4882a593Smuzhiyun 		if (IS_ERR(keyring[id])) {
50*4882a593Smuzhiyun 			int err = PTR_ERR(keyring[id]);
51*4882a593Smuzhiyun 			pr_err("no %s keyring: %d\n", keyring_name[id], err);
52*4882a593Smuzhiyun 			keyring[id] = NULL;
53*4882a593Smuzhiyun 			return ERR_PTR(err);
54*4882a593Smuzhiyun 		}
55*4882a593Smuzhiyun 	}
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun 	return keyring[id];
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun 
integrity_digsig_verify(const unsigned int id,const char * sig,int siglen,const char * digest,int digestlen)60*4882a593Smuzhiyun int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
61*4882a593Smuzhiyun 			    const char *digest, int digestlen)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun 	struct key *keyring;
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 	if (siglen < 2)
66*4882a593Smuzhiyun 		return -EINVAL;
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun 	keyring = integrity_keyring_from_id(id);
69*4882a593Smuzhiyun 	if (IS_ERR(keyring))
70*4882a593Smuzhiyun 		return PTR_ERR(keyring);
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 	switch (sig[1]) {
73*4882a593Smuzhiyun 	case 1:
74*4882a593Smuzhiyun 		/* v1 API expect signature without xattr type */
75*4882a593Smuzhiyun 		return digsig_verify(keyring, sig + 1, siglen - 1, digest,
76*4882a593Smuzhiyun 				     digestlen);
77*4882a593Smuzhiyun 	case 2:
78*4882a593Smuzhiyun 		return asymmetric_verify(keyring, sig, siglen, digest,
79*4882a593Smuzhiyun 					 digestlen);
80*4882a593Smuzhiyun 	}
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	return -EOPNOTSUPP;
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun 
integrity_modsig_verify(const unsigned int id,const struct modsig * modsig)85*4882a593Smuzhiyun int integrity_modsig_verify(const unsigned int id, const struct modsig *modsig)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun 	struct key *keyring;
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 	keyring = integrity_keyring_from_id(id);
90*4882a593Smuzhiyun 	if (IS_ERR(keyring))
91*4882a593Smuzhiyun 		return PTR_ERR(keyring);
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	return ima_modsig_verify(keyring, modsig);
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun 
__integrity_init_keyring(const unsigned int id,key_perm_t perm,struct key_restriction * restriction)96*4882a593Smuzhiyun static int __init __integrity_init_keyring(const unsigned int id,
97*4882a593Smuzhiyun 					   key_perm_t perm,
98*4882a593Smuzhiyun 					   struct key_restriction *restriction)
99*4882a593Smuzhiyun {
100*4882a593Smuzhiyun 	const struct cred *cred = current_cred();
101*4882a593Smuzhiyun 	int err = 0;
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0),
104*4882a593Smuzhiyun 				    KGIDT_INIT(0), cred, perm,
105*4882a593Smuzhiyun 				    KEY_ALLOC_NOT_IN_QUOTA, restriction, NULL);
106*4882a593Smuzhiyun 	if (IS_ERR(keyring[id])) {
107*4882a593Smuzhiyun 		err = PTR_ERR(keyring[id]);
108*4882a593Smuzhiyun 		pr_info("Can't allocate %s keyring (%d)\n",
109*4882a593Smuzhiyun 			keyring_name[id], err);
110*4882a593Smuzhiyun 		keyring[id] = NULL;
111*4882a593Smuzhiyun 	} else {
112*4882a593Smuzhiyun 		if (id == INTEGRITY_KEYRING_PLATFORM)
113*4882a593Smuzhiyun 			set_platform_trusted_keys(keyring[id]);
114*4882a593Smuzhiyun 	}
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	return err;
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun 
integrity_init_keyring(const unsigned int id)119*4882a593Smuzhiyun int __init integrity_init_keyring(const unsigned int id)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun 	struct key_restriction *restriction;
122*4882a593Smuzhiyun 	key_perm_t perm;
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW
125*4882a593Smuzhiyun 		| KEY_USR_READ | KEY_USR_SEARCH;
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	if (id == INTEGRITY_KEYRING_PLATFORM) {
128*4882a593Smuzhiyun 		restriction = NULL;
129*4882a593Smuzhiyun 		goto out;
130*4882a593Smuzhiyun 	}
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING))
133*4882a593Smuzhiyun 		return 0;
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 	restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL);
136*4882a593Smuzhiyun 	if (!restriction)
137*4882a593Smuzhiyun 		return -ENOMEM;
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	restriction->check = restrict_link_to_ima;
140*4882a593Smuzhiyun 	perm |= KEY_USR_WRITE;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun out:
143*4882a593Smuzhiyun 	return __integrity_init_keyring(id, perm, restriction);
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun 
integrity_add_key(const unsigned int id,const void * data,off_t size,key_perm_t perm)146*4882a593Smuzhiyun int __init integrity_add_key(const unsigned int id, const void *data,
147*4882a593Smuzhiyun 			     off_t size, key_perm_t perm)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun 	key_ref_t key;
150*4882a593Smuzhiyun 	int rc = 0;
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	if (!keyring[id])
153*4882a593Smuzhiyun 		return -EINVAL;
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	key = key_create_or_update(make_key_ref(keyring[id], 1), "asymmetric",
156*4882a593Smuzhiyun 				   NULL, data, size, perm,
157*4882a593Smuzhiyun 				   KEY_ALLOC_NOT_IN_QUOTA);
158*4882a593Smuzhiyun 	if (IS_ERR(key)) {
159*4882a593Smuzhiyun 		rc = PTR_ERR(key);
160*4882a593Smuzhiyun 		pr_err("Problem loading X.509 certificate %d\n", rc);
161*4882a593Smuzhiyun 	} else {
162*4882a593Smuzhiyun 		pr_notice("Loaded X.509 cert '%s'\n",
163*4882a593Smuzhiyun 			  key_ref_to_ptr(key)->description);
164*4882a593Smuzhiyun 		key_ref_put(key);
165*4882a593Smuzhiyun 	}
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	return rc;
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun 
integrity_load_x509(const unsigned int id,const char * path)171*4882a593Smuzhiyun int __init integrity_load_x509(const unsigned int id, const char *path)
172*4882a593Smuzhiyun {
173*4882a593Smuzhiyun 	void *data = NULL;
174*4882a593Smuzhiyun 	size_t size;
175*4882a593Smuzhiyun 	int rc;
176*4882a593Smuzhiyun 	key_perm_t perm;
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 	rc = kernel_read_file_from_path(path, 0, &data, INT_MAX, NULL,
179*4882a593Smuzhiyun 					READING_X509_CERTIFICATE);
180*4882a593Smuzhiyun 	if (rc < 0) {
181*4882a593Smuzhiyun 		pr_err("Unable to open file: %s (%d)", path, rc);
182*4882a593Smuzhiyun 		return rc;
183*4882a593Smuzhiyun 	}
184*4882a593Smuzhiyun 	size = rc;
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ;
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	pr_info("Loading X.509 certificate: %s\n", path);
189*4882a593Smuzhiyun 	rc = integrity_add_key(id, (const void *)data, size, perm);
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	vfree(data);
192*4882a593Smuzhiyun 	return rc;
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun 
integrity_load_cert(const unsigned int id,const char * source,const void * data,size_t len,key_perm_t perm)195*4882a593Smuzhiyun int __init integrity_load_cert(const unsigned int id, const char *source,
196*4882a593Smuzhiyun 			       const void *data, size_t len, key_perm_t perm)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun 	if (!data)
199*4882a593Smuzhiyun 		return -EINVAL;
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 	pr_info("Loading X.509 certificate: %s\n", source);
202*4882a593Smuzhiyun 	return integrity_add_key(id, data, len, perm);
203*4882a593Smuzhiyun }
204