Merge pull request #145 from tomoveu/zd11566-13

pull/148/head
David Garske 2021-03-01 13:15:35 -08:00 committed by GitHub
commit b3f3eadac8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 680 additions and 17 deletions

View File

@ -44,6 +44,14 @@ More information about how to test and use PCR attestation can be found in the i
## Parameter Encryption
### Key generation with encrypted authorization
Detailed information can be found in this file under section "Key generation"
### Secure vault for keys with encrypted NVRAM authorization
Detailed information can be found in this file under section "Storing keys into the TPM's NVRAM"
### TPM2.0 Quote with encrypted user data
Example for demonstrating how to use parameter encryption to protect the user data between the Host and the TPM.
@ -260,3 +268,29 @@ Loaded key to 0x80000001
```
The `keyload` tool takes only one argument, the filename of the stored key. Because the information what is key scheme (RSA or ECC) is contained within the key blob.
## Storing keys into the TPM's NVRAM
These examples demonstrates how to use the TPM as secure vault for keys. There are two programs, one to store a TPM key into the TPM's NVRAM and another to extract the key from the TPM's NVRAM. Both examples can use parameter encryption to protect from MITM attacks. The Non-volatile memory location is protected with a password authorization that is passed in encrypted form, when "-aes" or "-xor" is given on the commmand line.
Before running the examples, make sure there is a keyblob.bin generated using the keygen tool. The key can be of any type, RSA, ECC or symmetric. The example will store the private and public part. In case of a symmetric key the public part is meta data from the TPM. How to generate a key you can see above, in the description of the keygen example.
Typical output for storing and then reading an RSA key using parameter encryption:
```
$ ./examples/nvram/store -aes
TPM2_StartAuthSession: sessionHandle 0x2000000
Reading 840 bytes from keyblob.bin
Storing key at TPM NV index 0x1800202 with password protection
Public part = 616 bytes
Private part = 222 bytes
NV write succeeded
$ ./examples/nvram/read 616 222 -aes
TPM2_StartAuthSession: sessionHandle 0x2000000
Trying to read 616 bytes of public key part from NV
Trying to read 222 bytes of private key part from NV
Extraction of key from NVRAM at index 0x1800202 succeeded
```
The read example takes as first argument the size of the public part and as second argument the private part. This information is given from the store example. The "-aes" swiches triggers the use of parameter encryption.

View File

@ -11,6 +11,7 @@ include examples/timestamp/include.am
include examples/pcr/include.am
include examples/management/include.am
include examples/keygen/include.am
include examples/nvram/include.am
dist_example_DATA+= examples/README.md \
examples/tpm_io.c \

View File

@ -0,0 +1,26 @@
# vim:ft=automake
# All paths should be given relative to the root
if BUILD_EXAMPLES
noinst_HEADERS += examples/nvram/store.h
bin_PROGRAMS += examples/nvram/store
examples_nvram_store_SOURCES = examples/nvram/store.c \
examples/tpm_test_keys.c \
examples/tpm_io.c
examples_nvram_store_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
examples_nvram_store_DEPENDENCIES = src/libwolftpm.la
bin_PROGRAMS += examples/nvram/read
examples_nvram_read_SOURCES = examples/nvram/read.c \
examples/tpm_test_keys.c \
examples/tpm_io.c
examples_nvram_read_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
examples_nvram_read_DEPENDENCIES = src/libwolftpm.la
endif
dist_example_DATA+= examples/nvram/store.c
dist_example_DATA+= examples/nvram/read.c
DISTCLEANFILES+= examples/nvram/.libs/store
DISTCLEANFILES+= examples/nvram/.libs/read

View File

@ -0,0 +1,178 @@
/* read.c
*
* Copyright (C) 2006-2021 wolfSSL Inc.
*
* This file is part of wolfTPM.
*
* wolfTPM is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfTPM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* Tool and example for extracting a TPM key from the TPM's NVRAM
*
* NB: This example uses Parameter Encryption to protect
* the Password Authorization of the TPM NVRAM Index
*
**/
#include <wolftpm/tpm2_wrap.h>
#include <examples/nvram/store.h>
#include <examples/tpm_io.h>
#include <examples/tpm_test.h>
#include <examples/tpm_test_keys.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef WOLFTPM2_NO_WRAPPER
#define ARGC_PUB_SIZE 1
#define ARGC_PRIV_SIZE 2
#define ARGC_PARAM_ENC 3
/******************************************************************************/
/* --- BEGIN TPM Keygen Example -- */
/******************************************************************************/
static void usage(void)
{
printf("Expected usage:\n");
printf("./examples/nvram/read priv pub [-aes/-xor]\n");
printf("* priv: size in bytes of the private part of the key in NV\n");
printf("* pub: size in bytes of the public part of the key in NV\n");
printf("* -aes/xor: Use Parameter Encryption\n");
}
int TPM2_NVRAM_Read_Example(void* userCtx, int argc, char *argv[])
{
int rc;
WOLFTPM2_DEV dev;
WOLFTPM2_KEYBLOB keyBlob;
WOLFTPM2_SESSION tpmSession;
WOLFTPM2_HANDLE parent;
WOLFTPM2_NV nv;
TPM2B_AUTH auth;
word32 readSize;
int paramEncAlg = TPM_ALG_NULL;
if (argc > 2) {
XMEMSET(&keyBlob, 0, sizeof(keyBlob));
keyBlob.pub.size = atoi(argv[ARGC_PUB_SIZE]);
keyBlob.priv.size = atoi(argv[ARGC_PRIV_SIZE]);
if (argc == 4) {
if (XSTRNCMP(argv[ARGC_PARAM_ENC], "-aes", 4) == 0) {
paramEncAlg = TPM_ALG_CFB;
}
if (XSTRNCMP(argv[ARGC_PARAM_ENC], "-xor", 4) == 0) {
paramEncAlg = TPM_ALG_XOR;
}
argc--;
}
}
else {
usage();
return 0;
}
if (keyBlob.priv.size == 0 || keyBlob.pub.size == 0) {
printf("Specify size of private and public part of the key\n");
usage();
return 0;
}
XMEMSET(&tpmSession, 0, sizeof(tpmSession));
XMEMSET(&parent, 0, sizeof(parent));
XMEMSET(&auth, 0, sizeof(auth));
rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx);
if (rc != TPM_RC_SUCCESS) {
printf("\nwolfTPM2_Init failed\n");
goto exit;
}
if (paramEncAlg != TPM_ALG_NULL) {
/* Start TPM session for parameter encryption */
rc = wolfTPM2_StartSession(&dev, &tpmSession, NULL, NULL,
TPM_SE_HMAC, TPM_ALG_CFB);
if (rc != 0) goto exit;
printf("TPM2_StartAuthSession: sessionHandle 0x%x\n",
(word32)tpmSession.handle.hndl);
/* Set TPM session attributes for parameter encryption */
rc = wolfTPM2_SetAuthSession(&dev, 1, &tpmSession,
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt | TPMA_SESSION_continueSession));
if (rc != 0) goto exit;
}
auth.size = sizeof(gNvAuth)-1;
XMEMCPY(auth.buffer, gNvAuth, auth.size);
/* Prepare auth for NV Index */
XMEMSET(&nv, 0, sizeof(nv));
nv.handle.hndl = TPM2_DEMO_NVRAM_STORE_INDEX;
nv.handle.auth.size = auth.size;
XMEMCPY(nv.handle.auth.buffer, auth.buffer, auth.size);
readSize = keyBlob.pub.size;
printf("Trying to read %d bytes of public key part from NV\n", readSize);
rc = wolfTPM2_NVReadAuth(&dev, &nv, TPM2_DEMO_NVRAM_STORE_INDEX,
(byte*)&keyBlob.pub.publicArea, &readSize, 0);
if (rc != 0) goto exit;
readSize = keyBlob.priv.size;
printf("Trying to read %d bytes of private key part from NV\n", readSize);
rc = wolfTPM2_NVReadAuth(&dev, &nv, TPM2_DEMO_NVRAM_STORE_INDEX,
(byte*)&keyBlob.priv.buffer, &readSize, keyBlob.pub.size);
if (rc != 0) goto exit;
parent.hndl = TPM_RH_OWNER;
rc = wolfTPM2_NVDeleteAuth(&dev, &parent, TPM2_DEMO_NVRAM_STORE_INDEX);
if (rc != 0) goto exit;
printf("Extraction of key from NVRAM at index 0x%x succeeded\n" ,
TPM2_DEMO_NVRAM_STORE_INDEX);
exit:
if (rc != 0) {
printf("\nFailure 0x%x: %s\n\n", rc, wolfTPM2_GetRCString(rc));
}
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
wolfTPM2_Cleanup(&dev);
return rc;
}
/******************************************************************************/
/* --- END TPM NVRAM Store Example -- */
/******************************************************************************/
#endif /* !WOLFTPM2_NO_WRAPPER */
#ifndef NO_MAIN_DRIVER
int main(int argc, char *argv[])
{
int rc = NOT_COMPILED_IN;
#ifndef WOLFTPM2_NO_WRAPPER
rc = TPM2_NVRAM_Read_Example(NULL, argc, argv);
#else
printf("NVRAM code not compiled in\n");
(void)argc;
(void)argv;
#endif
return rc;
}
#endif

View File

@ -0,0 +1,170 @@
/* store.c
*
* Copyright (C) 2006-2021 wolfSSL Inc.
*
* This file is part of wolfTPM.
*
* wolfTPM is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfTPM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* Tool and example for storing a TPM key into the TPM's NVRAM
*
* NB: This example uses Parameter Encryption to protect the password of the
* TPM NVRAM Index, where the private and public parts of a TPM key is stored
*
**/
#include <wolftpm/tpm2_wrap.h>
#include <examples/nvram/store.h>
#include <examples/tpm_io.h>
#include <examples/tpm_test.h>
#include <examples/tpm_test_keys.h>
#include <stdio.h>
#ifndef WOLFTPM2_NO_WRAPPER
/******************************************************************************/
/* --- BEGIN TPM Keygen Example -- */
/******************************************************************************/
static void usage(void)
{
printf("Expected usage:\n");
printf("./examples/nvram/store [filename] [-aes/-xor]\n");
printf("* filename: point to a file containing a TPM key\n");
printf("\tIf not supplied, default filename is \"keyblob.bin\"\n");
printf("* -aes/xor: Use Parameter Encryption\n");
}
int TPM2_NVRAM_Store_Example(void* userCtx, int argc, char *argv[])
{
int rc;
WOLFTPM2_DEV dev;
WOLFTPM2_KEYBLOB keyBlob;
WOLFTPM2_SESSION tpmSession;
WOLFTPM2_HANDLE parent;
WOLFTPM2_NV nv;
TPM2B_AUTH auth;
word32 nvAttributes;
const char* filename = "keyblob.bin";
int paramEncAlg = TPM_ALG_NULL;
if (argc >= 2) {
if (XSTRNCMP(argv[1], "-?", 2) == 0 ||
XSTRNCMP(argv[1], "-h", 2) == 0 ||
XSTRNCMP(argv[1], "--help", 6) == 0) {
usage();
return 0;
}
if (argv[1][0] != '-') {
filename = argv[1];
}
}
while (argc > 1) {
if (XSTRNCMP(argv[argc-1], "-aes", 4) == 0) {
paramEncAlg = TPM_ALG_CFB;
}
if (XSTRNCMP(argv[argc-1], "-xor", 4) == 0) {
paramEncAlg = TPM_ALG_XOR;
}
argc--;
};
XMEMSET(&keyBlob, 0, sizeof(keyBlob));
XMEMSET(&tpmSession, 0, sizeof(tpmSession));
XMEMSET(&parent, 0, sizeof(parent));
XMEMSET(&auth, 0, sizeof(auth));
rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx);
if (rc != TPM_RC_SUCCESS) {
printf("\nwolfTPM2_Init failed\n");
goto exit;
}
if (paramEncAlg != TPM_ALG_NULL) {
/* Start TPM session for parameter encryption */
rc = wolfTPM2_StartSession(&dev, &tpmSession, NULL, NULL,
TPM_SE_HMAC, TPM_ALG_CFB);
if (rc != 0) goto exit;
printf("TPM2_StartAuthSession: sessionHandle 0x%x\n",
(word32)tpmSession.handle.hndl);
/* Set TPM session attributes for parameter encryption */
rc = wolfTPM2_SetAuthSession(&dev, 1, &tpmSession,
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt | TPMA_SESSION_continueSession));
if (rc != 0) goto exit;
}
rc = readKeyBlob(filename, &keyBlob);
if (rc != 0) goto exit;
/* Prepare NV_AUTHWRITE and NV_AUTHREAD attributes necessary for password */
parent.hndl = TPM_RH_OWNER;
rc = wolfTPM2_GetNvAttributesTemplate(parent.hndl, &nvAttributes);
if (rc != 0) goto exit;
/* Our wolfTPM2 wrapper for NV_Define */
rc = wolfTPM2_NVCreateAuth(&dev, &parent, &nv, TPM2_DEMO_NVRAM_STORE_INDEX,
nvAttributes, TPM2_DEMO_NV_TEST_SIZE, (byte*)gNvAuth, sizeof(gNvAuth)-1);
if (rc != 0 && rc != TPM_RC_NV_DEFINED) goto exit;
printf("Storing key at TPM NV index 0x%x with password protection\n",
TPM2_DEMO_NVRAM_STORE_INDEX);
printf("Public part = %d bytes\n", keyBlob.pub.size);
rc = wolfTPM2_NVWriteAuth(&dev, &nv, TPM2_DEMO_NVRAM_STORE_INDEX,
(byte*)&keyBlob.pub.publicArea, keyBlob.pub.size, 0);
if (rc != 0) goto exit;
printf("Private part = %d bytes\n", keyBlob.priv.size);
rc = wolfTPM2_NVWriteAuth(&dev, &nv, TPM2_DEMO_NVRAM_STORE_INDEX,
keyBlob.priv.buffer, keyBlob.priv.size, keyBlob.pub.size);
if (rc != 0) goto exit;
printf("NV write succeeded\n");
exit:
if (rc != 0) {
printf("\nFailure 0x%x: %s\n\n", rc, wolfTPM2_GetRCString(rc));
}
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
wolfTPM2_Cleanup(&dev);
return rc;
}
/******************************************************************************/
/* --- END TPM NVRAM Store Example -- */
/******************************************************************************/
#endif /* !WOLFTPM2_NO_WRAPPER */
#ifndef NO_MAIN_DRIVER
int main(int argc, char *argv[])
{
int rc = NOT_COMPILED_IN;
#ifndef WOLFTPM2_NO_WRAPPER
rc = TPM2_NVRAM_Store_Example(NULL, argc, argv);
#else
printf("NVRAM code not compiled in\n");
(void)argc;
(void)argv;
#endif
return rc;
}
#endif

View File

@ -0,0 +1,36 @@
/* store.h
*
* Copyright (C) 2006-2020 wolfSSL Inc.
*
* This file is part of wolfTPM.
*
* wolfTPM is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfTPM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _STORE_H_
#define _STORE_H_
#ifdef __cplusplus
extern "C" {
#endif
int TPM2_NVRAM_Store_Example(void* userCtx, int argc, char *argv[]);
int TPM2_NVRAM_Read_Example(void* userCtx, int argc, char *argv[]);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _Store_H_ */

View File

@ -32,7 +32,6 @@
/* Test Configuration */
#define TPM2_DEMO_STORAGE_KEY_HANDLE 0x81000200 /* Persistent Storage Key Handle (RSA) */
#define TPM2_DEMO_STORAGE_EC_KEY_HANDLE 0x81000201 /* Persistent Storage Key Handle (ECC) */
#define TPM2_DEMO_RSA_IDX 0x20 /* offset handle to unused index */
#define TPM2_DEMO_RSA_KEY_HANDLE (0x81000000 + TPM2_DEMO_RSA_IDX) /* Persistent Key Handle */
#define TPM2_DEMO_RSA_CERT_HANDLE (0x01800000 + TPM2_DEMO_RSA_IDX) /* NV Handle */
@ -43,6 +42,7 @@
#define TPM2_DEMO_NV_TEST_INDEX 0x01800200
#define TPM2_DEMO_NV_TEST_AUTH_INDEX 0x01800201
#define TPM2_DEMO_NVRAM_STORE_INDEX 0x01800202
#define TPM2_DEMO_NV_TEST_SIZE 1024 /* max size on Infineon SLB9670 is 1664 */
static const char gStorageKeyAuth[] = "ThisIsMyStorageKeyAuth";

View File

@ -278,6 +278,7 @@ int getRSAkey(WOLFTPM2_DEV* pDev,
}
#else
(void)pWolfRsaKey;
(void)tpmDevId;
#endif /* !WOLFTPM2_NO_WOLFCRYPT && !NO_RSA */
return rc;
@ -311,6 +312,7 @@ int getECCkey(WOLFTPM2_DEV* pDev,
}
#else
(void)pWolfEccKey;
(void)tpmDevId;
#endif /* !WOLFTPM2_NO_WRAPPER && HAVE_ECC */
return rc;

View File

@ -106,9 +106,10 @@ static int TPM2_CommandProcess(TPM2_CTX* ctx, TPM2_Packet* packet,
CmdInfo_t* info, TPM_CC cmdCode, UINT32 cmdSz)
{
int rc = TPM_RC_SUCCESS;
UINT32 authSz;
UINT32 authSz, handleValue;
BYTE *param, *encParam = NULL;
int paramSz, encParamSz = 0, authPos, i;
int paramSz, encParamSz = 0;
int i, authPos, handlePos;
/* Skip the header and handles area */
packet->pos = TPM2_HEADER_SIZE + (info->inHandleCnt * sizeof(TPM_HANDLE));
@ -187,9 +188,14 @@ static int TPM2_CommandProcess(TPM2_CTX* ctx, TPM2_Packet* packet,
}
#ifndef WOLFTPM2_NO_WOLFCRYPT
rc = TPM2_GetName(ctx, info->inHandleCnt, 0, &name1);
rc |= TPM2_GetName(ctx, info->inHandleCnt, 1, &name2);
rc |= TPM2_GetName(ctx, info->inHandleCnt, 2, &name3);
handlePos = packet->pos;
packet->pos = TPM2_HEADER_SIZE; /* Handles are right after header */
TPM2_Packet_ParseU32(packet, &handleValue);
packet->pos = handlePos;
rc = TPM2_GetName(ctx, handleValue, info->inHandleCnt, 0, &name1);
rc |= TPM2_GetName(ctx, handleValue, info->inHandleCnt, 1, &name2);
rc |= TPM2_GetName(ctx, handleValue, info->inHandleCnt, 2, &name3);
if (rc != TPM_RC_SUCCESS) {
#ifdef DEBUG_WOLFTPM
printf("Error getting names for cpHash!\n");
@ -217,6 +223,9 @@ static int TPM2_CommandProcess(TPM2_CTX* ctx, TPM2_Packet* packet,
#endif
return rc;
}
#else
(void)handleValue;
(void)handlePos;
#endif
}
@ -4609,9 +4618,10 @@ TPM_RC TPM2_NV_DefineSpace(NV_DefineSpace_In* in)
TPM2_Packet_AppendU32(&packet, in->authHandle);
info.authCnt = TPM2_Packet_AppendAuth(&packet, ctx);
/* 1st TPM2B parameter, TPM2B_AUTH different from Authorization Area */
TPM2_Packet_AppendU16(&packet, in->auth.size);
TPM2_Packet_AppendBytes(&packet, in->auth.buffer, in->auth.size);
/* 2nd TPM2B parameter, TPM2B_PUBLIC */
in->publicInfo.size = 4 + 2 + 4 + 2 +
in->publicInfo.nvPublic.authPolicy.size + 2;
TPM2_Packet_AppendU16(&packet, in->publicInfo.size);
@ -5268,7 +5278,7 @@ int TPM2_GetNonce(byte* nonceBuf, int nonceSz)
}
/* Get name for object/handle */
int TPM2_GetName(TPM2_CTX* ctx, int handleCnt, int idx, TPM2B_NAME* name)
int TPM2_GetName(TPM2_CTX* ctx, UINT32 handleValue, int handleCnt, int idx, TPM2B_NAME* name)
{
TPM2_AUTH_SESSION* session;
@ -5278,10 +5288,20 @@ int TPM2_GetName(TPM2_CTX* ctx, int handleCnt, int idx, TPM2B_NAME* name)
return TPM_RC_SUCCESS;
session = &ctx->session[idx];
if (session->name.size > 0) {
name->size = session->name.size;
XMEMCPY(name->name, session->name.name, name->size);
if ((handleValue >= TRANSIENT_FIRST) ||
(handleValue >= NV_INDEX_FIRST && handleValue <= NV_INDEX_LAST)) {
if (session->name.size > 0) {
name->size = session->name.size;
XMEMCPY(name->name, session->name.name, name->size);
}
}
else {
handleValue = TPM2_Packet_SwapU32(handleValue);
name->size = sizeof(handleValue);
XMEMCPY(name->name, (byte*)&handleValue, name->size);
}
#ifdef WOLFTPM_DEBUG_VERBOSE
printf("Name %d: %d\n", idx, name->size);
TPM2_PrintBin(name->name, name->size);
@ -5648,6 +5668,71 @@ UINT16 TPM2_GetVendorID(void)
return vid;
}
/* Stores nameAlg + the digest of nvPublic in buffer, total size in size */
int TPM2_HashNvPublic(TPMS_NV_PUBLIC* nvPublic, byte* buffer, UINT16* size)
{
#ifndef WOLFTPM2_NO_WOLFCRYPT
int rc;
int hashSize, nameAlgSize;
UINT16 nameAlgValue;
wc_HashAlg hash;
enum wc_HashType hashType;
byte appending[sizeof(TPMS_NV_PUBLIC)];
TPM2_Packet packet;
/* Prepare temporary buffer */
packet.buf = appending;
packet.pos = 0;
packet.size = sizeof(appending);
/* nvPublic must be in Marshaled state for hashing */
TPM2_Packet_AppendU32(&packet, nvPublic->nvIndex);
TPM2_Packet_AppendU16(&packet, nvPublic->nameAlg);
TPM2_Packet_AppendU32(&packet, nvPublic->attributes);
TPM2_Packet_AppendU16(&packet, nvPublic->authPolicy.size);
TPM2_Packet_AppendBytes(&packet, nvPublic->authPolicy.buffer,
nvPublic->authPolicy.size);
TPM2_Packet_AppendU16(&packet, nvPublic->dataSize);
/* Hashing nvPublic */
rc = TPM2_GetHashType(nvPublic->nameAlg);
hashType = (enum wc_HashType)rc;
rc = wc_HashGetDigestSize(hashType);
if (rc < 0) {
return rc;
}
hashSize = rc;
rc = wc_HashInit(&hash, hashType);
if (rc == 0) {
rc = wc_HashUpdate(&hash, hashType, packet.buf, packet.pos);
}
if (rc == 0) {
rc = wc_HashFinal(&hash, hashType, &buffer[2]);
}
if (rc == 0) {
/* Concatenate the nvPublic digest with nameAlg at the front */
nameAlgValue = TPM2_Packet_SwapU16(nvPublic->nameAlg);
nameAlgSize = sizeof(nvPublic->nameAlg);
XMEMCPY(buffer, (byte*)&nameAlgValue, nameAlgSize);
/* account for nameAlg concatenation */
*size = hashSize + nameAlgSize;
rc = TPM_RC_SUCCESS;
}
wc_HashFree(&hash, hashType);
return rc;
#else
(void)nvPublic;
(void)buffer;
(void)size;
return TPM_RC_SUCCESS;
#endif
}
#ifdef DEBUG_WOLFTPM
#define LINE_LEN 16
void TPM2_PrintBin(const byte* buffer, word32 length)
@ -5686,6 +5771,20 @@ void TPM2_PrintBin(const byte* buffer, word32 length)
length -= sz;
}
}
void TPM2_PrintAuth(const TPMS_AUTH_COMMAND* authCmd)
{
if (authCmd == NULL)
return;
printf("authCmd:\n");
printf("sessionHandle=0x%08X\n", authCmd->sessionHandle);
printf("nonceSize=%u nonceBuffer:\n", authCmd->nonce.size);
TPM2_PrintBin(authCmd->nonce.buffer, authCmd->nonce.size);
printf("sessionAttributes=0x%02X\n", authCmd->sessionAttributes);
printf("hmacSize=%u hmacBuffer:\n", authCmd->hmac.size);
TPM2_PrintBin(authCmd->hmac.buffer, authCmd->hmac.size);
}
#endif
/******************************************************************************/

View File

@ -320,6 +320,10 @@ void TPM2_Packet_AppendAuthCmd(TPM2_Packet* packet, TPMS_AUTH_COMMAND* authCmd)
if (packet == NULL || authCmd == NULL)
return;
#ifdef WOLFTPM_DEBUG_VERBOSE
TPM2_PrintAuth(authCmd);
#endif
/* make sure continueSession is set for TPM_RS_PW */
if (authCmd->sessionHandle == TPM_RS_PW &&
(authCmd->sessionAttributes & TPMA_SESSION_continueSession) == 0) {

View File

@ -27,6 +27,7 @@
/* For some struct to buffer conversions */
#include <wolftpm/tpm2_packet.h>
/* Local Functions */
static int wolfTPM2_GetCapabilities_NoDev(WOLFTPM2_CAPS* cap);
@ -369,13 +370,27 @@ int wolfTPM2_GetCapabilities(WOLFTPM2_DEV* dev, WOLFTPM2_CAPS* cap)
return wolfTPM2_GetCapabilities_NoDev(cap);
}
int wolfTPM2_UnsetAuth(WOLFTPM2_DEV* dev, int index)
{
TPM2_AUTH_SESSION* session;
if (dev == NULL || index >= MAX_SESSION_NUM || index < 0) {
return BAD_FUNC_ARG;
}
session = &dev->session[index];
XMEMSET(session, 0, sizeof(TPM2_AUTH_SESSION));
return TPM2_SetSessionAuth(dev->session);
}
int wolfTPM2_SetAuth(WOLFTPM2_DEV* dev, int index,
TPM_HANDLE sessionHandle, const TPM2B_AUTH* auth,
TPMA_SESSION sessionAttributes, const TPM2B_NAME* name)
{
TPM2_AUTH_SESSION* session;
if (dev == NULL || index >= MAX_SESSION_NUM) {
if (dev == NULL || index >= MAX_SESSION_NUM || index < 0) {
return BAD_FUNC_ARG;
}
@ -415,6 +430,24 @@ int wolfTPM2_SetAuthHandle(WOLFTPM2_DEV* dev, int index,
return wolfTPM2_SetAuth(dev, index, TPM_RS_PW, auth, 0, name);
}
int wolfTPM2_SetAuthHandleName(WOLFTPM2_DEV* dev, int index,
const WOLFTPM2_HANDLE* handle)
{
const TPM2B_NAME* name = NULL;
TPM2_AUTH_SESSION* session;
if (dev == NULL || handle == NULL || index >= MAX_SESSION_NUM) {
return BAD_FUNC_ARG;
}
name = &handle->name;
session = &dev->session[index];
session->name.size = name->size;
XMEMCPY(session->name.name, name->name, session->name.size);
return TPM_RC_SUCCESS;
}
int wolfTPM2_SetAuthSession(WOLFTPM2_DEV* dev, int index,
const WOLFTPM2_SESSION* tpmSession, TPMA_SESSION sessionAttributes)
{
@ -446,6 +479,15 @@ int wolfTPM2_SetAuthSession(WOLFTPM2_DEV* dev, int index,
session->nonceTPM.size = tpmSession->nonceTPM.size;
XMEMCPY(session->nonceTPM.buffer, tpmSession->nonceTPM.buffer,
session->nonceTPM.size);
/* Parameter Encryption session will have an hmac added later.
* Reserve space, the same way it was done for nonceCaller above.
*/
if (session->sessionHandle != TPM_RS_PW &&
((session->sessionAttributes & TPMA_SESSION_encrypt) ||
(session->sessionAttributes & TPMA_SESSION_decrypt))) {
session->auth.size = TPM2_GetHashDigestSize(session->authHash);
}
}
return rc;
}
@ -2560,9 +2602,19 @@ int wolfTPM2_NVCreateAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent,
return rc;
}
XMEMSET(nv, 0, sizeof(*nv));
/* Compute NV Index name in case of parameter encryption */
rc = TPM2_HashNvPublic(&in.publicInfo.nvPublic,
(byte*)&nv->handle.name.name,
&nv->handle.name.size);
if (rc != TPM_RC_SUCCESS) {
return rc;
}
/* return new NV handle */
nv->handle.hndl = (TPM_HANDLE)nvIndex;
nv->handle.auth = in.auth;
/* nv->handle.name already populated by TPM2_HashNvPublic above */
#ifdef DEBUG_WOLFTPM
printf("TPM2_NV_DefineSpace: Auth 0x%x, Idx 0x%x, Attribs 0x%d, Size %d\n",
@ -2596,6 +2648,7 @@ int wolfTPM2_NVWriteAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv,
int rc = TPM_RC_SUCCESS;
word32 pos = 0, towrite;
NV_Write_In in;
TPMS_NV_PUBLIC nvPublic;
if (dev == NULL || nv == NULL)
return BAD_FUNC_ARG;
@ -2605,6 +2658,30 @@ int wolfTPM2_NVWriteAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv,
wolfTPM2_SetAuthHandle(dev, 0, &nv->handle);
}
/* Read the NV Index publicArea to have up to date NV Index Name */
rc = wolfTPM2_NVReadPublic(dev, nv->handle.hndl, &nvPublic);
if (rc != TPM_RC_SUCCESS) {
#ifdef DEBUG_WOLFTPM
printf("Failed to read fresh NvPublic\n");
#endif
return TPM_RC_FAILURE;
}
/* Compute NV Index name in case of parameter encryption */
rc = TPM2_HashNvPublic(&nvPublic, (byte*)&nv->handle.name.name,
&nv->handle.name.size);
if (rc != TPM_RC_SUCCESS) {
return rc;
}
/* Necessary, because NVWrite has two handles, second is NV Index */
rc = wolfTPM2_SetAuthHandleName(dev, 0, &nv->handle);
rc |= wolfTPM2_SetAuthHandleName(dev, 1, &nv->handle);
if (rc != TPM_RC_SUCCESS) {
printf("Storing NV Index Name failed\n");
return TPM_RC_FAILURE;
}
while (dataSz > 0) {
towrite = dataSz;
if (towrite > MAX_NV_BUFFER_SIZE)
@ -2629,7 +2706,8 @@ int wolfTPM2_NVWriteAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv,
#ifdef DEBUG_WOLFTPM
printf("TPM2_NV_Write: Auth 0x%x, Idx 0x%x, Offset %d, Size %d\n",
(word32)in.authHandle, (word32)in.nvIndex, in.offset, in.data.size);
(word32)in.authHandle, (word32)in.nvIndex,
in.offset, in.data.size);
#endif
pos += towrite;
@ -2656,6 +2734,7 @@ int wolfTPM2_NVReadAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv,
word32 pos = 0, toread, dataSz;
NV_Read_In in;
NV_Read_Out out;
TPMS_NV_PUBLIC nvPublic;
if (dev == NULL || nv == NULL || pDataSz == NULL)
return BAD_FUNC_ARG;
@ -2665,6 +2744,30 @@ int wolfTPM2_NVReadAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv,
wolfTPM2_SetAuthHandle(dev, 0, &nv->handle);
}
/* Read the NV Index publicArea to have up to date NV Index Name */
rc = wolfTPM2_NVReadPublic(dev, nv->handle.hndl, &nvPublic);
if (rc != TPM_RC_SUCCESS) {
#ifdef DEBUG_WOLFTPM
printf("Failed to read fresh NvPublic\n");
#endif
return TPM_RC_FAILURE;
}
/* Compute NV Index name in case of parameter encryption */
rc = TPM2_HashNvPublic(&nvPublic, (byte*)&nv->handle.name.name,
&nv->handle.name.size);
if (rc != TPM_RC_SUCCESS) {
return rc;
}
/* Necessary, because NVWrite has two handles, second is NV Index */
rc = wolfTPM2_SetAuthHandleName(dev, 0, &nv->handle);
rc |= wolfTPM2_SetAuthHandleName(dev, 1, &nv->handle);
if (rc != TPM_RC_SUCCESS) {
printf("Storing NV Index Name failed\n");
return TPM_RC_FAILURE;
}
dataSz = *pDataSz;
while (dataSz > 0) {
@ -2773,6 +2876,9 @@ int wolfTPM2_NVDeleteAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent,
/* set session auth for key */
if (dev->ctx.session) {
wolfTPM2_SetAuthHandle(dev, 0, parent);
/* Make sure no other auth sessions exist */
wolfTPM2_UnsetAuth(dev, 1);
wolfTPM2_UnsetAuth(dev, 2);
}
XMEMSET(&in, 0, sizeof(in));
@ -3768,9 +3874,11 @@ int wolfTPM2_GetNvAttributesTemplate(TPM_HANDLE auth, word32* nvAttributes)
return BAD_FUNC_ARG;
*nvAttributes = (
TPMA_NV_AUTHWRITE | TPMA_NV_OWNERWRITE | /* write allowed */
TPMA_NV_AUTHREAD | TPMA_NV_OWNERREAD | /* read allowed */
TPMA_NV_NO_DA /* no dictionary attack */
TPMA_NV_AUTHWRITE | /* password or HMAC can authorize writing */
TPMA_NV_AUTHREAD | /* password or HMAC can authorize reading */
TPMA_NV_OWNERWRITE | /* Owner Hierarchy auth can be used also */
TPMA_NV_OWNERREAD | /* Owner Hierarchy auth for read */
TPMA_NV_NO_DA /* Don't increment dictionary attack counter */
);
if (auth == TPM_RH_PLATFORM) {

View File

@ -2800,7 +2800,8 @@ WOLFTPM_API int TPM2_GetTpmCurve(int curveID);
WOLFTPM_API int TPM2_GetWolfCurve(int curve_id);
WOLFTPM_API int TPM2_ParseAttest(const TPM2B_ATTEST* in, TPMS_ATTEST* out);
WOLFTPM_LOCAL int TPM2_GetName(TPM2_CTX* ctx, int handleCnt, int idx, TPM2B_NAME* name);
WOLFTPM_LOCAL int TPM2_GetName(TPM2_CTX* ctx, UINT32 handleValue, int handleCnt, int idx, TPM2B_NAME* name);
WOLFTPM_API int TPM2_HashNvPublic(TPMS_NV_PUBLIC* nvPublic, byte* buffer, UINT16* size);
#ifdef WOLFTPM2_USE_WOLF_RNG
WOLFTPM_API int TPM2_GetWolfRng(WC_RNG** rng);
@ -2819,8 +2820,10 @@ WOLFTPM_API UINT16 TPM2_GetVendorID(void);
#ifdef DEBUG_WOLFTPM
WOLFTPM_API void TPM2_PrintBin(const byte* buffer, word32 length);
WOLFTPM_API void TPM2_PrintAuth(const TPMS_AUTH_COMMAND* authCmd);
#else
#define TPM2_PrintBin(b, l)
#define TPM2_PrintAuth(b, l)
#endif
#ifdef __cplusplus

View File

@ -131,6 +131,7 @@ WOLFTPM_API int wolfTPM2_GetTpmDevId(WOLFTPM2_DEV* dev);
WOLFTPM_API int wolfTPM2_SelfTest(WOLFTPM2_DEV* dev);
WOLFTPM_API int wolfTPM2_GetCapabilities(WOLFTPM2_DEV* dev, WOLFTPM2_CAPS* caps);
WOLFTPM_API int wolfTPM2_UnsetAuth(WOLFTPM2_DEV* dev, int index);
WOLFTPM_API int wolfTPM2_SetAuth(WOLFTPM2_DEV* dev, int index,
TPM_HANDLE sessionHandle, const TPM2B_AUTH* auth, TPMA_SESSION sessionAttributes,
const TPM2B_NAME* name);
@ -138,6 +139,7 @@ WOLFTPM_API int wolfTPM2_SetAuthPassword(WOLFTPM2_DEV* dev, int index, const TPM
WOLFTPM_API int wolfTPM2_SetAuthHandle(WOLFTPM2_DEV* dev, int index, const WOLFTPM2_HANDLE* handle);
WOLFTPM_API int wolfTPM2_SetAuthSession(WOLFTPM2_DEV* dev, int index,
const WOLFTPM2_SESSION* tpmSession, TPMA_SESSION sessionAttributes);
WOLFTPM_API int wolfTPM2_SetAuthHandleName(WOLFTPM2_DEV* dev, int index, const WOLFTPM2_HANDLE* handle);
WOLFTPM_API int wolfTPM2_StartSession(WOLFTPM2_DEV* dev,
WOLFTPM2_SESSION* session, WOLFTPM2_KEY* tpmKey,