File Index
Files and directories
Sign in
FILE

trusted_tpm2.c

File preview with syntax highlighting.

linux-6.19.14/security/keys/trusted-keys/trusted_tpm2.c C
  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
 21static u32 tpm2key_oid[] = { 2, 23, 133, 10, 1, 5 };
 22
 23static 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
 88err:
 89	kfree(scratch);
 90	return ret;
 91}
 92
 93struct tpm2_key_context {
 94	u32 parent;
 95	const u8 *pub;
 96	u32 pub_len;
 97	const u8 *priv;
 98	u32 priv_len;
 99};
100
101static 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
134int 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
151int 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
169int 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
181int 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 */
204static 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 */
232int 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
345out:
346	tpm_buf_destroy(&sized);
347	tpm_buf_destroy(&buf);
348
349	if (!rc)
350		payload->blob_len = blob_len;
351
352out_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 */
370static 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
461out:
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 */
479static 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
570out:
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 */
584int 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
602out:
603	tpm_put_ops(chip);
604	return tpm_ret_to_err(rc);
605}
~/ Read-only file preview.