tpmdd-devel Archive on lore.kernel.org
 help / color / Atom feed
From: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
To: denkenz-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
	jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org,
	jejb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org
Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
	linux-integrity-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	keyrings-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: [PATCH 11/23] TPMLIB: Put banner comments on public TPM library functions
Date: Tue, 21 Aug 2018 16:58:03 +0100
Message-ID: <153486708356.13066.15616902542019684189.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <153486700916.13066.12870860668352070081.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>

Put banner comments on public TPM library functions and, if necessary, rename
the arguments to make them more obvious.

Signed-off-by: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---

 drivers/char/tpm/tpm-library.c |  126 ++++++++++++++++++++++++++++------------
 include/linux/tpm.h            |   19 ++++++
 2 files changed, 105 insertions(+), 40 deletions(-)

diff --git a/drivers/char/tpm/tpm-library.c b/drivers/char/tpm/tpm-library.c
index 41fe4247a4c8..7d1f55413f02 100644
--- a/drivers/char/tpm/tpm-library.c
+++ b/drivers/char/tpm/tpm-library.c
@@ -66,8 +66,17 @@ static int TSS_sha1(const unsigned char *data, unsigned int datalen,
 	return ret;
 }
 
-static int TSS_rawhmac(unsigned char *digest, const unsigned char *key,
-		       unsigned int keylen, ...)
+/**
+ * TSS_rawhmac - Generate a HMAC(SHA1) from raw data
+ * @digest: Result buffer - must be SHA1_DIGEST_SIZE in size
+ * @key: The key to use in the HMAC generation
+ * @keylen: The size of @key
+ * @...: Pairs of size and pointer of data elements to load into hmac
+ * @0,0: Terminator
+ */
+static int TSS_rawhmac(unsigned char *digest,
+		       const unsigned char *key, unsigned keylen,
+		       ...)
 {
 	struct tpm_sdesc *sdesc;
 	va_list argp;
@@ -110,7 +119,17 @@ out:
 	return ret;
 }
 
