Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/security/keys/trusted-keys/trusted_core.c
26442 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* Copyright (C) 2010 IBM Corporation
4
* Copyright (c) 2019-2021, Linaro Limited
5
*
6
* See Documentation/security/keys/trusted-encrypted.rst
7
*/
8
9
#include <keys/user-type.h>
10
#include <keys/trusted-type.h>
11
#include <keys/trusted_tee.h>
12
#include <keys/trusted_caam.h>
13
#include <keys/trusted_dcp.h>
14
#include <keys/trusted_tpm.h>
15
#include <linux/capability.h>
16
#include <linux/err.h>
17
#include <linux/init.h>
18
#include <linux/key-type.h>
19
#include <linux/module.h>
20
#include <linux/parser.h>
21
#include <linux/random.h>
22
#include <linux/rcupdate.h>
23
#include <linux/slab.h>
24
#include <linux/static_call.h>
25
#include <linux/string.h>
26
#include <linux/uaccess.h>
27
28
static char *trusted_rng = "default";
29
module_param_named(rng, trusted_rng, charp, 0);
30
MODULE_PARM_DESC(rng, "Select trusted key RNG");
31
32
static char *trusted_key_source;
33
module_param_named(source, trusted_key_source, charp, 0);
34
MODULE_PARM_DESC(source, "Select trusted keys source (tpm, tee, caam or dcp)");
35
36
static const struct trusted_key_source trusted_key_sources[] = {
37
#if defined(CONFIG_TRUSTED_KEYS_TPM)
38
{ "tpm", &trusted_key_tpm_ops },
39
#endif
40
#if defined(CONFIG_TRUSTED_KEYS_TEE)
41
{ "tee", &trusted_key_tee_ops },
42
#endif
43
#if defined(CONFIG_TRUSTED_KEYS_CAAM)
44
{ "caam", &trusted_key_caam_ops },
45
#endif
46
#if defined(CONFIG_TRUSTED_KEYS_DCP)
47
{ "dcp", &dcp_trusted_key_ops },
48
#endif
49
};
50
51
DEFINE_STATIC_CALL_NULL(trusted_key_seal, *trusted_key_sources[0].ops->seal);
52
DEFINE_STATIC_CALL_NULL(trusted_key_unseal,
53
*trusted_key_sources[0].ops->unseal);
54
DEFINE_STATIC_CALL_NULL(trusted_key_get_random,
55
*trusted_key_sources[0].ops->get_random);
56
static void (*trusted_key_exit)(void);
57
static unsigned char migratable;
58
59
enum {
60
Opt_err,
61
Opt_new, Opt_load, Opt_update,
62
};
63
64
static const match_table_t key_tokens = {
65
{Opt_new, "new"},
66
{Opt_load, "load"},
67
{Opt_update, "update"},
68
{Opt_err, NULL}
69
};
70
71
/*
72
* datablob_parse - parse the keyctl data and fill in the
73
* payload structure
74
*
75
* On success returns 0, otherwise -EINVAL.
76
*/
77
static int datablob_parse(char **datablob, struct trusted_key_payload *p)
78
{
79
substring_t args[MAX_OPT_ARGS];
80
long keylen;
81
int ret = -EINVAL;
82
int key_cmd;
83
char *c;
84
85
/* main command */
86
c = strsep(datablob, " \t");
87
if (!c)
88
return -EINVAL;
89
key_cmd = match_token(c, key_tokens, args);
90
switch (key_cmd) {
91
case Opt_new:
92
/* first argument is key size */
93
c = strsep(datablob, " \t");
94
if (!c)
95
return -EINVAL;
96
ret = kstrtol(c, 10, &keylen);
97
if (ret < 0 || keylen < MIN_KEY_SIZE || keylen > MAX_KEY_SIZE)
98
return -EINVAL;
99
p->key_len = keylen;
100
ret = Opt_new;
101
break;
102
case Opt_load:
103
/* first argument is sealed blob */
104
c = strsep(datablob, " \t");
105
if (!c)
106
return -EINVAL;
107
p->blob_len = strlen(c) / 2;
108
if (p->blob_len > MAX_BLOB_SIZE)
109
return -EINVAL;
110
ret = hex2bin(p->blob, c, p->blob_len);
111
if (ret < 0)
112
return -EINVAL;
113
ret = Opt_load;
114
break;
115
case Opt_update:
116
ret = Opt_update;
117
break;
118
case Opt_err:
119
return -EINVAL;
120
}
121
return ret;
122
}
123
124
static struct trusted_key_payload *trusted_payload_alloc(struct key *key)
125
{
126
struct trusted_key_payload *p = NULL;
127
int ret;
128
129
ret = key_payload_reserve(key, sizeof(*p));
130
if (ret < 0)
131
goto err;
132
p = kzalloc(sizeof(*p), GFP_KERNEL);
133
if (!p)
134
goto err;
135
136
p->migratable = migratable;
137
err:
138
return p;
139
}
140
141
/*
142
* trusted_instantiate - create a new trusted key
143
*
144
* Unseal an existing trusted blob or, for a new key, get a
145
* random key, then seal and create a trusted key-type key,
146
* adding it to the specified keyring.
147
*
148
* On success, return 0. Otherwise return errno.
149
*/
150
static int trusted_instantiate(struct key *key,
151
struct key_preparsed_payload *prep)
152
{
153
struct trusted_key_payload *payload = NULL;
154
size_t datalen = prep->datalen;
155
char *datablob, *orig_datablob;
156
int ret = 0;
157
int key_cmd;
158
size_t key_len;
159
160
if (datalen <= 0 || datalen > 32767 || !prep->data)
161
return -EINVAL;
162
163
orig_datablob = datablob = kmalloc(datalen + 1, GFP_KERNEL);
164
if (!datablob)
165
return -ENOMEM;
166
memcpy(datablob, prep->data, datalen);
167
datablob[datalen] = '\0';
168
169
payload = trusted_payload_alloc(key);
170
if (!payload) {
171
ret = -ENOMEM;
172
goto out;
173
}
174
175
key_cmd = datablob_parse(&datablob, payload);
176
if (key_cmd < 0) {
177
ret = key_cmd;
178
goto out;
179
}
180
181
dump_payload(payload);
182
183
switch (key_cmd) {
184
case Opt_load:
185
ret = static_call(trusted_key_unseal)(payload, datablob);
186
dump_payload(payload);
187
if (ret < 0)
188
pr_info("key_unseal failed (%d)\n", ret);
189
break;
190
case Opt_new:
191
key_len = payload->key_len;
192
ret = static_call(trusted_key_get_random)(payload->key,
193
key_len);
194
if (ret < 0)
195
goto out;
196
197
if (ret != key_len) {
198
pr_info("key_create failed (%d)\n", ret);
199
ret = -EIO;
200
goto out;
201
}
202
203
ret = static_call(trusted_key_seal)(payload, datablob);
204
if (ret < 0)
205
pr_info("key_seal failed (%d)\n", ret);
206
break;
207
default:
208
ret = -EINVAL;
209
}
210
out:
211
kfree_sensitive(orig_datablob);
212
if (!ret)
213
rcu_assign_keypointer(key, payload);
214
else
215
kfree_sensitive(payload);
216
return ret;
217
}
218
219
static void trusted_rcu_free(struct rcu_head *rcu)
220
{
221
struct trusted_key_payload *p;
222
223
p = container_of(rcu, struct trusted_key_payload, rcu);
224
kfree_sensitive(p);
225
}
226
227
/*
228
* trusted_update - reseal an existing key with new PCR values
229
*/
230
static int trusted_update(struct key *key, struct key_preparsed_payload *prep)
231
{
232
struct trusted_key_payload *p;
233
struct trusted_key_payload *new_p;
234
size_t datalen = prep->datalen;
235
char *datablob, *orig_datablob;
236
int ret = 0;
237
238
if (key_is_negative(key))
239
return -ENOKEY;
240
p = key->payload.data[0];
241
if (!p->migratable)
242
return -EPERM;
243
if (datalen <= 0 || datalen > 32767 || !prep->data)
244
return -EINVAL;
245
246
orig_datablob = datablob = kmalloc(datalen + 1, GFP_KERNEL);
247
if (!datablob)
248
return -ENOMEM;
249
250
new_p = trusted_payload_alloc(key);
251
if (!new_p) {
252
ret = -ENOMEM;
253
goto out;
254
}
255
256
memcpy(datablob, prep->data, datalen);
257
datablob[datalen] = '\0';
258
ret = datablob_parse(&datablob, new_p);
259
if (ret != Opt_update) {
260
ret = -EINVAL;
261
kfree_sensitive(new_p);
262
goto out;
263
}
264
265
/* copy old key values, and reseal with new pcrs */
266
new_p->migratable = p->migratable;
267
new_p->key_len = p->key_len;
268
memcpy(new_p->key, p->key, p->key_len);
269
dump_payload(p);
270
dump_payload(new_p);
271
272
ret = static_call(trusted_key_seal)(new_p, datablob);
273
if (ret < 0) {
274
pr_info("key_seal failed (%d)\n", ret);
275
kfree_sensitive(new_p);
276
goto out;
277
}
278
279
rcu_assign_keypointer(key, new_p);
280
call_rcu(&p->rcu, trusted_rcu_free);
281
out:
282
kfree_sensitive(orig_datablob);
283
return ret;
284
}
285
286
/*
287
* trusted_read - copy the sealed blob data to userspace in hex.
288
* On success, return to userspace the trusted key datablob size.
289
*/
290
static long trusted_read(const struct key *key, char *buffer,
291
size_t buflen)
292
{
293
const struct trusted_key_payload *p;
294
char *bufp;
295
int i;
296
297
p = dereference_key_locked(key);
298
if (!p)
299
return -EINVAL;
300
301
if (buffer && buflen >= 2 * p->blob_len) {
302
bufp = buffer;
303
for (i = 0; i < p->blob_len; i++)
304
bufp = hex_byte_pack(bufp, p->blob[i]);
305
}
306
return 2 * p->blob_len;
307
}
308
309
/*
310
* trusted_destroy - clear and free the key's payload
311
*/
312
static void trusted_destroy(struct key *key)
313
{
314
kfree_sensitive(key->payload.data[0]);
315
}
316
317
struct key_type key_type_trusted = {
318
.name = "trusted",
319
.instantiate = trusted_instantiate,
320
.update = trusted_update,
321
.destroy = trusted_destroy,
322
.describe = user_describe,
323
.read = trusted_read,
324
};
325
EXPORT_SYMBOL_GPL(key_type_trusted);
326
327
static int kernel_get_random(unsigned char *key, size_t key_len)
328
{
329
return get_random_bytes_wait(key, key_len) ?: key_len;
330
}
331
332
static int __init init_trusted(void)
333
{
334
int (*get_random)(unsigned char *key, size_t key_len);
335
int i, ret = 0;
336
337
for (i = 0; i < ARRAY_SIZE(trusted_key_sources); i++) {
338
if (trusted_key_source &&
339
strncmp(trusted_key_source, trusted_key_sources[i].name,
340
strlen(trusted_key_sources[i].name)))
341
continue;
342
343
/*
344
* We always support trusted.rng="kernel" and "default" as
345
* well as trusted.rng=$trusted.source if the trust source
346
* defines its own get_random callback.
347
*/
348
get_random = trusted_key_sources[i].ops->get_random;
349
if (trusted_rng && strcmp(trusted_rng, "default")) {
350
if (!strcmp(trusted_rng, "kernel")) {
351
get_random = kernel_get_random;
352
} else if (strcmp(trusted_rng, trusted_key_sources[i].name) ||
353
!get_random) {
354
pr_warn("Unsupported RNG. Supported: kernel");
355
if (get_random)
356
pr_cont(", %s", trusted_key_sources[i].name);
357
pr_cont(", default\n");
358
return -EINVAL;
359
}
360
}
361
362
if (!get_random)
363
get_random = kernel_get_random;
364
365
ret = trusted_key_sources[i].ops->init();
366
if (!ret) {
367
static_call_update(trusted_key_seal, trusted_key_sources[i].ops->seal);
368
static_call_update(trusted_key_unseal, trusted_key_sources[i].ops->unseal);
369
static_call_update(trusted_key_get_random, get_random);
370
371
trusted_key_exit = trusted_key_sources[i].ops->exit;
372
migratable = trusted_key_sources[i].ops->migratable;
373
}
374
375
if (!ret || ret != -ENODEV)
376
break;
377
}
378
379
/*
380
* encrypted_keys.ko depends on successful load of this module even if
381
* trusted key implementation is not found.
382
*/
383
if (ret == -ENODEV)
384
return 0;
385
386
return ret;
387
}
388
389
static void __exit cleanup_trusted(void)
390
{
391
if (trusted_key_exit)
392
(*trusted_key_exit)();
393
}
394
395
late_initcall(init_trusted);
396
module_exit(cleanup_trusted);
397
398
MODULE_DESCRIPTION("Trusted Key type");
399
MODULE_LICENSE("GPL");
400
401