Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/security/keys/trusted-keys/trusted_tpm2.c
50904 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* Copyright (C) 2004 IBM Corporation
4
* Copyright (C) 2014 Intel Corporation
5
*/
6
7
#include <linux/asn1_encoder.h>
8
#include <linux/oid_registry.h>
9
#include <linux/string.h>
10
#include <linux/err.h>
11
#include <linux/tpm.h>
12
#include <linux/tpm_command.h>
13
14
#include <keys/trusted-type.h>
15
#include <keys/trusted_tpm.h>
16
17
#include <linux/unaligned.h>
18
19
#include "tpm2key.asn1.h"
20
21
static u32 tpm2key_oid[] = { 2, 23, 133, 10, 1, 5 };
22
23
static int tpm2_key_encode(struct trusted_key_payload *payload,
24
struct trusted_key_options *options,
25
u8 *src, u32 len)
26
{
27
const int SCRATCH_SIZE = PAGE_SIZE;
28
u8 *scratch = kmalloc(SCRATCH_SIZE, GFP_KERNEL);
29
u8 *work = scratch, *work1;
30
u8 *end_work = scratch + SCRATCH_SIZE;
31
u8 *priv, *pub;
32
u16 priv_len, pub_len;
33
int ret;
34
35
priv_len = get_unaligned_be16(src) + 2;
36
priv = src;
37
38
src += priv_len;
39
40
pub_len = get_unaligned_be16(src) + 2;
41
pub = src;
42
43
if (!scratch)
44
return -ENOMEM;
45
46
work = asn1_encode_oid(work, end_work, tpm2key_oid,
47
asn1_oid_len(tpm2key_oid));
48
49
if (options->blobauth_len == 0) {
50
unsigned char bool[3], *w = bool;
51
/* tag 0 is emptyAuth */
52
w = asn1_encode_boolean(w, w + sizeof(bool), true);
53
if (WARN(IS_ERR(w), "BUG: Boolean failed to encode")) {
54
ret = PTR_ERR(w);
55
goto err;
56
}
57
work = asn1_encode_tag(work, end_work, 0, bool, w - bool);
58
}
59
60
/*
61
* Assume both octet strings will encode to a 2 byte definite length
62
*
63
* Note: For a well behaved TPM, this warning should never
64
* trigger, so if it does there's something nefarious going on
65
*/
66
if (WARN(work - scratch + pub_len + priv_len + 14 > SCRATCH_SIZE,
67
"BUG: scratch buffer is too small")) {
68
ret = -EINVAL;
69
goto err;
70
}
71
72
work = asn1_encode_integer(work, end_work, options->keyhandle);
73
work = asn1_encode_octet_string(work, end_work, pub, pub_len);
74
work = asn1_encode_octet_string(work, end_work, priv, priv_len);
75
76
work1 = payload->blob;
77
work1 = asn1_encode_sequence(work1, work1 + sizeof(payload->blob),
78
scratch, work - scratch);
79
if (IS_ERR(work1)) {
80
ret = PTR_ERR(work1);
81
pr_err("BUG: ASN.1 encoder failed with %d\n", ret);
82
goto err;
83
}
84
85
kfree(scratch);
86
return work1 - payload->blob;
87
88
err:
89
kfree(scratch);
90
return ret;
91
}
92
93
struct tpm2_key_context {
94
u32 parent;
95
const u8 *pub;
96
u32 pub_len;
97
const u8 *priv;
98
u32 priv_len;
99
};
100
101
static int tpm2_key_decode(struct trusted_key_payload *payload,
102
struct trusted_key_options *options,
103
u8 **buf)
104
{
105
int ret;
106
struct tpm2_key_context ctx;
107
u8 *blob;
108
109
memset(&ctx, 0, sizeof(ctx));
110
111
ret = asn1_ber_decoder(&tpm2key_decoder, &ctx, payload->blob,
112
payload->blob_len);
113
if (ret < 0)
114
return ret;
115
116
if (ctx.priv_len + ctx.pub_len > MAX_BLOB_SIZE)
117
return -EINVAL;
118
119
blob = kmalloc(ctx.priv_len + ctx.pub_len + 4, GFP_KERNEL);
120
if (!blob)
121
return -ENOMEM;
122
123
*buf = blob;
124
options->keyhandle = ctx.parent;
125
126
memcpy(blob, ctx.priv, ctx.priv_len);
127
blob += ctx.priv_len;
128
129
memcpy(blob, ctx.pub, ctx.pub_len);
130
131
return 0;
132
}
133
134
int tpm2_key_parent(void *context, size_t hdrlen,
135
unsigned char tag,
136
const void *value, size_t vlen)
137
{
138
struct tpm2_key_context *ctx = context;
139
const u8 *v = value;
140
int i;
141
142
ctx->parent = 0;
143
for (i = 0; i < vlen; i++) {
144
ctx->parent <<= 8;
145
ctx->parent |= v[i];
146
}
147
148
return 0;
149
}
150
151
int tpm2_key_type(void *context, size_t hdrlen,
152
unsigned char tag,
153
const void *value, size_t vlen)
154
{
155
enum OID oid = look_up_OID(value, vlen);
156
157
if (oid != OID_TPMSealedData) {
158
char buffer[50];
159
160
sprint_oid(value, vlen, buffer, sizeof(buffer));
161
pr_debug("OID is \"%s\" which is not TPMSealedData\n",
162
buffer);
163
return -EINVAL;
164
}
165
166
return 0;
167
}
168
169
int tpm2_key_pub(void *context, size_t hdrlen,
170
unsigned char tag,
171
const void *value, size_t vlen)
172
{
173
struct tpm2_key_context *ctx = context;
174
175
ctx->pub = value;
176
ctx->pub_len = vlen;
177
178
return 0;
179
}
180
181
int tpm2_key_priv(void *context, size_t hdrlen,
182
unsigned char tag,
183
const void *value, size_t vlen)
184
{
185
struct tpm2_key_context *ctx = context;
186
187
ctx->priv = value;
188
ctx->priv_len = vlen;
189
190
return 0;
191
}
192
193
/**
194
* tpm2_buf_append_auth() - append TPMS_AUTH_COMMAND to the buffer.
195
*
196
* @buf: an allocated tpm_buf instance
197
* @session_handle: session handle
198
* @nonce: the session nonce, may be NULL if not used
199
* @nonce_len: the session nonce length, may be 0 if not used
200
* @attributes: the session attributes
201
* @hmac: the session HMAC or password, may be NULL if not used
202
* @hmac_len: the session HMAC or password length, maybe 0 if not used
203
*/
204
static void tpm2_buf_append_auth(struct tpm_buf *buf, u32 session_handle,
205
const u8 *nonce, u16 nonce_len,
206
u8 attributes,
207
const u8 *hmac, u16 hmac_len)
208
{
209
tpm_buf_append_u32(buf, 9 + nonce_len + hmac_len);
210
tpm_buf_append_u32(buf, session_handle);
211
tpm_buf_append_u16(buf, nonce_len);
212
213
if (nonce && nonce_len)
214
tpm_buf_append(buf, nonce, nonce_len);
215
216
tpm_buf_append_u8(buf, attributes);
217
tpm_buf_append_u16(buf, hmac_len);
218
219
if (hmac && hmac_len)
220
tpm_buf_append(buf, hmac, hmac_len);
221
}
222
223
/**
224
* tpm2_seal_trusted() - seal the payload of a trusted key
225
*
226
* @chip: TPM chip to use
227
* @payload: the key data in clear and encrypted form
228
* @options: authentication values and other options
229
*
230
* Return: < 0 on error and 0 on success.
231
*/
232
int tpm2_seal_trusted(struct tpm_chip *chip,
233
struct trusted_key_payload *payload,
234
struct trusted_key_options *options)
235
{
236
off_t offset = TPM_HEADER_SIZE;
237
struct tpm_buf buf, sized;
238
int blob_len = 0;
239
int hash;
240
u32 flags;
241
int rc;
242
243
hash = tpm2_find_hash_alg(options->hash);
244
if (hash < 0)
245
return hash;
246
247
if (!options->keyhandle)
248
return -EINVAL;
249
250
rc = tpm_try_get_ops(chip);
251
if (rc)
252
return rc;
253
254
rc = tpm2_start_auth_session(chip);
255
if (rc)
256
goto out_put;
257
258
rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE);
259
if (rc) {
260
tpm2_end_auth_session(chip);
261
goto out_put;
262
}
263
264
rc = tpm_buf_init_sized(&sized);
265
if (rc) {
266
tpm_buf_destroy(&buf);
267
tpm2_end_auth_session(chip);
268
goto out_put;
269
}
270
271
rc = tpm_buf_append_name(chip, &buf, options->keyhandle, NULL);
272
if (rc)
273
goto out;
274
275
tpm_buf_append_hmac_session(chip, &buf, TPM2_SA_DECRYPT,
276
options->keyauth, TPM_DIGEST_SIZE);
277
278
/* sensitive */
279
tpm_buf_append_u16(&sized, options->blobauth_len);
280
281
if (options->blobauth_len)
282
tpm_buf_append(&sized, options->blobauth, options->blobauth_len);
283
284
tpm_buf_append_u16(&sized, payload->key_len);
285
tpm_buf_append(&sized, payload->key, payload->key_len);
286
tpm_buf_append(&buf, sized.data, sized.length);
287
288
/* public */
289
tpm_buf_reset_sized(&sized);
290
tpm_buf_append_u16(&sized, TPM_ALG_KEYEDHASH);
291
tpm_buf_append_u16(&sized, hash);
292
293
/* key properties */
294
flags = 0;
295
flags |= options->policydigest_len ? 0 : TPM2_OA_USER_WITH_AUTH;
296
flags |= payload->migratable ? 0 : (TPM2_OA_FIXED_TPM | TPM2_OA_FIXED_PARENT);
297
tpm_buf_append_u32(&sized, flags);
298
299
/* policy */
300
tpm_buf_append_u16(&sized, options->policydigest_len);
301
if (options->policydigest_len)
302
tpm_buf_append(&sized, options->policydigest, options->policydigest_len);
303
304
/* public parameters */
305
tpm_buf_append_u16(&sized, TPM_ALG_NULL);
306
tpm_buf_append_u16(&sized, 0);
307
308
tpm_buf_append(&buf, sized.data, sized.length);
309
310
/* outside info */
311
tpm_buf_append_u16(&buf, 0);
312
313
/* creation PCR */
314
tpm_buf_append_u32(&buf, 0);
315
316
if (buf.flags & TPM_BUF_OVERFLOW) {
317
rc = -E2BIG;
318
tpm2_end_auth_session(chip);
319
goto out;
320
}
321
322
rc = tpm_buf_fill_hmac_session(chip, &buf);
323
if (rc)
324
goto out;
325
326
rc = tpm_transmit_cmd(chip, &buf, 4, "sealing data");
327
rc = tpm_buf_check_hmac_response(chip, &buf, rc);
328
if (rc)
329
goto out;
330
331
blob_len = tpm_buf_read_u32(&buf, &offset);
332
if (blob_len > MAX_BLOB_SIZE || buf.flags & TPM_BUF_BOUNDARY_ERROR) {
333
rc = -E2BIG;
334
goto out;
335
}
336
if (buf.length - offset < blob_len) {
337
rc = -EFAULT;
338
goto out;
339
}
340
341
blob_len = tpm2_key_encode(payload, options, &buf.data[offset], blob_len);
342
if (blob_len < 0)
343
rc = blob_len;
344
345
out:
346
tpm_buf_destroy(&sized);
347
tpm_buf_destroy(&buf);
348
349
if (!rc)
350
payload->blob_len = blob_len;
351
352
out_put:
353
tpm_put_ops(chip);
354
return tpm_ret_to_err(rc);
355
}
356
357
/**
358
* tpm2_load_cmd() - execute a TPM2_Load command
359
*
360
* @chip: TPM chip to use
361
* @payload: the key data in clear and encrypted form
362
* @options: authentication values and other options
363
* @blob_handle: returned blob handle
364
*
365
* Return: 0 on success.
366
* -E2BIG on wrong payload size.
367
* -EPERM on tpm error status.
368
* < 0 error from tpm_send.
369
*/
370
static int tpm2_load_cmd(struct tpm_chip *chip,
371
struct trusted_key_payload *payload,
372
struct trusted_key_options *options,
373
u32 *blob_handle)
374
{
375
u8 *blob_ref __free(kfree) = NULL;
376
struct tpm_buf buf;
377
unsigned int private_len;
378
unsigned int public_len;
379
unsigned int blob_len;
380
u8 *blob, *pub;
381
int rc;
382
u32 attrs;
383
384
rc = tpm2_key_decode(payload, options, &blob);
385
if (rc) {
386
/* old form */
387
blob = payload->blob;
388
payload->old_format = 1;
389
} else {
390
/* Bind for cleanup: */
391
blob_ref = blob;
392
}
393
394
/* new format carries keyhandle but old format doesn't */
395
if (!options->keyhandle)
396
return -EINVAL;
397
398
/* must be big enough for at least the two be16 size counts */
399
if (payload->blob_len < 4)
400
return -EINVAL;
401
402
private_len = get_unaligned_be16(blob);
403
404
/* must be big enough for following public_len */
405
if (private_len + 2 + 2 > (payload->blob_len))
406
return -E2BIG;
407
408
public_len = get_unaligned_be16(blob + 2 + private_len);
409
if (private_len + 2 + public_len + 2 > payload->blob_len)
410
return -E2BIG;
411
412
pub = blob + 2 + private_len + 2;
413
/* key attributes are always at offset 4 */
414
attrs = get_unaligned_be32(pub + 4);
415
416
if ((attrs & (TPM2_OA_FIXED_TPM | TPM2_OA_FIXED_PARENT)) ==
417
(TPM2_OA_FIXED_TPM | TPM2_OA_FIXED_PARENT))
418
payload->migratable = 0;
419
else
420
payload->migratable = 1;
421
422
blob_len = private_len + public_len + 4;
423
if (blob_len > payload->blob_len)
424
return -E2BIG;
425
426
rc = tpm2_start_auth_session(chip);
427
if (rc)
428
return rc;
429
430
rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_LOAD);
431
if (rc) {
432
tpm2_end_auth_session(chip);
433
return rc;
434
}
435
436
rc = tpm_buf_append_name(chip, &buf, options->keyhandle, NULL);
437
if (rc)
438
goto out;
439
440
tpm_buf_append_hmac_session(chip, &buf, 0, options->keyauth,
441
TPM_DIGEST_SIZE);
442
443
tpm_buf_append(&buf, blob, blob_len);
444
445
if (buf.flags & TPM_BUF_OVERFLOW) {
446
rc = -E2BIG;
447
tpm2_end_auth_session(chip);
448
goto out;
449
}
450
451
rc = tpm_buf_fill_hmac_session(chip, &buf);
452
if (rc)
453
goto out;
454
455
rc = tpm_transmit_cmd(chip, &buf, 4, "loading blob");
456
rc = tpm_buf_check_hmac_response(chip, &buf, rc);
457
if (!rc)
458
*blob_handle = be32_to_cpup(
459
(__be32 *) &buf.data[TPM_HEADER_SIZE]);
460
461
out:
462
tpm_buf_destroy(&buf);
463
464
return tpm_ret_to_err(rc);
465
}
466
467
/**
468
* tpm2_unseal_cmd() - execute a TPM2_Unseal command
469
*
470
* @chip: TPM chip to use
471
* @payload: the key data in clear and encrypted form
472
* @options: authentication values and other options
473
* @blob_handle: blob handle
474
*
475
* Return: 0 on success
476
* -EPERM on tpm error status
477
* < 0 error from tpm_send
478
*/
479
static int tpm2_unseal_cmd(struct tpm_chip *chip,
480
struct trusted_key_payload *payload,
481
struct trusted_key_options *options,
482
u32 blob_handle)
483
{
484
struct tpm_header *head;
485
struct tpm_buf buf;
486
u16 data_len;
487
int offset;
488
u8 *data;
489
int rc;
490
491
rc = tpm2_start_auth_session(chip);
492
if (rc)
493
return rc;
494
495
rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_UNSEAL);
496
if (rc) {
497
tpm2_end_auth_session(chip);
498
return rc;
499
}
500
501
rc = tpm_buf_append_name(chip, &buf, blob_handle, NULL);
502
if (rc)
503
goto out;
504
505
if (!options->policyhandle) {
506
tpm_buf_append_hmac_session(chip, &buf, TPM2_SA_ENCRYPT,
507
options->blobauth,
508
options->blobauth_len);
509
} else {
510
/*
511
* FIXME: The policy session was generated outside the
512
* kernel so we don't known the nonce and thus can't
513
* calculate a HMAC on it. Therefore, the user can
514
* only really use TPM2_PolicyPassword and we must
515
* send down the plain text password, which could be
516
* intercepted. We can still encrypt the returned
517
* key, but that's small comfort since the interposer
518
* could repeat our actions with the exfiltrated
519
* password.
520
*/
521
tpm2_buf_append_auth(&buf, options->policyhandle,
522
NULL /* nonce */, 0, 0,
523
options->blobauth, options->blobauth_len);
524
if (tpm2_chip_auth(chip)) {
525
tpm_buf_append_hmac_session(chip, &buf, TPM2_SA_ENCRYPT, NULL, 0);
526
} else {
527
offset = buf.handles * 4 + TPM_HEADER_SIZE;
528
head = (struct tpm_header *)buf.data;
529
if (tpm_buf_length(&buf) == offset)
530
head->tag = cpu_to_be16(TPM2_ST_NO_SESSIONS);
531
}
532
}
533
534
rc = tpm_buf_fill_hmac_session(chip, &buf);
535
if (rc)
536
goto out;
537
538
rc = tpm_transmit_cmd(chip, &buf, 6, "unsealing");
539
rc = tpm_buf_check_hmac_response(chip, &buf, rc);
540
541
if (!rc) {
542
data_len = be16_to_cpup(
543
(__be16 *) &buf.data[TPM_HEADER_SIZE + 4]);
544
if (data_len < MIN_KEY_SIZE || data_len > MAX_KEY_SIZE) {
545
rc = -EFAULT;
546
goto out;
547
}
548
549
if (tpm_buf_length(&buf) < TPM_HEADER_SIZE + 6 + data_len) {
550
rc = -EFAULT;
551
goto out;
552
}
553
data = &buf.data[TPM_HEADER_SIZE + 6];
554
555
if (payload->old_format) {
556
/* migratable flag is at the end of the key */
557
memcpy(payload->key, data, data_len - 1);
558
payload->key_len = data_len - 1;
559
payload->migratable = data[data_len - 1];
560
} else {
561
/*
562
* migratable flag already collected from key
563
* attributes
564
*/
565
memcpy(payload->key, data, data_len);
566
payload->key_len = data_len;
567
}
568
}
569
570
out:
571
tpm_buf_destroy(&buf);
572
return tpm_ret_to_err(rc);
573
}
574
575
/**
576
* tpm2_unseal_trusted() - unseal the payload of a trusted key
577
*
578
* @chip: TPM chip to use
579
* @payload: the key data in clear and encrypted form
580
* @options: authentication values and other options
581
*
582
* Return: Same as with tpm_send.
583
*/
584
int tpm2_unseal_trusted(struct tpm_chip *chip,
585
struct trusted_key_payload *payload,
586
struct trusted_key_options *options)
587
{
588
u32 blob_handle;
589
int rc;
590
591
rc = tpm_try_get_ops(chip);
592
if (rc)
593
return rc;
594
595
rc = tpm2_load_cmd(chip, payload, options, &blob_handle);
596
if (rc)
597
goto out;
598
599
rc = tpm2_unseal_cmd(chip, payload, options, blob_handle);
600
tpm2_flush_context(chip, blob_handle);
601
602
out:
603
tpm_put_ops(chip);
604
return tpm_ret_to_err(rc);
605
}
606
607