All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: denkenz@gmail.com, jarkko.sakkinen@linux.intel.com,
	jejb@linux.vnet.ibm.com
Cc: keyrings@vger.kernel.org, linux-integrity@vger.kernel.org,
	tpmdd-devel@lists.sourceforge.net,
	linux-security-module@vger.kernel.org
Subject: [PATCH 12/23] TPMLIB: Create tpm_{even, odd}_nonce structs to represent nonces
Date: Tue, 21 Aug 2018 15:58:10 +0000	[thread overview]
Message-ID: <153486709034.13066.6676055815830934254.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <153486700916.13066.12870860668352070081.stgit@warthog.procyon.org.uk>

Create a tpm_even_nonce struct and a tpm_odd_nonce struct to represent nonces
in internal routines rather than directly using char arrays.  Having two
separate structures helps keep track of which nonce is used where.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 drivers/char/tpm/tpm-library.c |  151 +++++++++++++++++++++-------------------
 drivers/char/tpm/tpm-library.h |   10 ++-
 2 files changed, 90 insertions(+), 71 deletions(-)

diff --git a/drivers/char/tpm/tpm-library.c b/drivers/char/tpm/tpm-library.c
index 7d1f55413f02..1c64282d1d0d 100644
--- a/drivers/char/tpm/tpm-library.c
+++ b/drivers/char/tpm/tpm-library.c
@@ -35,6 +35,19 @@ static atomic_t tpm_library_usage;
 static struct crypto_shash *tpm_hashalg;
 static struct crypto_shash *tpm_hmacalg;
 
+static int tpm_gen_odd_nonce(struct tpm_chip *chip,
+			     struct tpm_odd_nonce *ononce)
+{
+	int ret;
+
+	ret = tpm_get_random(chip, ononce->data, TPM_NONCE_SIZE);
+	if (ret = TPM_NONCE_SIZE)
+		ret = 0;
+	else
+		pr_info("tpm_get_random failed (%d)\n", ret);
+	return ret;
+}
+
 static struct tpm_sdesc *tpm_init_sdesc(struct crypto_shash *alg)
 {
 	struct tpm_sdesc *sdesc;
@@ -124,23 +137,25 @@ out:
  * @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
+ * @enonce: Even nonce
+ * @ononce: Odd nonce
+ * @cont: 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,
-			unsigned int keylen, unsigned char *h1,
-			unsigned char *h2, unsigned char h3, ...)
+static int TSS_authhmac(unsigned char *digest,
+			const unsigned char *key, unsigned keylen,
+			const struct tpm_even_nonce *enonce,
+			const struct tpm_odd_nonce *ononce,
+			unsigned char cont,
+			...)
 {
 	unsigned char paramdigest[SHA1_DIGEST_SIZE];
 	struct tpm_sdesc *sdesc;
 	unsigned int dlen;
 	unsigned char *data;
-	unsigned char c;
 	int ret;
 	va_list argp;
 
@@ -150,11 +165,10 @@ static int TSS_authhmac(unsigned char *digest, const unsigned char *key,
 		return PTR_ERR(sdesc);
 	}
 
-	c = h3;
 	ret = crypto_shash_init(&sdesc->shash);
 	if (ret < 0)
 		goto out;
-	va_start(argp, h3);
+	va_start(argp, cont);
 	for (;;) {
 		dlen = va_arg(argp, unsigned int);
 		if (dlen = 0)
@@ -174,9 +188,9 @@ static int TSS_authhmac(unsigned char *digest, const unsigned char *key,
 	if (!ret)
 		ret = TSS_rawhmac(digest, key, keylen,
 				  SHA1_DIGEST_SIZE, paramdigest,
-				  TPM_NONCE_SIZE, h1,
-				  TPM_NONCE_SIZE, h2,
-				  1, &c,
+				  TPM_NONCE_SIZE, enonce->data,
+				  TPM_NONCE_SIZE, ononce->data,
+				  1, &cont,
 				  0, 0);
 out:
 	kfree(sdesc);
@@ -188,15 +202,15 @@ out:
  */
 static int TSS_checkhmac1(unsigned char *buffer,
 			  const uint32_t command,
-			  const unsigned char *ononce,
-			  const unsigned char *key,
-			  unsigned int keylen, ...)
+			  const struct tpm_odd_nonce *ononce,
+			  const unsigned char *key, unsigned keylen,
+			  ...)
 {
 	uint32_t bufsize;
 	uint16_t tag;
 	uint32_t ordinal;
 	uint32_t result;
-	unsigned char *enonce;
+	struct tpm_even_nonce *enonce;
 	unsigned char *continueflag;
 	unsigned char *authdata;
 	unsigned char testhmac[SHA1_DIGEST_SIZE];
@@ -217,7 +231,7 @@ static int TSS_checkhmac1(unsigned char *buffer,
 		return -EINVAL;
 	authdata = buffer + bufsize - SHA1_DIGEST_SIZE;
 	continueflag = authdata - 1;
-	enonce = continueflag - TPM_NONCE_SIZE;
+	enonce = (void *)continueflag - TPM_NONCE_SIZE;
 
 	sdesc = tpm_init_sdesc(tpm_hashalg);
 	if (IS_ERR(sdesc)) {
@@ -253,8 +267,8 @@ static int TSS_checkhmac1(unsigned char *buffer,
 
 	ret = TSS_rawhmac(testhmac, key, keylen,
 			  SHA1_DIGEST_SIZE, paramdigest,
-			  TPM_NONCE_SIZE, enonce,
-			  TPM_NONCE_SIZE, ononce,
+			  TPM_NONCE_SIZE, enonce->data,
+			  TPM_NONCE_SIZE, ononce->data,
 			  1, continueflag,
 			  0, 0);
 	if (ret < 0)
@@ -270,24 +284,23 @@ out:
 /*
  * verify the AUTH2_COMMAND (unseal) result from TPM
  */
-static int TSS_checkhmac2(unsigned char *buffer,
+static int TSS_checkhmac2(const unsigned char *buffer,
 			  const uint32_t command,
-			  const unsigned char *ononce,
-			  const unsigned char *key1,
-			  unsigned int keylen1,
-			  const unsigned char *key2,
-			  unsigned int keylen2, ...)
+			  const struct tpm_odd_nonce *ononce,
+			  const unsigned char *key1, unsigned keylen1,
+			  const unsigned char *key2, unsigned keylen2,
+			  ...)
 {
 	uint32_t bufsize;
 	uint16_t tag;
 	uint32_t ordinal;
 	uint32_t result;
-	unsigned char *enonce1;
-	unsigned char *continueflag1;
-	unsigned char *authdata1;
-	unsigned char *enonce2;
-	unsigned char *continueflag2;
-	unsigned char *authdata2;
+	const struct tpm_even_nonce *enonce1;
+	const unsigned char *continueflag1;
+	const unsigned char *authdata1;
+	const struct tpm_even_nonce *enonce2;
+	const unsigned char *continueflag2;
+	const unsigned char *authdata2;
 	unsigned char testhmac1[SHA1_DIGEST_SIZE];
 	unsigned char testhmac2[SHA1_DIGEST_SIZE];
 	unsigned char paramdigest[SHA1_DIGEST_SIZE];
@@ -311,8 +324,8 @@ static int TSS_checkhmac2(unsigned char *buffer,
 	authdata2 = buffer + bufsize - (SHA1_DIGEST_SIZE);
 	continueflag1 = authdata1 - 1;
 	continueflag2 = authdata2 - 1;
-	enonce1 = continueflag1 - TPM_NONCE_SIZE;
-	enonce2 = continueflag2 - TPM_NONCE_SIZE;
+	enonce1 = (const void *)continueflag1 - TPM_NONCE_SIZE;
+	enonce2 = (const void *)continueflag2 - TPM_NONCE_SIZE;
 
 	sdesc = tpm_init_sdesc(tpm_hashalg);
 	if (IS_ERR(sdesc)) {
@@ -349,8 +362,8 @@ static int TSS_checkhmac2(unsigned char *buffer,
 
 	ret = TSS_rawhmac(testhmac1, key1, keylen1,
 			  SHA1_DIGEST_SIZE, paramdigest,
-			  TPM_NONCE_SIZE, enonce1,
-			  TPM_NONCE_SIZE, ononce,
+			  TPM_NONCE_SIZE, enonce1->data,
+			  TPM_NONCE_SIZE, ononce->data,
 			  1, continueflag1,
 			  0, 0);
 	if (ret < 0)
@@ -361,8 +374,8 @@ static int TSS_checkhmac2(unsigned char *buffer,
 	}
 	ret = TSS_rawhmac(testhmac2, key2, keylen2,
 			  SHA1_DIGEST_SIZE, paramdigest,
-			  TPM_NONCE_SIZE, enonce2,
-			  TPM_NONCE_SIZE, ononce,
+			  TPM_NONCE_SIZE, enonce2->data,
+			  TPM_NONCE_SIZE, ononce->data,
 			  1, continueflag2,
 			  0, 0);
 	if (ret < 0)
@@ -400,12 +413,12 @@ static int tpm_create_osap(struct tpm_chip *chip,
 			   const unsigned char *keyauth,
 			   enum tpm_entity_type keytype, uint32_t keyhandle)
 {
-	unsigned char enonce[TPM_NONCE_SIZE];
-	unsigned char ononce[TPM_NONCE_SIZE];
+	struct tpm_even_nonce enonce;
+	struct tpm_odd_nonce ononce;
 	int ret;
 
-	ret = tpm_get_random(chip, ononce, TPM_NONCE_SIZE);
-	if (ret != TPM_NONCE_SIZE)
+	ret = tpm_gen_odd_nonce(chip, &ononce);
+	if (ret < 0)
 		return ret;
 
 	INIT_BUF(tb);
@@ -414,7 +427,7 @@ static int tpm_create_osap(struct tpm_chip *chip,
 	store32(tb, TPM_ORD_OSAP);
 	store16(tb, keytype);
 	store32(tb, keyhandle);
-	storebytes(tb, ononce, TPM_NONCE_SIZE);
+	storebytes(tb, ononce.data, TPM_NONCE_SIZE);
 
 	ret = tpm_send_dump(chip, tb->data, MAX_BUF_SIZE,
 			    "creating OSAP session");
@@ -422,13 +435,13 @@ static int tpm_create_osap(struct tpm_chip *chip,
 		return ret;
 
 	s->handle = LOAD32(tb->data, TPM_DATA_OFFSET);
-	memcpy(s->enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)]),
+	memcpy(s->enonce.data, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)]),
 	       TPM_NONCE_SIZE);
-	memcpy(enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t) +
+	memcpy(enonce.data, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t) +
 				  TPM_NONCE_SIZE]), TPM_NONCE_SIZE);
 	return TSS_rawhmac(s->secret, keyauth, SHA1_DIGEST_SIZE,
-			   TPM_NONCE_SIZE, enonce,
-			   TPM_NONCE_SIZE, ononce,
+			   TPM_NONCE_SIZE, enonce.data,
+			   TPM_NONCE_SIZE, ononce.data,
 			   0, 0);
 }
 
@@ -436,7 +449,7 @@ static int tpm_create_osap(struct tpm_chip *chip,
  * Create an object independent authorisation protocol (oiap) session
  */
 static int tpm_create_oiap(struct tpm_chip *chip, struct tpm_buf *tb,
-			   uint32_t *handle, unsigned char *nonce)
+			   uint32_t *handle, struct tpm_even_nonce *enonce)
 {
 	int ret;
 
@@ -450,7 +463,7 @@ static int tpm_create_oiap(struct tpm_chip *chip, struct tpm_buf *tb,
 		return ret;
 
 	*handle = LOAD32(tb->data, TPM_DATA_OFFSET);
-	memcpy(nonce, &tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)],
+	memcpy(enonce->data, &tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)],
 	       TPM_NONCE_SIZE);
 	return 0;
 }
@@ -460,7 +473,7 @@ struct tpm_digests {
 	unsigned char pubauth[SHA1_DIGEST_SIZE];
 	unsigned char xorwork[SHA1_DIGEST_SIZE * 2];
 	unsigned char xorhash[SHA1_DIGEST_SIZE];
-	unsigned char nonceodd[TPM_NONCE_SIZE];
+	struct tpm_odd_nonce ononce;
 };
 
 /**
@@ -517,13 +530,13 @@ int tpm_seal(struct tpm_chip *chip,
 
 	/* calculate encrypted authorization value */
 	memcpy(td->xorwork, sess.secret, SHA1_DIGEST_SIZE);
-	memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce, SHA1_DIGEST_SIZE);
+	memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce.data, SHA1_DIGEST_SIZE);
 	ret = TSS_sha1(td->xorwork, SHA1_DIGEST_SIZE * 2, td->xorhash);
 	if (ret < 0)
 		goto out;
 