-/*
+/**
+ * TSS_authhmac - Calculate authorisation info to send to TPM
+ * @digest: Result buffer - must be SHA1_DIGEST_SIZE in size
+ * @key: The key to use in the HMAC generation
+ * @keylen: The size of @key
+ * @h1: Even nonce
+ * @h2: Odd nonce
+ * @h3: Continuation flag
+ * @...: Pairs of size and pointer of data elements to load into hash
+ * @0,0: Terminator
+ *
  * calculate authorization info fields to send to TPM
  */
 static int TSS_authhmac(unsigned char *digest, const unsigned char *key,
@@ -378,8 +397,8 @@ static int tpm_send_dump(struct tpm_chip *chip,
  */
 static int tpm_create_osap(struct tpm_chip *chip,
 			   struct tpm_buf *tb, struct tpm_osapsess *s,
-			   const unsigned char *key, uint16_t type,
-			   uint32_t handle)
+			   const unsigned char *keyauth,
+			   enum tpm_entity_type keytype, uint32_t keyhandle)
 {
 	unsigned char enonce[TPM_NONCE_SIZE];
 	unsigned char ononce[TPM_NONCE_SIZE];
@@ -393,8 +412,8 @@ static int tpm_create_osap(struct tpm_chip *chip,
 	store16(tb, TPM_TAG_RQU_COMMAND);
 	store32(tb, TPM_OSAP_SIZE);
 	store32(tb, TPM_ORD_OSAP);
-	store16(tb, type);
-	store32(tb, handle);
+	store16(tb, keytype);
+	store32(tb, keyhandle);
 	storebytes(tb, ononce, TPM_NONCE_SIZE);
 
 	ret = tpm_send_dump(chip, tb->data, MAX_BUF_SIZE,
@@ -407,7 +426,7 @@ static int tpm_create_osap(struct tpm_chip *chip,
 	       TPM_NONCE_SIZE);
 	memcpy(enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t) +
 				  TPM_NONCE_SIZE]), TPM_NONCE_SIZE);
-	return TSS_rawhmac(s->secret, key, SHA1_DIGEST_SIZE,
+	return TSS_rawhmac(s->secret, keyauth, SHA1_DIGEST_SIZE,
 			   TPM_NONCE_SIZE, enonce,
 			   TPM_NONCE_SIZE, ononce,
 			   0, 0);
@@ -444,15 +463,33 @@ struct tpm_digests {
 	unsigned char nonceodd[TPM_NONCE_SIZE];
 };
 
-/*
- * Have the TPM seal(encrypt) the trusted key, possibly based on
- * Platform Configuration Registers (PCRs). AUTH1 for sealing key.
+/**
+ * tpm_seal - Encrypt one key according to another plus PCR state
+ * @chip: The chip to use
+ * @tb: Large scratch buffer for I/O
+ * @keytype: Type of entity attached to @keyhandle
+ * @keyhandle: TPM-resident key used to encrypt
+ * @keyauth: 'Password' to use the key.
+ * @rawdata: Data to be encrypted
+ * @rawlen: Length of @rawdata
+ * @encbuffer: Buffer to hold the encrypted data (max SHA1_DIGEST_SIZE)
+ * @_enclen: Where to place the size of the encrypted data
+ * @encauth: 'Password' to use to encrypt authorisation key
+ * @pcrinfo: Information on PCR register values to seal to
+ * @pcrinfosize: size of @pcrinfo
+ *
+ * Have the TPM seal (encrypt) the data in the data buffer.  The encryption is
+ * based on a key already resident in the TPM and may also include the state of
+ * one or more Platform Configuration Registers (PCRs).
+ *
+ * AUTH1 is used for sealing key.
  */
-int tpm_seal(struct tpm_chip *chip, struct tpm_buf *tb, uint16_t keytype,
+int tpm_seal(struct tpm_chip *chip,
+	     struct tpm_buf *tb, enum tpm_entity_type keytype,
 	     uint32_t keyhandle, const unsigned char *keyauth,
-	     const unsigned char *data, uint32_t datalen,
-	     unsigned char *blob, uint32_t *bloblen,
-	     const unsigned char *blobauth,
+	     const unsigned char *rawdata, uint32_t rawlen,
+	     unsigned char *encbuffer, uint32_t *_enclen,
+	     const unsigned char *encauth,
 	     const unsigned char *pcrinfo, uint32_t pcrinfosize)
 {
 	struct tpm_osapsess sess;
@@ -489,13 +526,13 @@ int tpm_seal(struct tpm_chip *chip, struct tpm_buf *tb, uint16_t keytype,
 	if (ret != TPM_NONCE_SIZE)
 		goto out;
 	ordinal = htonl(TPM_ORD_SEAL);
-	datsize = htonl(datalen);
+	datsize = htonl(rawlen);
 	pcrsize = htonl(pcrinfosize);
 	cont = 0;
 
 	/* encrypt data authorization key */
 	for (i = 0; i < SHA1_DIGEST_SIZE; ++i)
-		td->encauth[i] = td->xorhash[i] ^ blobauth[i];
+		td->encauth[i] = td->xorhash[i] ^ encauth[i];
 
 	/* calculate authorization HMAC value */
 	if (pcrinfosize == 0) {
@@ -506,7 +543,7 @@ int tpm_seal(struct tpm_chip *chip, struct tpm_buf *tb, uint16_t keytype,
 				   SHA1_DIGEST_SIZE, td->encauth,
 				   sizeof(uint32_t), &pcrsize,
 				   sizeof(uint32_t), &datsize,
-				   datalen, data,
+				   rawlen, rawdata,
 				   0, 0);
 	} else {
 		/* pcr info specified */
@@ -517,7 +554,7 @@ int tpm_seal(struct tpm_chip *chip, struct tpm_buf *tb, uint16_t keytype,
 				   sizeof(uint32_t), &pcrsize,
 				   pcrinfosize, pcrinfo,
 				   sizeof(uint32_t), &datsize,
-				   datalen, data,
+				   rawlen, rawdata,
 				   0, 0);
 	}
 	if (ret < 0)
@@ -526,14 +563,14 @@ int tpm_seal(struct tpm_chip *chip, struct tpm_buf *tb, uint16_t keytype,
 	/* build and send the TPM request packet */
 	INIT_BUF(tb);
 	store16(tb, TPM_TAG_RQU_AUTH1_COMMAND);
-	store32(tb, TPM_SEAL_SIZE + pcrinfosize + datalen);
+	store32(tb, TPM_SEAL_SIZE + pcrinfosize + rawlen);
 	store32(tb, TPM_ORD_SEAL);
 	store32(tb, keyhandle);
 	storebytes(tb, td->encauth, SHA1_DIGEST_SIZE);
 	store32(tb, pcrinfosize);
 	storebytes(tb, pcrinfo, pcrinfosize);
-	store32(tb, datalen);
-	storebytes(tb, data, datalen);
+	store32(tb, rawlen);
+	storebytes(tb, rawdata, rawlen);
 	store32(tb, sess.handle);
 	storebytes(tb, td->nonceodd, TPM_NONCE_SIZE);
 	store8(tb, cont);
@@ -544,7 +581,7 @@ int tpm_seal(struct tpm_chip *chip, struct tpm_buf *tb, uint16_t keytype,
 	if (ret < 0)
 		goto out;
 
-	/* calculate the size of the returned Blob */
+	/* calculate the size of the returned encrypted data */
 	sealinfosize = LOAD32(tb->data, TPM_DATA_OFFSET + sizeof(uint32_t));
 	encdatasize = LOAD32(tb->data, TPM_DATA_OFFSET + sizeof(uint32_t) +
 			     sizeof(uint32_t) + sealinfosize);
@@ -557,10 +594,10 @@ int tpm_seal(struct tpm_chip *chip, struct tpm_buf *tb, uint16_t keytype,
 			     storedsize, TPM_DATA_OFFSET,
 			     0, 0);
 
-	/* copy the returned blob to caller */
+	/* copy the encrypted data to caller's buffer */
 	if (!ret) {
-		memcpy(blob, tb->data + TPM_DATA_OFFSET, storedsize);
-		*bloblen = storedsize;
+		memcpy(encbuffer, tb->data + TPM_DATA_OFFSET, storedsize);
+		*_enclen = storedsize;
 	}
 out:
 	kfree(td);
@@ -568,14 +605,25 @@ out:
 }
 EXPORT_SYMBOL_GPL(tpm_seal);
 
-/*
+/**
+ * tpm_unseal - Encrypt one key according to another plus PCR state
+ * @chip: The chip to use
+ * @tb: Large scratch buffer for I/O
+ * @keyhandle: TPM-resident key used to decrypt
+ * @keyauth: HMAC key
+ * @encdata: Data to be decrypted
+ * @enclen: Length of @encdata
+ * @decauth: Data to use to decrypt the authorisation key
+ * @rawbuffer: Buffer to hold the decrypted data (max SHA1_DIGEST_SIZE)
+ * @_rawlen: Where to place the size of the decrypted data
+ *
  * use the AUTH2_COMMAND form of unseal, to authorize both key and blob
  */
 int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	       uint32_t keyhandle, const unsigned char *keyauth,
-	       const unsigned char *blob, int bloblen,
-	       const unsigned char *blobauth,
-	       unsigned char *data, unsigned int *datalen)
+	       const unsigned char *encdata, int enclen,
+	       const unsigned char *decauth,
+	       unsigned char *rawbuffer, unsigned int *_rawlen)
 {
 	unsigned char nonceodd[TPM_NONCE_SIZE];
 	unsigned char enonce1[TPM_NONCE_SIZE];
@@ -611,14 +659,14 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	ret = TSS_authhmac(authdata1, keyauth, TPM_NONCE_SIZE,
 			   enonce1, nonceodd, cont,
 			   sizeof(uint32_t), &ordinal,
-			   bloblen, blob,
+			   enclen, encdata,
 			   0, 0);
 	if (ret < 0)
 		return ret;
-	ret = TSS_authhmac(authdata2, blobauth, TPM_NONCE_SIZE,
+	ret = TSS_authhmac(authdata2, decauth, TPM_NONCE_SIZE,
 			   enonce2, nonceodd, cont,
 			   sizeof(uint32_t), &ordinal,
-			   bloblen, blob,
+			   enclen, encdata,
 			   0, 0);
 	if (ret < 0)
 		return ret;
@@ -626,10 +674,10 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	/* build and send TPM request packet */
 	INIT_BUF(tb);
 	store16(tb, TPM_TAG_RQU_AUTH2_COMMAND);
-	store32(tb, TPM_UNSEAL_SIZE + bloblen);
+	store32(tb, TPM_UNSEAL_SIZE + enclen);
 	store32(tb, TPM_ORD_UNSEAL);
 	store32(tb, keyhandle);
-	storebytes(tb, blob, bloblen);
+	storebytes(tb, encdata, enclen);
 	store32(tb, authhandle1);
 	storebytes(tb, nonceodd, TPM_NONCE_SIZE);
 	store8(tb, cont);
@@ -646,18 +694,18 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 		return ret;
 	}
 
-	*datalen = LOAD32(tb->data, TPM_DATA_OFFSET);
+	*_rawlen = LOAD32(tb->data, TPM_DATA_OFFSET);
 	ret = TSS_checkhmac2(tb->data, ordinal, nonceodd,
 			     keyauth, SHA1_DIGEST_SIZE,
-			     blobauth, SHA1_DIGEST_SIZE,
+			     decauth, SHA1_DIGEST_SIZE,
 			     sizeof(uint32_t), TPM_DATA_OFFSET,
-			     *datalen, TPM_DATA_OFFSET + sizeof(uint32_t),
+			     *_rawlen, TPM_DATA_OFFSET + sizeof(uint32_t),
 			     0, 0);
 	if (ret < 0) {
 		pr_info("TSS_checkhmac2 failed (%d)\n", ret);
 		return ret;
 	}
-	memcpy(data, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t), *datalen);
+	memcpy(rawbuffer, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t), *_rawlen);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(tpm_unseal);
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index b08539920f76..cbd13e03a869 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -93,6 +93,22 @@ static inline int tpm_get_random(struct tpm_chip *chip, u8 *data, size_t max) {
 #define TPM_RETURN_OFFSET		6
 #define TPM_DATA_OFFSET			10
 
+enum tpm_entity_type {
+	TPM_ET_KEYHANDLE		= 0x01,
+	TPM_ET_OWNER			= 0x02,
+	TPM_ET_DATA			= 0x03,
+	TPM_ET_SRK			= 0x04,
+	TPM_ET_KEY			= 0x05,
+	TPM_ET_REVOKE			= 0x06,
+	TPM_ET_DEL_OWNER_BLOB		= 0x07,
+	TPM_ET_DEL_ROW			= 0x08,
+	TPM_ET_DEL_KEY_BLOB		= 0x09,
+	TPM_ET_COUNTER			= 0x0a,
+	TPM_ET_NV			= 0x0b,
+	TPM_ET_OPERATOR			= 0x0c,
+	TPM_ET_RESERVED_HANDLE		= 0x40,
+};
+
 struct tpm_buf {
 	int len;
 	unsigned char data[MAX_BUF_SIZE];
@@ -103,7 +119,8 @@ struct tpm_buf {
 extern int tpm_library_use(void);
 extern void tpm_library_unuse(void);
 
-extern int tpm_seal(struct tpm_chip *chip, struct tpm_buf *tb, uint16_t keytype,
+extern int tpm_seal(struct tpm_chip *chip,
+		    struct tpm_buf *tb, enum tpm_entity_type keytype,
 		    uint32_t keyhandle, const unsigned char *keyauth,
 		    const unsigned char *data, uint32_t datalen,
 		    unsigned char *blob, uint32_t *bloblen,


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot

  parent reply index

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-21 15:56 tpm: Provide a TPM access library David Howells
     [not found] ` <153486700916.13066.12870860668352070081.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2018-08-21 15:56   ` [PATCH 01/23] TPM: Add new TPMs to the tail of the list to prevent inadvertent change of dev David Howells
     [not found]     ` <153486701644.13066.13372706238885253812.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2018-08-21 18:30       ` Jason Gunthorpe
     [not found]         ` <20180821183004.GB25543-uk2M96/98Pc@public.gmane.org>
2018-08-24  6:24           ` Jarkko Sakkinen
     [not found]             ` <20180824062434.GB3584-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2018-08-24  6:25               ` Jarkko Sakkinen
     [not found]                 ` <20180824062557.GC3584-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2018-08-24 11:22                   ` Mimi Zohar
2018-08-24  6:19       ` Jarkko Sakkinen
2018-08-21 15:57   ` [PATCH 02/23] TPM: Provide a facility for a userspace TPM emulator David Howells
     [not found]     ` <153486702302.13066.15889029286852815542.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2018-08-21 18:31       ` Jason Gunthorpe
     [not found]         ` <20180821183140.GD25543-uk2M96/98Pc@public.gmane.org>
2018-08-24  6:29           ` Jarkko Sakkinen
2018-08-21 15:57   ` [PATCH 03/23] TPM: Provide a platform driver for the user emulator driver David Howells
     [not found]     ` <153486702979.13066.16900998092976336647.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2018-08-24  6:30       ` Jarkko Sakkinen
2018-08-21 15:57   ` [PATCH 04/23] TPM: Expose struct tpm_chip and related find_get and put functions David Howells
     [not found]     ` <153486703636.13066.16209594327379341518.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2018-08-21 18:31       ` Jason Gunthorpe
     [not found]     ` <20180821183108.GC25543-uk2M96/98Pc@public.gmane.org>
2018-08-21 18:35       ` David Howells
2018-08-21 15:57   ` [PATCH 05/23] TPM: Use struct tpm_chip rather than chip number as interface parameter David Howells
     [not found]     ` <153486704294.13066.8818198038331415342.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2018-08-24  7:42       ` Jarkko Sakkinen
2018-08-21 15:57   ` [PATCH 06/23] TPM: Move ordinal values from interface file to header with other ordinals David Howells
2018-08-21 15:57   ` [PATCH 07/23] TPM: Consolidate tpm_send(), transmit_cmd() and tpm_transmit() David Howells
2018-08-21 15:57   ` [PATCH 08/23] TPMLIB: Break TPM bits out of security/keys/trusted.c David Howells
     [not found]     ` <153486706322.13066.3105842100625841410.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2018-08-24  7:52       ` Jarkko Sakkinen
     [not found]         ` <20180824075227.GG3584-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2018-08-24  8:49           ` Jarkko Sakkinen
     [not found]         ` <20180824084930.GA10266-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2018-08-24  9:33           ` David Howells
     [not found]             ` <25340.1535103190-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2018-08-27  8:25               ` Jarkko Sakkinen
2018-08-21 15:57   ` [PATCH 09/23] TPMLIB: Do some source cleanups David Howells
2018-08-21 15:57   ` [PATCH 10/23] TPMLIB: Better format calls to TSS_*hmac*() David Howells
2018-08-21 15:58   ` David Howells [this message]
2018-08-21 15:58   ` [PATCH 12/23] TPMLIB: Create tpm_{even, odd}_nonce structs to represent nonces David Howells
2018-08-21 15:58   ` [PATCH 13/23] TPMLIB: Rename store8() and storebytes() David Howells
2018-08-21 15:58   ` [PATCH 14/23] TPMLIB: Make store_s() take a void* data argument, not unsigned char* David Howells
2018-08-21 15:58   ` [PATCH 15/23] TPMLIB: Use __be32 rather than int32_t and use cpu_to_beX() and co David Howells
2018-08-21 15:58   ` [PATCH 16/23] TPMLIB: Put more comments into the HMAC generation functions David Howells
2018-08-21 15:58   ` [PATCH 17/23] TPMLIB: Provide a wrapper to load bytes out of the reply David Howells
2018-08-21 15:58   ` [PATCH 18/23] TPMLIB: Encapsulate XOR-based encryption with authkey derivative David Howells
2018-08-21 15:58   ` [PATCH 19/23] TPMLIB: Add some debugging code David Howells
2018-08-21 15:59   ` [PATCH 20/23] TPMLIB: Implement call to TPM_CreateWrapKey David Howells
2018-08-21 15:59   ` [PATCH 21/23] TPMLIB: Implement call to TPM_LoadKey2 David Howells
2018-08-21 15:59   ` [PATCH 22/23] TPMLIB: Provide call for TPM_FlushSpecific David Howells
2018-08-21 15:59   ` [PATCH 23/23] TPM: Add an asymmetric key subtype for handling TPM-based keys David Howells
2018-08-22 14:19   ` tpm: Provide a TPM access library Jarkko Sakkinen
     [not found] ` <20180822141956.GA28110-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2018-08-22 14:45   ` David Howells
     [not found]     ` <13611.1534949106-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2018-08-23 22:49       ` Jarkko Sakkinen

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=153486708356.13066.15616902542019684189.stgit@warthog.procyon.org.uk \
    --to=dhowells-h+wxahxf7alqt0dzr+alfa@public.gmane.org \
    --cc=denkenz-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org \
    --cc=jejb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org \
    --cc=keyrings-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-integrity-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-security-module-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

tpmdd-devel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/tpmdd-devel/0 tpmdd-devel/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 tpmdd-devel tpmdd-devel/ https://lore.kernel.org/tpmdd-devel \
		tpmdd-devel@lists.sourceforge.net tpmdd-devel@archiver.kernel.org
	public-inbox-index tpmdd-devel


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/net.sourceforge.lists.tpmdd-devel


AGPL code for this site: git clone https://public-inbox.org/ public-inbox