-	ret = tpm_get_random(chip, td->nonceodd, TPM_NONCE_SIZE);
-	if (ret != TPM_NONCE_SIZE)
+	ret = tpm_gen_odd_nonce(chip, &td->ononce);
+	if (ret < 0)
 		goto out;
 	ordinal = htonl(TPM_ORD_SEAL);
 	datsize = htonl(rawlen);
@@ -538,7 +551,7 @@ int tpm_seal(struct tpm_chip *chip,
 	if (pcrinfosize = 0) {
 		/* no pcr info specified */
 		ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE,
-				   sess.enonce, td->nonceodd, cont,
+				   &sess.enonce, &td->ononce, cont,
 				   sizeof(uint32_t), &ordinal,
 				   SHA1_DIGEST_SIZE, td->encauth,
 				   sizeof(uint32_t), &pcrsize,
@@ -548,7 +561,7 @@ int tpm_seal(struct tpm_chip *chip,
 	} else {
 		/* pcr info specified */
 		ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE,
-				   sess.enonce, td->nonceodd, cont,
+				   &sess.enonce, &td->ononce, cont,
 				   sizeof(uint32_t), &ordinal,
 				   SHA1_DIGEST_SIZE, td->encauth,
 				   sizeof(uint32_t), &pcrsize,
@@ -572,7 +585,7 @@ int tpm_seal(struct tpm_chip *chip,
 	store32(tb, rawlen);
 	storebytes(tb, rawdata, rawlen);
 	store32(tb, sess.handle);
-	storebytes(tb, td->nonceodd, TPM_NONCE_SIZE);
+	storebytes(tb, td->ononce.data, TPM_NONCE_SIZE);
 	store8(tb, cont);
 	storebytes(tb, td->pubauth, SHA1_DIGEST_SIZE);
 
@@ -589,7 +602,7 @@ int tpm_seal(struct tpm_chip *chip,
 	    sizeof(uint32_t) + encdatasize;
 
 	/* check the HMAC in the response */
-	ret = TSS_checkhmac1(tb->data, ordinal, td->nonceodd,
+	ret = TSS_checkhmac1(tb->data, ordinal, &td->ononce,
 			     sess.secret, SHA1_DIGEST_SIZE,
 			     storedsize, TPM_DATA_OFFSET,
 			     0, 0);
@@ -625,9 +638,9 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	       const unsigned char *decauth,
 	       unsigned char *rawbuffer, unsigned int *_rawlen)
 {
-	unsigned char nonceodd[TPM_NONCE_SIZE];
-	unsigned char enonce1[TPM_NONCE_SIZE];
-	unsigned char enonce2[TPM_NONCE_SIZE];
+	struct tpm_odd_nonce ononce;
+	struct tpm_even_nonce enonce1;
+	struct tpm_even_nonce enonce2;
 	unsigned char authdata1[SHA1_DIGEST_SIZE];
 	unsigned char authdata2[SHA1_DIGEST_SIZE];
 	uint32_t authhandle1 = 0;
@@ -638,12 +651,12 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	int ret;
 
 	/* sessions for unsealing key and data */
-	ret = tpm_create_oiap(chip, tb, &authhandle1, enonce1);
+	ret = tpm_create_oiap(chip, tb, &authhandle1, &enonce1);
 	if (ret < 0) {
 		pr_info("Failed to create OIAP 1 (%d)\n", ret);
 		return ret;
 	}
-	ret = tpm_create_oiap(chip, tb, &authhandle2, enonce2);
+	ret = tpm_create_oiap(chip, tb, &authhandle2, &enonce2);
 	if (ret < 0) {
 		pr_info("Failed to create OIAP 2 (%d)\n", ret);
 		return ret;
@@ -651,20 +664,18 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 
 	ordinal = htonl(TPM_ORD_UNSEAL);
 	keyhndl = htonl(SRKHANDLE);
-	ret = tpm_get_random(chip, nonceodd, TPM_NONCE_SIZE);
-	if (ret != TPM_NONCE_SIZE) {
-		pr_info("tpm_get_random failed (%d)\n", ret);
+	ret = tpm_gen_odd_nonce(chip, &ononce);
+	if (ret < 0)
 		return ret;
-	}
 	ret = TSS_authhmac(authdata1, keyauth, TPM_NONCE_SIZE,
-			   enonce1, nonceodd, cont,
+			   &enonce1, &ononce, cont,
 			   sizeof(uint32_t), &ordinal,
 			   enclen, encdata,
 			   0, 0);
 	if (ret < 0)
 		return ret;
 	ret = TSS_authhmac(authdata2, decauth, TPM_NONCE_SIZE,
-			   enonce2, nonceodd, cont,
+			   &enonce2, &ononce, cont,
 			   sizeof(uint32_t), &ordinal,
 			   enclen, encdata,
 			   0, 0);
@@ -679,11 +690,11 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	store32(tb, keyhandle);
 	storebytes(tb, encdata, enclen);
 	store32(tb, authhandle1);
-	storebytes(tb, nonceodd, TPM_NONCE_SIZE);
+	storebytes(tb, ononce.data, TPM_NONCE_SIZE);
 	store8(tb, cont);
 	storebytes(tb, authdata1, SHA1_DIGEST_SIZE);
 	store32(tb, authhandle2);
-	storebytes(tb, nonceodd, TPM_NONCE_SIZE);
+	storebytes(tb, ononce.data, TPM_NONCE_SIZE);
 	store8(tb, cont);
 	storebytes(tb, authdata2, SHA1_DIGEST_SIZE);
 
@@ -695,7 +706,7 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	}
 
 	*_rawlen = LOAD32(tb->data, TPM_DATA_OFFSET);
-	ret = TSS_checkhmac2(tb->data, ordinal, nonceodd,
+	ret = TSS_checkhmac2(tb->data, ordinal, &ononce,
 			     keyauth, SHA1_DIGEST_SIZE,
 			     decauth, SHA1_DIGEST_SIZE,
 			     sizeof(uint32_t), TPM_DATA_OFFSET,
diff --git a/drivers/char/tpm/tpm-library.h b/drivers/char/tpm/tpm-library.h
index 6f7571cc6d6c..ceb0ea1cd2bb 100644
--- a/drivers/char/tpm/tpm-library.h
+++ b/drivers/char/tpm/tpm-library.h
@@ -15,10 +15,18 @@
 #define LOAD32N(buffer, offset)	(*(uint32_t *)&buffer[offset])
 #define LOAD16(buffer, offset)	(ntohs(*(uint16_t *)&buffer[offset]))
 
+struct tpm_even_nonce {
+	unsigned char data[TPM_NONCE_SIZE];
+};
+
+struct tpm_odd_nonce {
+	unsigned char data[TPM_NONCE_SIZE];
+};
+
 struct tpm_osapsess {
 	uint32_t handle;
 	unsigned char secret[SHA1_DIGEST_SIZE];
-	unsigned char enonce[TPM_NONCE_SIZE];
+	struct tpm_even_nonce enonce;
 };
 
 static inline void store8(struct tpm_buf *buf, const unsigned char value)

WARNING: multiple messages have this Message-ID (diff)
From: dhowells@redhat.com (David Howells)
To: linux-security-module@vger.kernel.org
Subject: [PATCH 12/23] TPMLIB: Create tpm_{even, odd}_nonce structs to represent nonces
Date: Tue, 21 Aug 2018 16:58:10 +0100	[thread overview]
Message-ID: <153486709034.13066.6676055815830934254.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <153486700916.13066.12870860668352070081.stgit@warthog.procyon.org.uk>

Create a tpm_even_nonce struct and a tpm_odd_nonce struct to represent nonces
in internal routines rather than directly using char arrays.  Having two
separate structures helps keep track of which nonce is used where.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 drivers/char/tpm/tpm-library.c |  151 +++++++++++++++++++++-------------------
 drivers/char/tpm/tpm-library.h |   10 ++-
 2 files changed, 90 insertions(+), 71 deletions(-)

diff --git a/drivers/char/tpm/tpm-library.c b/drivers/char/tpm/tpm-library.c
index 7d1f55413f02..1c64282d1d0d 100644
--- a/drivers/char/tpm/tpm-library.c
+++ b/drivers/char/tpm/tpm-library.c
@@ -35,6 +35,19 @@ static atomic_t tpm_library_usage;
 static struct crypto_shash *tpm_hashalg;
 static struct crypto_shash *tpm_hmacalg;
 
+static int tpm_gen_odd_nonce(struct tpm_chip *chip,
+			     struct tpm_odd_nonce *ononce)
+{
+	int ret;
+
+	ret = tpm_get_random(chip, ononce->data, TPM_NONCE_SIZE);
+	if (ret == TPM_NONCE_SIZE)
+		ret = 0;
+	else
+		pr_info("tpm_get_random failed (%d)\n", ret);
+	return ret;
+}
+
 static struct tpm_sdesc *tpm_init_sdesc(struct crypto_shash *alg)
 {
 	struct tpm_sdesc *sdesc;
@@ -124,23 +137,25 @@ out:
  * @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
+ * @enonce: Even nonce
+ * @ononce: Odd nonce
+ * @cont: 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,
-			unsigned int keylen, unsigned char *h1,
-			unsigned char *h2, unsigned char h3, ...)
+static int TSS_authhmac(unsigned char *digest,
+			const unsigned char *key, unsigned keylen,
+			const struct tpm_even_nonce *enonce,
+			const struct tpm_odd_nonce *ononce,
+			unsigned char cont,
+			...)
 {
 	unsigned char paramdigest[SHA1_DIGEST_SIZE];
 	struct tpm_sdesc *sdesc;
 	unsigned int dlen;
 	unsigned char *data;
-	unsigned char c;
 	int ret;
 	va_list argp;
 
@@ -150,11 +165,10 @@ static int TSS_authhmac(unsigned char *digest, const unsigned char *key,
 		return PTR_ERR(sdesc);
 	}
 
-	c = h3;
 	ret = crypto_shash_init(&sdesc->shash);
 	if (ret < 0)
 		goto out;
-	va_start(argp, h3);
+	va_start(argp, cont);
 	for (;;) {
 		dlen = va_arg(argp, unsigned int);
 		if (dlen == 0)
@@ -174,9 +188,9 @@ static int TSS_authhmac(unsigned char *digest, const unsigned char *key,
 	if (!ret)
 		ret = TSS_rawhmac(digest, key, keylen,
 				  SHA1_DIGEST_SIZE, paramdigest,
-				  TPM_NONCE_SIZE, h1,
-				  TPM_NONCE_SIZE, h2,
-				  1, &c,
+				  TPM_NONCE_SIZE, enonce->data,
+				  TPM_NONCE_SIZE, ononce->data,
+				  1, &cont,
 				  0, 0);
 out:
 	kfree(sdesc);
@@ -188,15 +202,15 @@ out:
  */
 static int TSS_checkhmac1(unsigned char *buffer,
 			  const uint32_t command,
-			  const unsigned char *ononce,
-			  const unsigned char *key,
-			  unsigned int keylen, ...)
+			  const struct tpm_odd_nonce *ononce,
+			  const unsigned char *key, unsigned keylen,
+			  ...)
 {
 	uint32_t bufsize;
 	uint16_t tag;
 	uint32_t ordinal;
 	uint32_t result;
-	unsigned char *enonce;
+	struct tpm_even_nonce *enonce;
 	unsigned char *continueflag;
 	unsigned char *authdata;
 	unsigned char testhmac[SHA1_DIGEST_SIZE];
@@ -217,7 +231,7 @@ static int TSS_checkhmac1(unsigned char *buffer,
 		return -EINVAL;
 	authdata = buffer + bufsize - SHA1_DIGEST_SIZE;
 	continueflag = authdata - 1;
-	enonce = continueflag - TPM_NONCE_SIZE;
+	enonce = (void *)continueflag - TPM_NONCE_SIZE;
 
 	sdesc = tpm_init_sdesc(tpm_hashalg);
 	if (IS_ERR(sdesc)) {
@@ -253,8 +267,8 @@ static int TSS_checkhmac1(unsigned char *buffer,
 
 	ret = TSS_rawhmac(testhmac, key, keylen,
 			  SHA1_DIGEST_SIZE, paramdigest,
-			  TPM_NONCE_SIZE, enonce,
-			  TPM_NONCE_SIZE, ononce,
+			  TPM_NONCE_SIZE, enonce->data,
+			  TPM_NONCE_SIZE, ononce->data,
 			  1, continueflag,
 			  0, 0);
 	if (ret < 0)
@@ -270,24 +284,23 @@ out:
 /*
  * verify the AUTH2_COMMAND (unseal) result from TPM
  */
-static int TSS_checkhmac2(unsigned char *buffer,
+static int TSS_checkhmac2(const unsigned char *buffer,
 			  const uint32_t command,
-			  const unsigned char *ononce,
-			  const unsigned char *key1,
-			  unsigned int keylen1,
-			  const unsigned char *key2,
-			  unsigned int keylen2, ...)
+			  const struct tpm_odd_nonce *ononce,
+			  const unsigned char *key1, unsigned keylen1,
+			  const unsigned char *key2, unsigned keylen2,
+			  ...)
 {
 	uint32_t bufsize;
 	uint16_t tag;
 	uint32_t ordinal;
 	uint32_t result;
-	unsigned char *enonce1;
-	unsigned char *continueflag1;
-	unsigned char *authdata1;
-	unsigned char *enonce2;
-	unsigned char *continueflag2;
-	unsigned char *authdata2;
+	const struct tpm_even_nonce *enonce1;
+	const unsigned char *continueflag1;
+	const unsigned char *authdata1;
+	const struct tpm_even_nonce *enonce2;
+	const unsigned char *continueflag2;
+	const unsigned char *authdata2;
 	unsigned char testhmac1[SHA1_DIGEST_SIZE];
 	unsigned char testhmac2[SHA1_DIGEST_SIZE];
 	unsigned char paramdigest[SHA1_DIGEST_SIZE];
@@ -311,8 +324,8 @@ static int TSS_checkhmac2(unsigned char *buffer,
 	authdata2 = buffer + bufsize - (SHA1_DIGEST_SIZE);
 	continueflag1 = authdata1 - 1;
 	continueflag2 = authdata2 - 1;
-	enonce1 = continueflag1 - TPM_NONCE_SIZE;
-	enonce2 = continueflag2 - TPM_NONCE_SIZE;
+	enonce1 = (const void *)continueflag1 - TPM_NONCE_SIZE;
+	enonce2 = (const void *)continueflag2 - TPM_NONCE_SIZE;
 
 	sdesc = tpm_init_sdesc(tpm_hashalg);
 	if (IS_ERR(sdesc)) {
@@ -349,8 +362,8 @@ static int TSS_checkhmac2(unsigned char *buffer,
 
 	ret = TSS_rawhmac(testhmac1, key1, keylen1,
 			  SHA1_DIGEST_SIZE, paramdigest,
-			  TPM_NONCE_SIZE, enonce1,
-			  TPM_NONCE_SIZE, ononce,
+			  TPM_NONCE_SIZE, enonce1->data,
+			  TPM_NONCE_SIZE, ononce->data,
 			  1, continueflag1,
 			  0, 0);
 	if (ret < 0)
@@ -361,8 +374,8 @@ static int TSS_checkhmac2(unsigned char *buffer,
 	}
 	ret = TSS_rawhmac(testhmac2, key2, keylen2,
 			  SHA1_DIGEST_SIZE, paramdigest,
-			  TPM_NONCE_SIZE, enonce2,
-			  TPM_NONCE_SIZE, ononce,
+			  TPM_NONCE_SIZE, enonce2->data,
+			  TPM_NONCE_SIZE, ononce->data,
 			  1, continueflag2,
 			  0, 0);
 	if (ret < 0)
@@ -400,12 +413,12 @@ static int tpm_create_osap(struct tpm_chip *chip,
 			   const unsigned char *keyauth,
 			   enum tpm_entity_type keytype, uint32_t keyhandle)
 {
-	unsigned char enonce[TPM_NONCE_SIZE];
-	unsigned char ononce[TPM_NONCE_SIZE];
+	struct tpm_even_nonce enonce;
+	struct tpm_odd_nonce ononce;
 	int ret;
 
-	ret = tpm_get_random(chip, ononce, TPM_NONCE_SIZE);
-	if (ret != TPM_NONCE_SIZE)
+	ret = tpm_gen_odd_nonce(chip, &ononce);
+	if (ret < 0)
 		return ret;
 
 	INIT_BUF(tb);
@@ -414,7 +427,7 @@ static int tpm_create_osap(struct tpm_chip *chip,
 	store32(tb, TPM_ORD_OSAP);
 	store16(tb, keytype);
 	store32(tb, keyhandle);
-	storebytes(tb, ononce, TPM_NONCE_SIZE);
+	storebytes(tb, ononce.data, TPM_NONCE_SIZE);
 
 	ret = tpm_send_dump(chip, tb->data, MAX_BUF_SIZE,
 			    "creating OSAP session");
@@ -422,13 +435,13 @@ static int tpm_create_osap(struct tpm_chip *chip,
 		return ret;
 
 	s->handle = LOAD32(tb->data, TPM_DATA_OFFSET);
-	memcpy(s->enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)]),
+	memcpy(s->enonce.data, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)]),
 	       TPM_NONCE_SIZE);
-	memcpy(enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t) +
+	memcpy(enonce.data, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t) +
 				  TPM_NONCE_SIZE]), TPM_NONCE_SIZE);
 	return TSS_rawhmac(s->secret, keyauth, SHA1_DIGEST_SIZE,
-			   TPM_NONCE_SIZE, enonce,
-			   TPM_NONCE_SIZE, ononce,
+			   TPM_NONCE_SIZE, enonce.data,
+			   TPM_NONCE_SIZE, ononce.data,
 			   0, 0);
 }
 
@@ -436,7 +449,7 @@ static int tpm_create_osap(struct tpm_chip *chip,
  * Create an object independent authorisation protocol (oiap) session
  */
 static int tpm_create_oiap(struct tpm_chip *chip, struct tpm_buf *tb,
-			   uint32_t *handle, unsigned char *nonce)
+			   uint32_t *handle, struct tpm_even_nonce *enonce)
 {
 	int ret;
 
@@ -450,7 +463,7 @@ static int tpm_create_oiap(struct tpm_chip *chip, struct tpm_buf *tb,
 		return ret;
 
 	*handle = LOAD32(tb->data, TPM_DATA_OFFSET);
-	memcpy(nonce, &tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)],
+	memcpy(enonce->data, &tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)],
 	       TPM_NONCE_SIZE);
 	return 0;
 }
@@ -460,7 +473,7 @@ struct tpm_digests {
 	unsigned char pubauth[SHA1_DIGEST_SIZE];
 	unsigned char xorwork[SHA1_DIGEST_SIZE * 2];
 	unsigned char xorhash[SHA1_DIGEST_SIZE];
-	unsigned char nonceodd[TPM_NONCE_SIZE];
+	struct tpm_odd_nonce ononce;
 };
 
 /**
@@ -517,13 +530,13 @@ int tpm_seal(struct tpm_chip *chip,
 
 	/* calculate encrypted authorization value */
 	memcpy(td->xorwork, sess.secret, SHA1_DIGEST_SIZE);
-	memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce, SHA1_DIGEST_SIZE);
+	memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce.data, SHA1_DIGEST_SIZE);
 	ret = TSS_sha1(td->xorwork, SHA1_DIGEST_SIZE * 2, td->xorhash);
 	if (ret < 0)
 		goto out;
 
-	ret = tpm_get_random(chip, td->nonceodd, TPM_NONCE_SIZE);
-	if (ret != TPM_NONCE_SIZE)
+	ret = tpm_gen_odd_nonce(chip, &td->ononce);
+	if (ret < 0)
 		goto out;
 	ordinal = htonl(TPM_ORD_SEAL);
 	datsize = htonl(rawlen);
@@ -538,7 +551,7 @@ int tpm_seal(struct tpm_chip *chip,
 	if (pcrinfosize == 0) {
 		/* no pcr info specified */
 		ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE,
-				   sess.enonce, td->nonceodd, cont,
+				   &sess.enonce, &td->ononce, cont,
 				   sizeof(uint32_t), &ordinal,
 				   SHA1_DIGEST_SIZE, td->encauth,
 				   sizeof(uint32_t), &pcrsize,
@@ -548,7 +561,7 @@ int tpm_seal(struct tpm_chip *chip,
 	} else {
 		/* pcr info specified */
 		ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE,
-				   sess.enonce, td->nonceodd, cont,
+				   &sess.enonce, &td->ononce, cont,
 				   sizeof(uint32_t), &ordinal,
 				   SHA1_DIGEST_SIZE, td->encauth,
 				   sizeof(uint32_t), &pcrsize,
@@ -572,7 +585,7 @@ int tpm_seal(struct tpm_chip *chip,
 	store32(tb, rawlen);
 	storebytes(tb, rawdata, rawlen);
 	store32(tb, sess.handle);
-	storebytes(tb, td->nonceodd, TPM_NONCE_SIZE);
+	storebytes(tb, td->ononce.data, TPM_NONCE_SIZE);
 	store8(tb, cont);
 	storebytes(tb, td->pubauth, SHA1_DIGEST_SIZE);
 
@@ -589,7 +602,7 @@ int tpm_seal(struct tpm_chip *chip,
 	    sizeof(uint32_t) + encdatasize;
 
 	/* check the HMAC in the response */
-	ret = TSS_checkhmac1(tb->data, ordinal, td->nonceodd,
+	ret = TSS_checkhmac1(tb->data, ordinal, &td->ononce,
 			     sess.secret, SHA1_DIGEST_SIZE,
 			     storedsize, TPM_DATA_OFFSET,
 			     0, 0);
@@ -625,9 +638,9 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	       const unsigned char *decauth,
 	       unsigned char *rawbuffer, unsigned int *_rawlen)
 {
-	unsigned char nonceodd[TPM_NONCE_SIZE];
-	unsigned char enonce1[TPM_NONCE_SIZE];
-	unsigned char enonce2[TPM_NONCE_SIZE];
+	struct tpm_odd_nonce ononce;
+	struct tpm_even_nonce enonce1;
+	struct tpm_even_nonce enonce2;
 	unsigned char authdata1[SHA1_DIGEST_SIZE];
 	unsigned char authdata2[SHA1_DIGEST_SIZE];
 	uint32_t authhandle1 = 0;
@@ -638,12 +651,12 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	int ret;
 
 	/* sessions for unsealing key and data */
-	ret = tpm_create_oiap(chip, tb, &authhandle1, enonce1);
+	ret = tpm_create_oiap(chip, tb, &authhandle1, &enonce1);
 	if (ret < 0) {
 		pr_info("Failed to create OIAP 1 (%d)\n", ret);
 		return ret;
 	}
-	ret = tpm_create_oiap(chip, tb, &authhandle2, enonce2);
+	ret = tpm_create_oiap(chip, tb, &authhandle2, &enonce2);
 	if (ret < 0) {
 		pr_info("Failed to create OIAP 2 (%d)\n", ret);
 		return ret;
@@ -651,20 +664,18 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 
 	ordinal = htonl(TPM_ORD_UNSEAL);
 	keyhndl = htonl(SRKHANDLE);
-	ret = tpm_get_random(chip, nonceodd, TPM_NONCE_SIZE);
-	if (ret != TPM_NONCE_SIZE) {
-		pr_info("tpm_get_random failed (%d)\n", ret);
+	ret = tpm_gen_odd_nonce(chip, &ononce);
+	if (ret < 0)
 		return ret;
-	}
 	ret = TSS_authhmac(authdata1, keyauth, TPM_NONCE_SIZE,
-			   enonce1, nonceodd, cont,
+			   &enonce1, &ononce, cont,
 			   sizeof(uint32_t), &ordinal,
 			   enclen, encdata,
 			   0, 0);
 	if (ret < 0)
 		return ret;
 	ret = TSS_authhmac(authdata2, decauth, TPM_NONCE_SIZE,
-			   enonce2, nonceodd, cont,
+			   &enonce2, &ononce, cont,
 			   sizeof(uint32_t), &ordinal,
 			   enclen, encdata,
 			   0, 0);
@@ -679,11 +690,11 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	store32(tb, keyhandle);
 	storebytes(tb, encdata, enclen);
 	store32(tb, authhandle1);
-	storebytes(tb, nonceodd, TPM_NONCE_SIZE);
+	storebytes(tb, ononce.data, TPM_NONCE_SIZE);
 	store8(tb, cont);
 	storebytes(tb, authdata1, SHA1_DIGEST_SIZE);
 	store32(tb, authhandle2);
-	storebytes(tb, nonceodd, TPM_NONCE_SIZE);
+	storebytes(tb, ononce.data, TPM_NONCE_SIZE);
 	store8(tb, cont);
 	storebytes(tb, authdata2, SHA1_DIGEST_SIZE);
 
@@ -695,7 +706,7 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	}
 
 	*_rawlen = LOAD32(tb->data, TPM_DATA_OFFSET);
-	ret = TSS_checkhmac2(tb->data, ordinal, nonceodd,
+	ret = TSS_checkhmac2(tb->data, ordinal, &ononce,
 			     keyauth, SHA1_DIGEST_SIZE,
 			     decauth, SHA1_DIGEST_SIZE,
 			     sizeof(uint32_t), TPM_DATA_OFFSET,
diff --git a/drivers/char/tpm/tpm-library.h b/drivers/char/tpm/tpm-library.h
index 6f7571cc6d6c..ceb0ea1cd2bb 100644
--- a/drivers/char/tpm/tpm-library.h
+++ b/drivers/char/tpm/tpm-library.h
@@ -15,10 +15,18 @@
 #define LOAD32N(buffer, offset)	(*(uint32_t *)&buffer[offset])
 #define LOAD16(buffer, offset)	(ntohs(*(uint16_t *)&buffer[offset]))
 
+struct tpm_even_nonce {
+	unsigned char data[TPM_NONCE_SIZE];
+};
+
+struct tpm_odd_nonce {
+	unsigned char data[TPM_NONCE_SIZE];
+};
+
 struct tpm_osapsess {
 	uint32_t handle;
 	unsigned char secret[SHA1_DIGEST_SIZE];
-	unsigned char enonce[TPM_NONCE_SIZE];
+	struct tpm_even_nonce enonce;
 };
 
 static inline void store8(struct tpm_buf *buf, const unsigned char value)

WARNING: multiple messages have this Message-ID (diff)
From: David Howells <dhowells@redhat.com>
To: denkenz@gmail.com, jarkko.sakkinen@linux.intel.com,
	jejb@linux.vnet.ibm.com
Cc: keyrings@vger.kernel.org, linux-integrity@vger.kernel.org,
	tpmdd-devel@lists.sourceforge.net,
	linux-security-module@vger.kernel.org
Subject: [PATCH 12/23] TPMLIB: Create tpm_{even, odd}_nonce structs to represent nonces
Date: Tue, 21 Aug 2018 16:58:10 +0100	[thread overview]
Message-ID: <153486709034.13066.6676055815830934254.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <153486700916.13066.12870860668352070081.stgit@warthog.procyon.org.uk>

Create a tpm_even_nonce struct and a tpm_odd_nonce struct to represent nonces
in internal routines rather than directly using char arrays.  Having two
separate structures helps keep track of which nonce is used where.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 drivers/char/tpm/tpm-library.c |  151 +++++++++++++++++++++-------------------
 drivers/char/tpm/tpm-library.h |   10 ++-
 2 files changed, 90 insertions(+), 71 deletions(-)

diff --git a/drivers/char/tpm/tpm-library.c b/drivers/char/tpm/tpm-library.c
index 7d1f55413f02..1c64282d1d0d 100644
--- a/drivers/char/tpm/tpm-library.c
+++ b/drivers/char/tpm/tpm-library.c
@@ -35,6 +35,19 @@ static atomic_t tpm_library_usage;
 static struct crypto_shash *tpm_hashalg;
 static struct crypto_shash *tpm_hmacalg;
 
+static int tpm_gen_odd_nonce(struct tpm_chip *chip,
+			     struct tpm_odd_nonce *ononce)
+{
+	int ret;
+
+	ret = tpm_get_random(chip, ononce->data, TPM_NONCE_SIZE);
+	if (ret == TPM_NONCE_SIZE)
+		ret = 0;
+	else
+		pr_info("tpm_get_random failed (%d)\n", ret);
+	return ret;
+}
+
 static struct tpm_sdesc *tpm_init_sdesc(struct crypto_shash *alg)
 {
 	struct tpm_sdesc *sdesc;
@@ -124,23 +137,25 @@ out:
  * @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
+ * @enonce: Even nonce
+ * @ononce: Odd nonce
+ * @cont: 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,
-			unsigned int keylen, unsigned char *h1,
-			unsigned char *h2, unsigned char h3, ...)
+static int TSS_authhmac(unsigned char *digest,
+			const unsigned char *key, unsigned keylen,
+			const struct tpm_even_nonce *enonce,
+			const struct tpm_odd_nonce *ononce,
+			unsigned char cont,
+			...)
 {
 	unsigned char paramdigest[SHA1_DIGEST_SIZE];
 	struct tpm_sdesc *sdesc;
 	unsigned int dlen;
 	unsigned char *data;
-	unsigned char c;
 	int ret;
 	va_list argp;
 
@@ -150,11 +165,10 @@ static int TSS_authhmac(unsigned char *digest, const unsigned char *key,
 		return PTR_ERR(sdesc);
 	}
 
-	c = h3;
 	ret = crypto_shash_init(&sdesc->shash);
 	if (ret < 0)
 		goto out;
-	va_start(argp, h3);
+	va_start(argp, cont);
 	for (;;) {
 		dlen = va_arg(argp, unsigned int);
 		if (dlen == 0)
@@ -174,9 +188,9 @@ static int TSS_authhmac(unsigned char *digest, const unsigned char *key,
 	if (!ret)
 		ret = TSS_rawhmac(digest, key, keylen,
 				  SHA1_DIGEST_SIZE, paramdigest,
-				  TPM_NONCE_SIZE, h1,
-				  TPM_NONCE_SIZE, h2,
-				  1, &c,
+				  TPM_NONCE_SIZE, enonce->data,
+				  TPM_NONCE_SIZE, ononce->data,
+				  1, &cont,
 				  0, 0);
 out:
 	kfree(sdesc);
@@ -188,15 +202,15 @@ out:
  */
 static int TSS_checkhmac1(unsigned char *buffer,
 			  const uint32_t command,
-			  const unsigned char *ononce,
-			  const unsigned char *key,
-			  unsigned int keylen, ...)
+			  const struct tpm_odd_nonce *ononce,
+			  const unsigned char *key, unsigned keylen,
+			  ...)
 {
 	uint32_t bufsize;
 	uint16_t tag;
 	uint32_t ordinal;
 	uint32_t result;
-	unsigned char *enonce;
+	struct tpm_even_nonce *enonce;
 	unsigned char *continueflag;
 	unsigned char *authdata;
 	unsigned char testhmac[SHA1_DIGEST_SIZE];
@@ -217,7 +231,7 @@ static int TSS_checkhmac1(unsigned char *buffer,
 		return -EINVAL;
 	authdata = buffer + bufsize - SHA1_DIGEST_SIZE;
 	continueflag = authdata - 1;
-	enonce = continueflag - TPM_NONCE_SIZE;
+	enonce = (void *)continueflag - TPM_NONCE_SIZE;
 
 	sdesc = tpm_init_sdesc(tpm_hashalg);
 	if (IS_ERR(sdesc)) {
@@ -253,8 +267,8 @@ static int TSS_checkhmac1(unsigned char *buffer,
 
 	ret = TSS_rawhmac(testhmac, key, keylen,
 			  SHA1_DIGEST_SIZE, paramdigest,
-			  TPM_NONCE_SIZE, enonce,
-			  TPM_NONCE_SIZE, ononce,
+			  TPM_NONCE_SIZE, enonce->data,
+			  TPM_NONCE_SIZE, ononce->data,
 			  1, continueflag,
 			  0, 0);
 	if (ret < 0)
@@ -270,24 +284,23 @@ out:
 /*
  * verify the AUTH2_COMMAND (unseal) result from TPM
  */
-static int TSS_checkhmac2(unsigned char *buffer,
+static int TSS_checkhmac2(const unsigned char *buffer,
 			  const uint32_t command,
-			  const unsigned char *ononce,
-			  const unsigned char *key1,
-			  unsigned int keylen1,
-			  const unsigned char *key2,
-			  unsigned int keylen2, ...)
+			  const struct tpm_odd_nonce *ononce,
+			  const unsigned char *key1, unsigned keylen1,
+			  const unsigned char *key2, unsigned keylen2,
+			  ...)
 {
 	uint32_t bufsize;
 	uint16_t tag;
 	uint32_t ordinal;
 	uint32_t result;
-	unsigned char *enonce1;
-	unsigned char *continueflag1;
-	unsigned char *authdata1;
-	unsigned char *enonce2;
-	unsigned char *continueflag2;
-	unsigned char *authdata2;
+	const struct tpm_even_nonce *enonce1;
+	const unsigned char *continueflag1;
+	const unsigned char *authdata1;
+	const struct tpm_even_nonce *enonce2;
+	const unsigned char *continueflag2;
+	const unsigned char *authdata2;
 	unsigned char testhmac1[SHA1_DIGEST_SIZE];
 	unsigned char testhmac2[SHA1_DIGEST_SIZE];
 	unsigned char paramdigest[SHA1_DIGEST_SIZE];
@@ -311,8 +324,8 @@ static int TSS_checkhmac2(unsigned char *buffer,
 	authdata2 = buffer + bufsize - (SHA1_DIGEST_SIZE);
 	continueflag1 = authdata1 - 1;
 	continueflag2 = authdata2 - 1;
-	enonce1 = continueflag1 - TPM_NONCE_SIZE;
-	enonce2 = continueflag2 - TPM_NONCE_SIZE;
+	enonce1 = (const void *)continueflag1 - TPM_NONCE_SIZE;
+	enonce2 = (const void *)continueflag2 - TPM_NONCE_SIZE;
 
 	sdesc = tpm_init_sdesc(tpm_hashalg);
 	if (IS_ERR(sdesc)) {
@@ -349,8 +362,8 @@ static int TSS_checkhmac2(unsigned char *buffer,
 
 	ret = TSS_rawhmac(testhmac1, key1, keylen1,
 			  SHA1_DIGEST_SIZE, paramdigest,
-			  TPM_NONCE_SIZE, enonce1,
-			  TPM_NONCE_SIZE, ononce,
+			  TPM_NONCE_SIZE, enonce1->data,
+			  TPM_NONCE_SIZE, ononce->data,
 			  1, continueflag1,
 			  0, 0);
 	if (ret < 0)
@@ -361,8 +374,8 @@ static int TSS_checkhmac2(unsigned char *buffer,
 	}
 	ret = TSS_rawhmac(testhmac2, key2, keylen2,
 			  SHA1_DIGEST_SIZE, paramdigest,
-			  TPM_NONCE_SIZE, enonce2,
-			  TPM_NONCE_SIZE, ononce,
+			  TPM_NONCE_SIZE, enonce2->data,
+			  TPM_NONCE_SIZE, ononce->data,
 			  1, continueflag2,
 			  0, 0);
 	if (ret < 0)
@@ -400,12 +413,12 @@ static int tpm_create_osap(struct tpm_chip *chip,
 			   const unsigned char *keyauth,
 			   enum tpm_entity_type keytype, uint32_t keyhandle)
 {
-	unsigned char enonce[TPM_NONCE_SIZE];
-	unsigned char ononce[TPM_NONCE_SIZE];
+	struct tpm_even_nonce enonce;
+	struct tpm_odd_nonce ononce;
 	int ret;
 
-	ret = tpm_get_random(chip, ononce, TPM_NONCE_SIZE);
-	if (ret != TPM_NONCE_SIZE)
+	ret = tpm_gen_odd_nonce(chip, &ononce);
+	if (ret < 0)
 		return ret;
 
 	INIT_BUF(tb);
@@ -414,7 +427,7 @@ static int tpm_create_osap(struct tpm_chip *chip,
 	store32(tb, TPM_ORD_OSAP);
 	store16(tb, keytype);
 	store32(tb, keyhandle);
-	storebytes(tb, ononce, TPM_NONCE_SIZE);
+	storebytes(tb, ononce.data, TPM_NONCE_SIZE);
 
 	ret = tpm_send_dump(chip, tb->data, MAX_BUF_SIZE,
 			    "creating OSAP session");
@@ -422,13 +435,13 @@ static int tpm_create_osap(struct tpm_chip *chip,
 		return ret;
 
 	s->handle = LOAD32(tb->data, TPM_DATA_OFFSET);
-	memcpy(s->enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)]),
+	memcpy(s->enonce.data, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)]),
 	       TPM_NONCE_SIZE);
-	memcpy(enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t) +
+	memcpy(enonce.data, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t) +
 				  TPM_NONCE_SIZE]), TPM_NONCE_SIZE);
 	return TSS_rawhmac(s->secret, keyauth, SHA1_DIGEST_SIZE,
-			   TPM_NONCE_SIZE, enonce,
-			   TPM_NONCE_SIZE, ononce,
+			   TPM_NONCE_SIZE, enonce.data,
+			   TPM_NONCE_SIZE, ononce.data,
 			   0, 0);
 }
 
@@ -436,7 +449,7 @@ static int tpm_create_osap(struct tpm_chip *chip,
  * Create an object independent authorisation protocol (oiap) session
  */
 static int tpm_create_oiap(struct tpm_chip *chip, struct tpm_buf *tb,
-			   uint32_t *handle, unsigned char *nonce)
+			   uint32_t *handle, struct tpm_even_nonce *enonce)
 {
 	int ret;
 
@@ -450,7 +463,7 @@ static int tpm_create_oiap(struct tpm_chip *chip, struct tpm_buf *tb,
 		return ret;
 
 	*handle = LOAD32(tb->data, TPM_DATA_OFFSET);
-	memcpy(nonce, &tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)],
+	memcpy(enonce->data, &tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)],
 	       TPM_NONCE_SIZE);
 	return 0;
 }
@@ -460,7 +473,7 @@ struct tpm_digests {
 	unsigned char pubauth[SHA1_DIGEST_SIZE];
 	unsigned char xorwork[SHA1_DIGEST_SIZE * 2];
 	unsigned char xorhash[SHA1_DIGEST_SIZE];
-	unsigned char nonceodd[TPM_NONCE_SIZE];
+	struct tpm_odd_nonce ononce;
 };
 
 /**
@@ -517,13 +530,13 @@ int tpm_seal(struct tpm_chip *chip,
 
 	/* calculate encrypted authorization value */
 	memcpy(td->xorwork, sess.secret, SHA1_DIGEST_SIZE);
-	memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce, SHA1_DIGEST_SIZE);
+	memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce.data, SHA1_DIGEST_SIZE);
 	ret = TSS_sha1(td->xorwork, SHA1_DIGEST_SIZE * 2, td->xorhash);
 	if (ret < 0)
 		goto out;
 
-	ret = tpm_get_random(chip, td->nonceodd, TPM_NONCE_SIZE);
-	if (ret != TPM_NONCE_SIZE)
+	ret = tpm_gen_odd_nonce(chip, &td->ononce);
+	if (ret < 0)
 		goto out;
 	ordinal = htonl(TPM_ORD_SEAL);
 	datsize = htonl(rawlen);
@@ -538,7 +551,7 @@ int tpm_seal(struct tpm_chip *chip,
 	if (pcrinfosize == 0) {
 		/* no pcr info specified */
 		ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE,
-				   sess.enonce, td->nonceodd, cont,
+				   &sess.enonce, &td->ononce, cont,
 				   sizeof(uint32_t), &ordinal,
 				   SHA1_DIGEST_SIZE, td->encauth,
 				   sizeof(uint32_t), &pcrsize,
@@ -548,7 +561,7 @@ int tpm_seal(struct tpm_chip *chip,
 	} else {
 		/* pcr info specified */
 		ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE,
-				   sess.enonce, td->nonceodd, cont,
+				   &sess.enonce, &td->ononce, cont,
 				   sizeof(uint32_t), &ordinal,
 				   SHA1_DIGEST_SIZE, td->encauth,
 				   sizeof(uint32_t), &pcrsize,
@@ -572,7 +585,7 @@ int tpm_seal(struct tpm_chip *chip,
 	store32(tb, rawlen);
 	storebytes(tb, rawdata, rawlen);
 	store32(tb, sess.handle);
-	storebytes(tb, td->nonceodd, TPM_NONCE_SIZE);
+	storebytes(tb, td->ononce.data, TPM_NONCE_SIZE);
 	store8(tb, cont);
 	storebytes(tb, td->pubauth, SHA1_DIGEST_SIZE);
 
@@ -589,7 +602,7 @@ int tpm_seal(struct tpm_chip *chip,
 	    sizeof(uint32_t) + encdatasize;
 
 	/* check the HMAC in the response */
-	ret = TSS_checkhmac1(tb->data, ordinal, td->nonceodd,
+	ret = TSS_checkhmac1(tb->data, ordinal, &td->ononce,
 			     sess.secret, SHA1_DIGEST_SIZE,
 			     storedsize, TPM_DATA_OFFSET,
 			     0, 0);
@@ -625,9 +638,9 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	       const unsigned char *decauth,
 	       unsigned char *rawbuffer, unsigned int *_rawlen)
 {
-	unsigned char nonceodd[TPM_NONCE_SIZE];
-	unsigned char enonce1[TPM_NONCE_SIZE];
-	unsigned char enonce2[TPM_NONCE_SIZE];
+	struct tpm_odd_nonce ononce;
+	struct tpm_even_nonce enonce1;
+	struct tpm_even_nonce enonce2;
 	unsigned char authdata1[SHA1_DIGEST_SIZE];
 	unsigned char authdata2[SHA1_DIGEST_SIZE];
 	uint32_t authhandle1 = 0;
@@ -638,12 +651,12 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	int ret;
 
 	/* sessions for unsealing key and data */
-	ret = tpm_create_oiap(chip, tb, &authhandle1, enonce1);
+	ret = tpm_create_oiap(chip, tb, &authhandle1, &enonce1);
 	if (ret < 0) {
 		pr_info("Failed to create OIAP 1 (%d)\n", ret);
 		return ret;
 	}
-	ret = tpm_create_oiap(chip, tb, &authhandle2, enonce2);
+	ret = tpm_create_oiap(chip, tb, &authhandle2, &enonce2);
 	if (ret < 0) {
 		pr_info("Failed to create OIAP 2 (%d)\n", ret);
 		return ret;
@@ -651,20 +664,18 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 
 	ordinal = htonl(TPM_ORD_UNSEAL);
 	keyhndl = htonl(SRKHANDLE);
-	ret = tpm_get_random(chip, nonceodd, TPM_NONCE_SIZE);
-	if (ret != TPM_NONCE_SIZE) {
-		pr_info("tpm_get_random failed (%d)\n", ret);
+	ret = tpm_gen_odd_nonce(chip, &ononce);
+	if (ret < 0)
 		return ret;
-	}
 	ret = TSS_authhmac(authdata1, keyauth, TPM_NONCE_SIZE,
-			   enonce1, nonceodd, cont,
+			   &enonce1, &ononce, cont,
 			   sizeof(uint32_t), &ordinal,
 			   enclen, encdata,
 			   0, 0);
 	if (ret < 0)
 		return ret;
 	ret = TSS_authhmac(authdata2, decauth, TPM_NONCE_SIZE,
-			   enonce2, nonceodd, cont,
+			   &enonce2, &ononce, cont,
 			   sizeof(uint32_t), &ordinal,
 			   enclen, encdata,
 			   0, 0);
@@ -679,11 +690,11 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	store32(tb, keyhandle);
 	storebytes(tb, encdata, enclen);
 	store32(tb, authhandle1);
-	storebytes(tb, nonceodd, TPM_NONCE_SIZE);
+	storebytes(tb, ononce.data, TPM_NONCE_SIZE);
 	store8(tb, cont);
 	storebytes(tb, authdata1, SHA1_DIGEST_SIZE);
 	store32(tb, authhandle2);
-	storebytes(tb, nonceodd, TPM_NONCE_SIZE);
+	storebytes(tb, ononce.data, TPM_NONCE_SIZE);
 	store8(tb, cont);
 	storebytes(tb, authdata2, SHA1_DIGEST_SIZE);
 
@@ -695,7 +706,7 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	}
 
 	*_rawlen = LOAD32(tb->data, TPM_DATA_OFFSET);
-	ret = TSS_checkhmac2(tb->data, ordinal, nonceodd,
+	ret = TSS_checkhmac2(tb->data, ordinal, &ononce,
 			     keyauth, SHA1_DIGEST_SIZE,
 			     decauth, SHA1_DIGEST_SIZE,
 			     sizeof(uint32_t), TPM_DATA_OFFSET,
diff --git a/drivers/char/tpm/tpm-library.h b/drivers/char/tpm/tpm-library.h
index 6f7571cc6d6c..ceb0ea1cd2bb 100644
--- a/drivers/char/tpm/tpm-library.h
+++ b/drivers/char/tpm/tpm-library.h
@@ -15,10 +15,18 @@
 #define LOAD32N(buffer, offset)	(*(uint32_t *)&buffer[offset])
 #define LOAD16(buffer, offset)	(ntohs(*(uint16_t *)&buffer[offset]))
 
+struct tpm_even_nonce {
+	unsigned char data[TPM_NONCE_SIZE];
+};
+
+struct tpm_odd_nonce {
+	unsigned char data[TPM_NONCE_SIZE];
+};
+
 struct tpm_osapsess {
 	uint32_t handle;
 	unsigned char secret[SHA1_DIGEST_SIZE];
-	unsigned char enonce[TPM_NONCE_SIZE];
+	struct tpm_even_nonce enonce;
 };
 
 static inline void store8(struct tpm_buf *buf, const unsigned char value)

WARNING: multiple messages have this Message-ID (diff)
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 12/23] TPMLIB: Create tpm_{even, odd}_nonce structs to represent nonces
Date: Tue, 21 Aug 2018 16:58:10 +0100	[thread overview]
Message-ID: <153486709034.13066.6676055815830934254.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <153486700916.13066.12870860668352070081.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>

Create a tpm_even_nonce struct and a tpm_odd_nonce struct to represent nonces
in internal routines rather than directly using char arrays.  Having two
separate structures helps keep track of which nonce is used where.

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

 drivers/char/tpm/tpm-library.c |  151 +++++++++++++++++++++-------------------
 drivers/char/tpm/tpm-library.h |   10 ++-
 2 files changed, 90 insertions(+), 71 deletions(-)

diff --git a/drivers/char/tpm/tpm-library.c b/drivers/char/tpm/tpm-library.c
index 7d1f55413f02..1c64282d1d0d 100644
--- a/drivers/char/tpm/tpm-library.c
+++ b/drivers/char/tpm/tpm-library.c
@@ -35,6 +35,19 @@ static atomic_t tpm_library_usage;
 static struct crypto_shash *tpm_hashalg;
 static struct crypto_shash *tpm_hmacalg;
 
+static int tpm_gen_odd_nonce(struct tpm_chip *chip,
+			     struct tpm_odd_nonce *ononce)
+{
+	int ret;
+
+	ret = tpm_get_random(chip, ononce->data, TPM_NONCE_SIZE);
+	if (ret == TPM_NONCE_SIZE)
+		ret = 0;
+	else
+		pr_info("tpm_get_random failed (%d)\n", ret);
+	return ret;
+}
+
 static struct tpm_sdesc *tpm_init_sdesc(struct crypto_shash *alg)
 {
 	struct tpm_sdesc *sdesc;
@@ -124,23 +137,25 @@ out:
  * @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
+ * @enonce: Even nonce
+ * @ononce: Odd nonce
+ * @cont: 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,
-			unsigned int keylen, unsigned char *h1,
-			unsigned char *h2, unsigned char h3, ...)
+static int TSS_authhmac(unsigned char *digest,
+			const unsigned char *key, unsigned keylen,
+			const struct tpm_even_nonce *enonce,
+			const struct tpm_odd_nonce *ononce,
+			unsigned char cont,
+			...)
 {
 	unsigned char paramdigest[SHA1_DIGEST_SIZE];
 	struct tpm_sdesc *sdesc;
 	unsigned int dlen;
 	unsigned char *data;
-	unsigned char c;
 	int ret;
 	va_list argp;
 
@@ -150,11 +165,10 @@ static int TSS_authhmac(unsigned char *digest, const unsigned char *key,
 		return PTR_ERR(sdesc);
 	}
 
-	c = h3;
 	ret = crypto_shash_init(&sdesc->shash);
 	if (ret < 0)
 		goto out;
-	va_start(argp, h3);
+	va_start(argp, cont);
 	for (;;) {
 		dlen = va_arg(argp, unsigned int);
 		if (dlen == 0)
@@ -174,9 +188,9 @@ static int TSS_authhmac(unsigned char *digest, const unsigned char *key,
 	if (!ret)
 		ret = TSS_rawhmac(digest, key, keylen,
 				  SHA1_DIGEST_SIZE, paramdigest,
-				  TPM_NONCE_SIZE, h1,
-				  TPM_NONCE_SIZE, h2,
-				  1, &c,
+				  TPM_NONCE_SIZE, enonce->data,
+				  TPM_NONCE_SIZE, ononce->data,
+				  1, &cont,
 				  0, 0);
 out:
 	kfree(sdesc);
@@ -188,15 +202,15 @@ out:
  */
 static int TSS_checkhmac1(unsigned char *buffer,
 			  const uint32_t command,
-			  const unsigned char *ononce,
-			  const unsigned char *key,
-			  unsigned int keylen, ...)
+			  const struct tpm_odd_nonce *ononce,
+			  const unsigned char *key, unsigned keylen,
+			  ...)
 {
 	uint32_t bufsize;
 	uint16_t tag;
 	uint32_t ordinal;
 	uint32_t result;
-	unsigned char *enonce;
+	struct tpm_even_nonce *enonce;
 	unsigned char *continueflag;
 	unsigned char *authdata;
 	unsigned char testhmac[SHA1_DIGEST_SIZE];
@@ -217,7 +231,7 @@ static int TSS_checkhmac1(unsigned char *buffer,
 		return -EINVAL;
 	authdata = buffer + bufsize - SHA1_DIGEST_SIZE;
 	continueflag = authdata - 1;
-	enonce = continueflag - TPM_NONCE_SIZE;
+	enonce = (void *)continueflag - TPM_NONCE_SIZE;
 
 	sdesc = tpm_init_sdesc(tpm_hashalg);
 	if (IS_ERR(sdesc)) {
@@ -253,8 +267,8 @@ static int TSS_checkhmac1(unsigned char *buffer,
 
 	ret = TSS_rawhmac(testhmac, key, keylen,
 			  SHA1_DIGEST_SIZE, paramdigest,
-			  TPM_NONCE_SIZE, enonce,
-			  TPM_NONCE_SIZE, ononce,
+			  TPM_NONCE_SIZE, enonce->data,
+			  TPM_NONCE_SIZE, ononce->data,
 			  1, continueflag,
 			  0, 0);
 	if (ret < 0)
@@ -270,24 +284,23 @@ out:
 /*
  * verify the AUTH2_COMMAND (unseal) result from TPM
  */
-static int TSS_checkhmac2(unsigned char *buffer,
+static int TSS_checkhmac2(const unsigned char *buffer,
 			  const uint32_t command,
-			  const unsigned char *ononce,
-			  const unsigned char *key1,
-			  unsigned int keylen1,
-			  const unsigned char *key2,
-			  unsigned int keylen2, ...)
+			  const struct tpm_odd_nonce *ononce,
+			  const unsigned char *key1, unsigned keylen1,
+			  const unsigned char *key2, unsigned keylen2,
+			  ...)
 {
 	uint32_t bufsize;
 	uint16_t tag;
 	uint32_t ordinal;
 	uint32_t result;
-	unsigned char *enonce1;
-	unsigned char *continueflag1;
-	unsigned char *authdata1;
-	unsigned char *enonce2;
-	unsigned char *continueflag2;
-	unsigned char *authdata2;
+	const struct tpm_even_nonce *enonce1;
+	const unsigned char *continueflag1;
+	const unsigned char *authdata1;
+	const struct tpm_even_nonce *enonce2;
+	const unsigned char *continueflag2;
+	const unsigned char *authdata2;
 	unsigned char testhmac1[SHA1_DIGEST_SIZE];
 	unsigned char testhmac2[SHA1_DIGEST_SIZE];
 	unsigned char paramdigest[SHA1_DIGEST_SIZE];
@@ -311,8 +324,8 @@ static int TSS_checkhmac2(unsigned char *buffer,
 	authdata2 = buffer + bufsize - (SHA1_DIGEST_SIZE);
 	continueflag1 = authdata1 - 1;
 	continueflag2 = authdata2 - 1;
-	enonce1 = continueflag1 - TPM_NONCE_SIZE;
-	enonce2 = continueflag2 - TPM_NONCE_SIZE;
+	enonce1 = (const void *)continueflag1 - TPM_NONCE_SIZE;
+	enonce2 = (const void *)continueflag2 - TPM_NONCE_SIZE;
 
 	sdesc = tpm_init_sdesc(tpm_hashalg);
 	if (IS_ERR(sdesc)) {
@@ -349,8 +362,8 @@ static int TSS_checkhmac2(unsigned char *buffer,
 
 	ret = TSS_rawhmac(testhmac1, key1, keylen1,
 			  SHA1_DIGEST_SIZE, paramdigest,
-			  TPM_NONCE_SIZE, enonce1,
-			  TPM_NONCE_SIZE, ononce,
+			  TPM_NONCE_SIZE, enonce1->data,
+			  TPM_NONCE_SIZE, ononce->data,
 			  1, continueflag1,
 			  0, 0);
 	if (ret < 0)
@@ -361,8 +374,8 @@ static int TSS_checkhmac2(unsigned char *buffer,
 	}
 	ret = TSS_rawhmac(testhmac2, key2, keylen2,
 			  SHA1_DIGEST_SIZE, paramdigest,
-			  TPM_NONCE_SIZE, enonce2,
-			  TPM_NONCE_SIZE, ononce,
+			  TPM_NONCE_SIZE, enonce2->data,
+			  TPM_NONCE_SIZE, ononce->data,
 			  1, continueflag2,
 			  0, 0);
 	if (ret < 0)
@@ -400,12 +413,12 @@ static int tpm_create_osap(struct tpm_chip *chip,
 			   const unsigned char *keyauth,
 			   enum tpm_entity_type keytype, uint32_t keyhandle)
 {
-	unsigned char enonce[TPM_NONCE_SIZE];
-	unsigned char ononce[TPM_NONCE_SIZE];
+	struct tpm_even_nonce enonce;
+	struct tpm_odd_nonce ononce;
 	int ret;
 
-	ret = tpm_get_random(chip, ononce, TPM_NONCE_SIZE);
-	if (ret != TPM_NONCE_SIZE)
+	ret = tpm_gen_odd_nonce(chip, &ononce);
+	if (ret < 0)
 		return ret;
 
 	INIT_BUF(tb);
@@ -414,7 +427,7 @@ static int tpm_create_osap(struct tpm_chip *chip,
 	store32(tb, TPM_ORD_OSAP);
 	store16(tb, keytype);
 	store32(tb, keyhandle);
-	storebytes(tb, ononce, TPM_NONCE_SIZE);
+	storebytes(tb, ononce.data, TPM_NONCE_SIZE);
 
 	ret = tpm_send_dump(chip, tb->data, MAX_BUF_SIZE,
 			    "creating OSAP session");
@@ -422,13 +435,13 @@ static int tpm_create_osap(struct tpm_chip *chip,
 		return ret;
 
 	s->handle = LOAD32(tb->data, TPM_DATA_OFFSET);
-	memcpy(s->enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)]),
+	memcpy(s->enonce.data, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)]),
 	       TPM_NONCE_SIZE);
-	memcpy(enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t) +
+	memcpy(enonce.data, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t) +
 				  TPM_NONCE_SIZE]), TPM_NONCE_SIZE);
 	return TSS_rawhmac(s->secret, keyauth, SHA1_DIGEST_SIZE,
-			   TPM_NONCE_SIZE, enonce,
-			   TPM_NONCE_SIZE, ononce,
+			   TPM_NONCE_SIZE, enonce.data,
+			   TPM_NONCE_SIZE, ononce.data,
 			   0, 0);
 }
 
@@ -436,7 +449,7 @@ static int tpm_create_osap(struct tpm_chip *chip,
  * Create an object independent authorisation protocol (oiap) session
  */
 static int tpm_create_oiap(struct tpm_chip *chip, struct tpm_buf *tb,
-			   uint32_t *handle, unsigned char *nonce)
+			   uint32_t *handle, struct tpm_even_nonce *enonce)
 {
 	int ret;
 
@@ -450,7 +463,7 @@ static int tpm_create_oiap(struct tpm_chip *chip, struct tpm_buf *tb,
 		return ret;
 
 	*handle = LOAD32(tb->data, TPM_DATA_OFFSET);
-	memcpy(nonce, &tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)],
+	memcpy(enonce->data, &tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)],
 	       TPM_NONCE_SIZE);
 	return 0;
 }
@@ -460,7 +473,7 @@ struct tpm_digests {
 	unsigned char pubauth[SHA1_DIGEST_SIZE];
 	unsigned char xorwork[SHA1_DIGEST_SIZE * 2];
 	unsigned char xorhash[SHA1_DIGEST_SIZE];
-	unsigned char nonceodd[TPM_NONCE_SIZE];
+	struct tpm_odd_nonce ononce;
 };
 
 /**
@@ -517,13 +530,13 @@ int tpm_seal(struct tpm_chip *chip,
 
 	/* calculate encrypted authorization value */
 	memcpy(td->xorwork, sess.secret, SHA1_DIGEST_SIZE);
-	memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce, SHA1_DIGEST_SIZE);
+	memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce.data, SHA1_DIGEST_SIZE);
 	ret = TSS_sha1(td->xorwork, SHA1_DIGEST_SIZE * 2, td->xorhash);
 	if (ret < 0)
 		goto out;
 
-	ret = tpm_get_random(chip, td->nonceodd, TPM_NONCE_SIZE);
-	if (ret != TPM_NONCE_SIZE)
+	ret = tpm_gen_odd_nonce(chip, &td->ononce);
+	if (ret < 0)
 		goto out;
 	ordinal = htonl(TPM_ORD_SEAL);
 	datsize = htonl(rawlen);
@@ -538,7 +551,7 @@ int tpm_seal(struct tpm_chip *chip,
 	if (pcrinfosize == 0) {
 		/* no pcr info specified */
 		ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE,
-				   sess.enonce, td->nonceodd, cont,
+				   &sess.enonce, &td->ononce, cont,
 				   sizeof(uint32_t), &ordinal,
 				   SHA1_DIGEST_SIZE, td->encauth,
 				   sizeof(uint32_t), &pcrsize,
@@ -548,7 +561,7 @@ int tpm_seal(struct tpm_chip *chip,
 	} else {
 		/* pcr info specified */
 		ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE,
-				   sess.enonce, td->nonceodd, cont,
+				   &sess.enonce, &td->ononce, cont,
 				   sizeof(uint32_t), &ordinal,
 				   SHA1_DIGEST_SIZE, td->encauth,
 				   sizeof(uint32_t), &pcrsize,
@@ -572,7 +585,7 @@ int tpm_seal(struct tpm_chip *chip,
 	store32(tb, rawlen);
 	storebytes(tb, rawdata, rawlen);
 	store32(tb, sess.handle);
-	storebytes(tb, td->nonceodd, TPM_NONCE_SIZE);
+	storebytes(tb, td->ononce.data, TPM_NONCE_SIZE);
 	store8(tb, cont);
 	storebytes(tb, td->pubauth, SHA1_DIGEST_SIZE);
 
@@ -589,7 +602,7 @@ int tpm_seal(struct tpm_chip *chip,
 	    sizeof(uint32_t) + encdatasize;
 
 	/* check the HMAC in the response */
-	ret = TSS_checkhmac1(tb->data, ordinal, td->nonceodd,
+	ret = TSS_checkhmac1(tb->data, ordinal, &td->ononce,
 			     sess.secret, SHA1_DIGEST_SIZE,
 			     storedsize, TPM_DATA_OFFSET,
 			     0, 0);
@@ -625,9 +638,9 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	       const unsigned char *decauth,
 	       unsigned char *rawbuffer, unsigned int *_rawlen)
 {
-	unsigned char nonceodd[TPM_NONCE_SIZE];
-	unsigned char enonce1[TPM_NONCE_SIZE];
-	unsigned char enonce2[TPM_NONCE_SIZE];
+	struct tpm_odd_nonce ononce;
+	struct tpm_even_nonce enonce1;
+	struct tpm_even_nonce enonce2;
 	unsigned char authdata1[SHA1_DIGEST_SIZE];
 	unsigned char authdata2[SHA1_DIGEST_SIZE];
 	uint32_t authhandle1 = 0;
@@ -638,12 +651,12 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	int ret;
 
 	/* sessions for unsealing key and data */
-	ret = tpm_create_oiap(chip, tb, &authhandle1, enonce1);
+	ret = tpm_create_oiap(chip, tb, &authhandle1, &enonce1);
 	if (ret < 0) {
 		pr_info("Failed to create OIAP 1 (%d)\n", ret);
 		return ret;
 	}
-	ret = tpm_create_oiap(chip, tb, &authhandle2, enonce2);
+	ret = tpm_create_oiap(chip, tb, &authhandle2, &enonce2);
 	if (ret < 0) {
 		pr_info("Failed to create OIAP 2 (%d)\n", ret);
 		return ret;
@@ -651,20 +664,18 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 
 	ordinal = htonl(TPM_ORD_UNSEAL);
 	keyhndl = htonl(SRKHANDLE);
-	ret = tpm_get_random(chip, nonceodd, TPM_NONCE_SIZE);
-	if (ret != TPM_NONCE_SIZE) {
-		pr_info("tpm_get_random failed (%d)\n", ret);
+	ret = tpm_gen_odd_nonce(chip, &ononce);
+	if (ret < 0)
 		return ret;
-	}
 	ret = TSS_authhmac(authdata1, keyauth, TPM_NONCE_SIZE,
-			   enonce1, nonceodd, cont,
+			   &enonce1, &ononce, cont,
 			   sizeof(uint32_t), &ordinal,
 			   enclen, encdata,
 			   0, 0);
 	if (ret < 0)
 		return ret;
 	ret = TSS_authhmac(authdata2, decauth, TPM_NONCE_SIZE,
-			   enonce2, nonceodd, cont,
+			   &enonce2, &ononce, cont,
 			   sizeof(uint32_t), &ordinal,
 			   enclen, encdata,
 			   0, 0);
@@ -679,11 +690,11 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	store32(tb, keyhandle);
 	storebytes(tb, encdata, enclen);
 	store32(tb, authhandle1);
-	storebytes(tb, nonceodd, TPM_NONCE_SIZE);
+	storebytes(tb, ononce.data, TPM_NONCE_SIZE);
 	store8(tb, cont);
 	storebytes(tb, authdata1, SHA1_DIGEST_SIZE);
 	store32(tb, authhandle2);
-	storebytes(tb, nonceodd, TPM_NONCE_SIZE);
+	storebytes(tb, ononce.data, TPM_NONCE_SIZE);
 	store8(tb, cont);
 	storebytes(tb, authdata2, SHA1_DIGEST_SIZE);
 
@@ -695,7 +706,7 @@ int tpm_unseal(struct tpm_chip *chip, struct tpm_buf *tb,
 	}
 
 	*_rawlen = LOAD32(tb->data, TPM_DATA_OFFSET);
-	ret = TSS_checkhmac2(tb->data, ordinal, nonceodd,
+	ret = TSS_checkhmac2(tb->data, ordinal, &ononce,
 			     keyauth, SHA1_DIGEST_SIZE,
 			     decauth, SHA1_DIGEST_SIZE,
 			     sizeof(uint32_t), TPM_DATA_OFFSET,
diff --git a/drivers/char/tpm/tpm-library.h b/drivers/char/tpm/tpm-library.h
index 6f7571cc6d6c..ceb0ea1cd2bb 100644
--- a/drivers/char/tpm/tpm-library.h
+++ b/drivers/char/tpm/tpm-library.h
@@ -15,10 +15,18 @@
 #define LOAD32N(buffer, offset)	(*(uint32_t *)&buffer[offset])
 #define LOAD16(buffer, offset)	(ntohs(*(uint16_t *)&buffer[offset]))
 
+struct tpm_even_nonce {
+	unsigned char data[TPM_NONCE_SIZE];
+};
+
+struct tpm_odd_nonce {
+	unsigned char data[TPM_NONCE_SIZE];
+};
+
 struct tpm_osapsess {
 	uint32_t handle;
 	unsigned char secret[SHA1_DIGEST_SIZE];
-	unsigned char enonce[TPM_NONCE_SIZE];
+	struct tpm_even_nonce enonce;
 };
 
 static inline void store8(struct tpm_buf *buf, const unsigned char value)


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

  parent reply	other threads:[~2018-08-21 15:58 UTC|newest]

Thread overview: 168+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-21 15:56 tpm: Provide a TPM access library David Howells
2018-08-21 15:56 ` David Howells
2018-08-21 15:56 ` David Howells
2018-08-21 15:56 ` David Howells
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
2018-08-21 15:56   ` David Howells
2018-08-21 15:56   ` David Howells
2018-08-21 15:56   ` David Howells
2018-08-21 18:30   ` Jason Gunthorpe
2018-08-21 18:30     ` Jason Gunthorpe
2018-08-21 18:30     ` Jason Gunthorpe
2018-08-21 18:30     ` Jason Gunthorpe
2018-08-24  6:24     ` Jarkko Sakkinen
2018-08-24  6:24       ` Jarkko Sakkinen
2018-08-24  6:24       ` Jarkko Sakkinen
2018-08-24  6:24       ` Jarkko Sakkinen
2018-08-24  6:25       ` Jarkko Sakkinen
2018-08-24  6:25         ` Jarkko Sakkinen
2018-08-24  6:25         ` Jarkko Sakkinen
2018-08-24  6:25         ` Jarkko Sakkinen
2018-08-24 11:22         ` Mimi Zohar
2018-08-24 11:22           ` Mimi Zohar
2018-08-24 11:22           ` Mimi Zohar
2018-08-24 11:22           ` Mimi Zohar
2018-08-24  6:19   ` Jarkko Sakkinen
2018-08-24  6:19     ` Jarkko Sakkinen
2018-08-24  6:19     ` Jarkko Sakkinen
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
2018-08-21 15:57   ` David Howells
2018-08-21 15:57   ` David Howells
2018-08-21 15:57   ` David Howells
2018-08-21 18:31   ` Jason Gunthorpe
2018-08-21 18:31     ` Jason Gunthorpe
2018-08-21 18:31     ` Jason Gunthorpe
2018-08-21 18:31     ` Jason Gunthorpe
2018-08-24  6:29     ` Jarkko Sakkinen
2018-08-24  6:29       ` Jarkko Sakkinen
2018-08-24  6:29       ` Jarkko Sakkinen
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
2018-08-21 15:57   ` David Howells
2018-08-21 15:57   ` David Howells
2018-08-21 15:57   ` David Howells
2018-08-24  6:30   ` Jarkko Sakkinen
2018-08-24  6:30     ` Jarkko Sakkinen
2018-08-24  6:30     ` Jarkko Sakkinen
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
2018-08-21 15:57   ` David Howells
2018-08-21 15:57   ` David Howells
2018-08-21 15:57   ` David Howells
2018-08-21 18:31   ` Jason Gunthorpe
2018-08-21 18:31     ` Jason Gunthorpe
2018-08-21 18:31     ` Jason Gunthorpe
2018-08-21 18:31     ` Jason Gunthorpe
2018-08-21 18:35   ` David Howells
2018-08-21 18:35     ` David Howells
2018-08-21 18:35     ` David Howells
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
2018-08-21 15:57   ` David Howells
2018-08-21 15:57   ` David Howells
2018-08-21 15:57   ` David Howells
2018-08-24  7:42   ` Jarkko Sakkinen
2018-08-24  7:42     ` Jarkko Sakkinen
2018-08-24  7:42     ` Jarkko Sakkinen
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   ` David Howells
2018-08-21 15:57   ` David Howells
2018-08-21 15:57   ` 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   ` David Howells
2018-08-21 15:57   ` David Howells
2018-08-21 15:57   ` David Howells
2018-08-21 15:57 ` [PATCH 08/23] TPMLIB: Break TPM bits out of security/keys/trusted.c David Howells
2018-08-21 15:57   ` David Howells
2018-08-21 15:57   ` David Howells
2018-08-21 15:57   ` David Howells
2018-08-24  7:52   ` Jarkko Sakkinen
2018-08-24  7:52     ` Jarkko Sakkinen
2018-08-24  7:52     ` Jarkko Sakkinen
2018-08-24  7:52     ` Jarkko Sakkinen
2018-08-24  8:49     ` Jarkko Sakkinen
2018-08-24  8:49       ` Jarkko Sakkinen
2018-08-24  8:49       ` Jarkko Sakkinen
2018-08-24  8:49       ` Jarkko Sakkinen
2018-08-24  9:33     ` David Howells
2018-08-24  9:33       ` David Howells
2018-08-24  9:33       ` David Howells
2018-08-24  9:33       ` David Howells
2018-08-27  8:25       ` Jarkko Sakkinen
2018-08-27  8:25         ` Jarkko Sakkinen
2018-08-27  8:25         ` Jarkko Sakkinen
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   ` David Howells
2018-08-21 15:57   ` David Howells
2018-08-21 15:57   ` David Howells
2018-08-21 15:57 ` [PATCH 10/23] TPMLIB: Better format calls to TSS_*hmac*() David Howells
2018-08-21 15:57   ` David Howells
2018-08-21 15:57   ` David Howells
2018-08-21 15:57   ` David Howells
2018-08-21 15:58 ` [PATCH 11/23] TPMLIB: Put banner comments on public TPM library functions David Howells
2018-08-21 15:58   ` David Howells
2018-08-21 15:58   ` David Howells
2018-08-21 15:58   ` 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   ` David Howells
2018-08-21 15:58   ` David Howells
2018-08-21 15:58 ` [PATCH 13/23] TPMLIB: Rename store8() and storebytes() David Howells
2018-08-21 15:58   ` David Howells
2018-08-21 15:58   ` David Howells
2018-08-21 15:58   ` 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   ` David Howells
2018-08-21 15:58   ` David Howells
2018-08-21 15:58   ` 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   ` David Howells
2018-08-21 15:58   ` David Howells
2018-08-21 15:58   ` 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   ` David Howells
2018-08-21 15:58   ` David Howells
2018-08-21 15:58   ` 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   ` David Howells
2018-08-21 15:58   ` David Howells
2018-08-21 15:58   ` 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   ` David Howells
2018-08-21 15:58   ` David Howells
2018-08-21 15:58   ` David Howells
2018-08-21 15:58 ` [PATCH 19/23] TPMLIB: Add some debugging code David Howells
2018-08-21 15:58   ` David Howells
2018-08-21 15:58   ` David Howells
2018-08-21 15:58   ` David Howells
2018-08-21 15:59 ` [PATCH 20/23] TPMLIB: Implement call to TPM_CreateWrapKey David Howells
2018-08-21 15:59   ` David Howells
2018-08-21 15:59   ` David Howells
2018-08-21 15:59   ` David Howells
2018-08-21 15:59 ` [PATCH 21/23] TPMLIB: Implement call to TPM_LoadKey2 David Howells
2018-08-21 15:59   ` David Howells
2018-08-21 15:59   ` David Howells
2018-08-21 15:59   ` David Howells
2018-08-21 15:59 ` [PATCH 22/23] TPMLIB: Provide call for TPM_FlushSpecific David Howells
2018-08-21 15:59   ` David Howells
2018-08-21 15:59   ` David Howells
2018-08-21 15:59   ` 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-21 15:59   ` David Howells
2018-08-21 15:59   ` David Howells
2018-08-21 15:59   ` David Howells
2018-08-22 14:19 ` tpm: Provide a TPM access library Jarkko Sakkinen
2018-08-22 14:19   ` Jarkko Sakkinen
2018-08-22 14:19   ` Jarkko Sakkinen
2018-08-22 14:19   ` Jarkko Sakkinen
2018-08-22 14:45 ` David Howells
2018-08-22 14:45   ` David Howells
2018-08-22 14:45   ` David Howells
2018-08-22 14:45   ` David Howells
2018-08-23 22:49   ` Jarkko Sakkinen
2018-08-23 22:49     ` Jarkko Sakkinen
2018-08-23 22:49     ` Jarkko Sakkinen
2018-08-23 22:49     ` Jarkko Sakkinen

Reply instructions:

You may reply publicly 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=153486709034.13066.6676055815830934254.stgit@warthog.procyon.org.uk \
    --to=dhowells@redhat.com \
    --cc=denkenz@gmail.com \
    --cc=jarkko.sakkinen@linux.intel.com \
    --cc=jejb@linux.vnet.ibm.com \
    --cc=keyrings@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=tpmdd-devel@lists.sourceforge.net \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.