mirror of https://github.com/wolfSSL/wolfTPM.git
add external nvram policy sealing example, fix wolfTPM2_SealWithAuthSigNV
wolfTPM2_SealWithAuthSigNV needs to have PolicyPCR called as a part of its logic since it uses wolfTPM2_SetAuthPassword, which interferes with the policy digestpull/267/head
parent
75e373c80a
commit
6678ea7c4b
|
@ -63,6 +63,8 @@ examples/keygen/keyimport
|
|||
examples/nvram/store
|
||||
examples/nvram/read
|
||||
examples/nvram/counter
|
||||
examples/nvram/seal_policy_auth_nv
|
||||
examples/nvram/seal_policy_auth_nv_external
|
||||
examples/gpio/gpio_config
|
||||
examples/gpio/gpio_set
|
||||
examples/gpio/gpio_read
|
||||
|
@ -70,7 +72,6 @@ examples/gpio/gpio_nuvoton
|
|||
examples/seal/seal
|
||||
examples/seal/unseal
|
||||
examples/seal/seal_policy_auth
|
||||
examples/seal/seal_policy_auth_nv
|
||||
examples/attestation/make_credential
|
||||
examples/attestation/activate_credential
|
||||
|
||||
|
|
|
@ -28,6 +28,12 @@ examples_nvram_seal_policy_auth_nv_SOURCES = examples/nvram/seal_policy_aut
|
|||
examples_nvram_seal_policy_auth_nv_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
|
||||
examples_nvram_seal_policy_auth_nv_DEPENDENCIES = src/libwolftpm.la
|
||||
|
||||
noinst_PROGRAMS += examples/nvram/seal_policy_auth_nv_external
|
||||
examples_nvram_seal_policy_auth_nv_external_SOURCES = examples/nvram/seal_policy_auth_nv_external.c \
|
||||
examples/tpm_test_keys.c
|
||||
examples_nvram_seal_policy_auth_nv_external_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
|
||||
examples_nvram_seal_policy_auth_nv_external_DEPENDENCIES = src/libwolftpm.la
|
||||
|
||||
endif
|
||||
|
||||
example_nvramdir = $(exampledir)/nvram
|
||||
|
@ -35,7 +41,8 @@ dist_example_nvram_DATA = \
|
|||
examples/nvram/store.c \
|
||||
examples/nvram/read.c \
|
||||
examples/nvram/counter.c \
|
||||
examples/nvram/seal_policy_auth_nv.c
|
||||
examples/nvram/seal_policy_auth_nv.c \
|
||||
examples/nvram/seal_policy_auth_nv_external.c
|
||||
|
||||
DISTCLEANFILES+= examples/nvram/.libs/store
|
||||
DISTCLEANFILES+= examples/nvram/.libs/read
|
||||
|
|
|
@ -30,6 +30,7 @@ int TPM2_NVRAM_Store_Example(void* userCtx, int argc, char *argv[]);
|
|||
int TPM2_NVRAM_Read_Example(void* userCtx, int argc, char *argv[]);
|
||||
int TPM2_NVRAM_Counter_Example(void* userCtx, int argc, char *argv[]);
|
||||
int TPM2_PCR_Seal_With_Policy_Auth_NV_Test(void* userCtx, int argc, char *argv[]);
|
||||
int TPM2_PCR_Seal_With_Policy_Auth_NV_External_Test(void* userCtx, int argc, char *argv[]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
|
@ -0,0 +1,340 @@
|
|||
/* seal_policy_auth_nv.c
|
||||
*
|
||||
* Copyright (C) 2006-2023 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
|
||||
*/
|
||||
|
||||
/* This is a helper tool for setting policies on a TPM 2.0 PCR */
|
||||
|
||||
#include <wolftpm/tpm2_wrap.h>
|
||||
|
||||
#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(WOLFSSL_PUBLIC_MP)
|
||||
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/wolfcrypt/sha256.h>
|
||||
#include <wolfssl/wolfcrypt/hash.h>
|
||||
#include <wolfssl/wolfcrypt/ecc.h>
|
||||
|
||||
#include <examples/nvram/nvram.h>
|
||||
#include <hal/tpm_io.h>
|
||||
#include <examples/tpm_test.h>
|
||||
#include <examples/tpm_test_keys.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/******************************************************************************/
|
||||
/* --- BEGIN TPM2.0 PCR Policy example tool -- */
|
||||
/******************************************************************************/
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
printf("Expected usage:\n");
|
||||
printf("./examples/pcr/policy [-aes/xor] [pcr]\n");
|
||||
printf("* pcr: PCR index between 0-23 (default %d)\n", 16);
|
||||
printf("* -aes/xor: Use Parameter Encryption\n");
|
||||
}
|
||||
|
||||
static const word32 sealNvIndex = TPM2_DEMO_NV_TEST_INDEX;
|
||||
static const word32 policyDigestNvIndex = TPM2_DEMO_NV_TEST_INDEX + 1;
|
||||
|
||||
int TPM2_PCR_Seal_With_Policy_Auth_NV_External_Test(void* userCtx, int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
int rc = -1;
|
||||
WOLFTPM2_NV nv;
|
||||
WOLFTPM2_DEV dev;
|
||||
WOLFTPM2_KEY storage;
|
||||
WOLFTPM2_SESSION tpmSession;
|
||||
WOLFTPM2_KEY authKey;
|
||||
TPMT_PUBLIC authTemplate;
|
||||
/* default to aes since parm encryption is required */
|
||||
TPM_ALG_ID paramEncAlg = TPM_ALG_CFB;
|
||||
word32 pcrIndex = 16;
|
||||
word32 pcrArray[48];
|
||||
word32 pcrArraySz = 0;
|
||||
byte secret[16];
|
||||
byte secretOut[16];
|
||||
word32 secretOutSz = (word32)sizeof(secretOut);
|
||||
wc_Sha256 sha;
|
||||
byte zeroExpiry[4];
|
||||
byte hash[WC_SHA256_DIGEST_SIZE];
|
||||
ecc_key external_key;
|
||||
WC_RNG rng;
|
||||
byte sig[256];
|
||||
word32 sigSz = 256;
|
||||
byte qx[32];
|
||||
word32 qxSz = 32;
|
||||
byte qy[32];
|
||||
word32 qySz = 32;
|
||||
mp_int r, s;
|
||||
|
||||
XMEMSET(&dev, 0, sizeof(WOLFTPM2_DEV));
|
||||
XMEMSET(&storage, 0, sizeof(WOLFTPM2_KEY));
|
||||
XMEMSET(&tpmSession, 0, sizeof(WOLFTPM2_SESSION));
|
||||
XMEMSET(&nv, 0, sizeof(nv));
|
||||
XMEMSET(&authKey, 0, sizeof(WOLFTPM2_KEY));
|
||||
XMEMSET(&authTemplate, 0, sizeof(TPMT_PUBLIC));
|
||||
XMEMSET(zeroExpiry, 0, sizeof(zeroExpiry));
|
||||
|
||||
for (i = 0; i < (int)sizeof(secret); i++) {
|
||||
secret[i] = i;
|
||||
}
|
||||
|
||||
if (argc >= 2) {
|
||||
if (XSTRCMP(argv[1], "-?") == 0 ||
|
||||
XSTRCMP(argv[1], "-h") == 0 ||
|
||||
XSTRCMP(argv[1], "--help") == 0) {
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
while (argc > 1) {
|
||||
if (XSTRCMP(argv[argc-1], "-aes") == 0) {
|
||||
paramEncAlg = TPM_ALG_CFB;
|
||||
}
|
||||
else if (XSTRCMP(argv[argc-1], "-xor") == 0) {
|
||||
paramEncAlg = TPM_ALG_XOR;
|
||||
}
|
||||
else if (argv[argc-1][0] != '-') {
|
||||
/* TODO: Allow selection of multiple PCR's SHA-1 or SHA2-256 */
|
||||
pcrIndex = XATOI(argv[argc-1]);
|
||||
if (pcrIndex > PCR_LAST) {
|
||||
printf("PCR index is out of range (0-23)\n");
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
pcrArray[pcrArraySz] = pcrIndex;
|
||||
pcrArraySz++;
|
||||
}
|
||||
else {
|
||||
printf("Warning: Unrecognized option: %s\n", argv[argc-1]);
|
||||
}
|
||||
argc--;
|
||||
}
|
||||
|
||||
if (pcrArraySz == 0) {
|
||||
pcrArray[pcrArraySz] = 16;
|
||||
pcrArraySz++;
|
||||
}
|
||||
|
||||
printf("Example for sealing data to NV memory with policy authorization\n");
|
||||
printf("\tPCR Indicies:");
|
||||
|
||||
for (i = 0; i < (int)pcrArraySz; i++) {
|
||||
printf("%d ", pcrArray[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
printf("\tUse Parameter Encryption: %s\n", TPM2_GetAlgName(paramEncAlg));
|
||||
|
||||
rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx);
|
||||
if (rc != TPM_RC_SUCCESS) {
|
||||
printf("wolfTPM2_Init failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
|
||||
goto exit;
|
||||
}
|
||||
printf("wolfTPM2_Init: success\n");
|
||||
|
||||
/* get SRK */
|
||||
rc = getPrimaryStoragekey(&dev, &storage, TPM_ALG_RSA);
|
||||
if (rc != 0) goto exit;
|
||||
|
||||
/* session is required for pcr authorization */
|
||||
/* Start an authenticated policy session (salted / unbound) */
|
||||
rc = wolfTPM2_StartSession(&dev, &tpmSession, NULL, NULL,
|
||||
TPM_SE_POLICY, paramEncAlg);
|
||||
if (rc != 0) goto exit;
|
||||
printf("TPM2_StartAuthSession: sessionHandle 0x%x\n",
|
||||
(word32)tpmSession.handle.hndl);
|
||||
|
||||
/* set session for authorization of the storage key */
|
||||
rc = wolfTPM2_SetAuthSession(&dev, 0, &tpmSession,
|
||||
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt |
|
||||
TPMA_SESSION_continueSession));
|
||||
if (rc != 0) goto exit;
|
||||
|
||||
/* init rng */
|
||||
rc = wc_InitRng(&rng);
|
||||
if (rc != 0) {
|
||||
printf("wc_InitRng failed\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* hash the zero expiry */
|
||||
rc = wc_InitSha256(&sha);
|
||||
if (rc != 0) {
|
||||
printf("wc_InitSha256 failed\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rc = wc_Sha256Update(&sha, zeroExpiry, sizeof(zeroExpiry));
|
||||
if (rc != 0) {
|
||||
printf("wc_Sha256Update failed\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rc = wc_Sha256Final(&sha, hash);
|
||||
if (rc != 0) {
|
||||
printf("wc_Sha256Final failed\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* create an external key */
|
||||
rc = wc_ecc_init(&external_key);
|
||||
if (rc != 0) {
|
||||
printf("wc_ecc_init failed\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* make the key */
|
||||
rc = wc_ecc_make_key(&rng, 32, &external_key);
|
||||
if (rc != 0) {
|
||||
printf("wc_ecc_make_key failed\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mp_init(&r);
|
||||
mp_init(&s);
|
||||
|
||||
rc = wc_ecc_sign_hash_ex(hash, sizeof(hash), &rng, &external_key,
|
||||
&r, &s);
|
||||
|
||||
mp_to_unsigned_bin(&r, sig);
|
||||
mp_to_unsigned_bin(&s, sig + 32);
|
||||
|
||||
mp_clear(&r);
|
||||
mp_clear(&s);
|
||||
|
||||
if (rc != 0) {
|
||||
printf("wc_ecc_sign_hash_ex failed %d\n", rc);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
sigSz = 64;
|
||||
|
||||
/* load the public part of the key into the tpm */
|
||||
rc = wc_ecc_export_public_raw(&external_key, qx, &qxSz, qy, &qySz);
|
||||
if (rc != 0) {
|
||||
printf("wc_ecc_export_public_raw failed\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rc = wolfTPM2_LoadEccPublicKey(&dev, (WOLFTPM2_KEY*)&authKey,
|
||||
TPM_ECC_NIST_P256, qx, qxSz, qy, qySz);
|
||||
if (rc != TPM_RC_SUCCESS) {
|
||||
printf("wolfTPM2_LoadEccPublicKey failed\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* seal the secret */
|
||||
rc = wolfTPM2_SealWithAuthSigNV(&dev, &authKey, &tpmSession, TPM_ALG_SHA256,
|
||||
TPM_ALG_SHA256, pcrArray, pcrArraySz, secret, sizeof(secret), NULL, 0,
|
||||
sig, sigSz, sealNvIndex, policyDigestNvIndex);
|
||||
if (rc != TPM_RC_SUCCESS) {
|
||||
printf("wolfTPM2_SealWithAuthPolicyNV failed 0x%x: %s\n", rc,
|
||||
TPM2_GetRCString(rc));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* reset our session */
|
||||
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
|
||||
XMEMSET(&tpmSession, 0, sizeof(WOLFTPM2_SESSION));
|
||||
|
||||
rc = wolfTPM2_StartSession(&dev, &tpmSession, NULL, NULL,
|
||||
TPM_SE_POLICY, paramEncAlg);
|
||||
if (rc != 0) goto exit;
|
||||
printf("TPM2_StartAuthSession: sessionHandle 0x%x\n",
|
||||
(word32)tpmSession.handle.hndl);
|
||||
|
||||
/* set session for authorization of the storage key */
|
||||
rc = wolfTPM2_SetAuthSession(&dev, 0, &tpmSession,
|
||||
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt |
|
||||
TPMA_SESSION_continueSession));
|
||||
if (rc != 0) goto exit;
|
||||
|
||||
nv.handle.hndl = sealNvIndex;
|
||||
|
||||
/* try to unseal with the regular command, should fail */
|
||||
rc = wolfTPM2_NVReadAuth(&dev, &nv, sealNvIndex,
|
||||
secretOut, &secretOutSz, 0);
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
printf("wolfTPM2_NVReadAuth failed, it should not have allowed a read"
|
||||
" without PolicyAuthorizeNV 0x%x: %s\n", rc, TPM2_GetRCString(rc));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* unseal the secret */
|
||||
rc = wolfTPM2_UnsealWithAuthSigNV(&dev, &authKey,
|
||||
&tpmSession, TPM_ALG_SHA256, pcrArray,
|
||||
pcrArraySz, NULL, 0, sig, sigSz, sealNvIndex,
|
||||
policyDigestNvIndex, secretOut, &secretOutSz);
|
||||
if (rc != TPM_RC_SUCCESS) {
|
||||
printf("wolfTPM2_UnsealWithAuthSigNV failed 0x%x: %s\n", rc,
|
||||
TPM2_GetRCString(rc));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (XMEMCMP(secret, secretOut, sizeof(secret)) != 0) {
|
||||
printf("Usealed secret does not match\n");
|
||||
goto exit;
|
||||
}
|
||||
else {
|
||||
printf("Usealed secret matches!\n");
|
||||
}
|
||||
|
||||
exit:
|
||||
if (rc != 0) {
|
||||
printf("Failure 0x%x: %s\n", rc, wolfTPM2_GetRCString(rc));
|
||||
}
|
||||
|
||||
wolfTPM2_SetAuthPassword(&dev, 0, NULL);
|
||||
|
||||
wolfTPM2_UnloadHandle(&dev, &authKey.handle);
|
||||
wolfTPM2_UnloadHandle(&dev, &storage.handle);
|
||||
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
|
||||
|
||||
wolfTPM2_Cleanup(&dev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* --- END TPM2.0 PCR Policy example tool -- */
|
||||
/******************************************************************************/
|
||||
|
||||
#endif /* !WOLFTPM2_NO_WRAPPER && !WOLFTPM2_NO_WOLFCRYPT && WOLFSSL_PUBLIC_MP */
|
||||
|
||||
#ifndef NO_MAIN_DRIVER
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(WOLFSSL_PUBLIC_MP)
|
||||
rc = TPM2_PCR_Seal_With_Policy_Auth_NV_External_Test(NULL, argc, argv);
|
||||
#else
|
||||
printf("Wrapper or wolfcrypt code not compiled in\n");
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
#endif /* !WOLFTPM2_NO_WRAPPER */
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
|
@ -6584,9 +6584,9 @@ int wolfTPM2_UnsealWithAuthSig(WOLFTPM2_DEV* dev, WOLFTPM2_KEYBLOB* authKey,
|
|||
|
||||
int wolfTPM2_SealWithAuthSigNV(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* authKey,
|
||||
WOLFTPM2_SESSION* session, TPM_ALG_ID policyHashAlg, TPM_ALG_ID pcrAlg,
|
||||
const byte* sealData, word32 sealSz, const byte* nonce, word32 nonceSz,
|
||||
const byte* policySignedSig, word32 policySignedSigSz, word32 sealNvIndex,
|
||||
word32 policyDigestNvIndex)
|
||||
word32* pcrArray, word32 pcrArraySz, const byte* sealData, word32 sealSz,
|
||||
const byte* nonce, word32 nonceSz, const byte* policySignedSig,
|
||||
word32 policySignedSigSz, word32 sealNvIndex, word32 policyDigestNvIndex)
|
||||
{
|
||||
int rc = 0;
|
||||
PolicySigned_In policySignedIn[1];
|
||||
|
@ -6613,7 +6613,12 @@ int wolfTPM2_SealWithAuthSigNV(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* authKey,
|
|||
rc = wolfTPM2_SetAuthPassword(dev, 0, NULL);
|
||||
|
||||
if (rc == 0) {
|
||||
/* PolicyPCR should already have been added to the policy */
|
||||
/* add PCR to the policy digest */
|
||||
rc = wolfTPM2_PolicyPCR(session->handle.hndl, pcrAlg, pcrArray,
|
||||
pcrArraySz);
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
/* add PolicySigned to the policy */
|
||||
/* set the key handle */
|
||||
policySignedIn->authObject = authKey->handle.hndl;
|
||||
|
|
|
@ -3104,10 +3104,9 @@ WOLFTPM_API int wolfTPM2_UnsealWithAuthSig(WOLFTPM2_DEV* dev,
|
|||
/*!
|
||||
\ingroup wolfTPM2_Wrappers
|
||||
|
||||
\brief Seal a secret to the TPM NVM after verifying the PolicySigned
|
||||
signature was signed by the auth private key along with the policyDigest
|
||||
of the session. Other policy functions such as PolicyPCR should be called
|
||||
before calling this function
|
||||
\brief Seal a secret to the TPM NVM after calling PolicyPCR with the passed
|
||||
in pcrArray indicies and verifying the PolicySigned signature was signed by
|
||||
the auth private key along with the policyDigest of the session.
|
||||
|
||||
wolfTPM2_SealWithAuthSigNV
|
||||
|
||||
|
@ -3120,6 +3119,8 @@ WOLFTPM_API int wolfTPM2_UnsealWithAuthSig(WOLFTPM2_DEV* dev,
|
|||
\param session the current session, a session is required to use policy pcr
|
||||
\param policyHashAlg the hashing algorithm used to calculate policyDigest
|
||||
\param pcrAlg the hashing algorithm to use for pcr values
|
||||
\param pcrArray array of PCR indices to use with this policy
|
||||
\param pcrArraySz length of pcrArray
|
||||
\param sealData the data to seal into the tpm
|
||||
\param sealSz the size of the seal data
|
||||
\param nonce a one time number to include in our policy
|
||||
|
@ -3132,9 +3133,9 @@ WOLFTPM_API int wolfTPM2_UnsealWithAuthSig(WOLFTPM2_DEV* dev,
|
|||
\sa wolfTPM2_SealWithAuthSigNV
|
||||
*/
|
||||
WOLFTPM_API int wolfTPM2_SealWithAuthSigNV(WOLFTPM2_DEV* dev,
|
||||
WOLFTPM2_KEY* authKey, WOLFTPM2_SESSION* session,
|
||||
TPM_ALG_ID policyHashAlg, TPM_ALG_ID pcrAlg, const byte* sealData,
|
||||
word32 sealSz, const byte* nonce, word32 nonceSz,
|
||||
WOLFTPM2_KEY* authKey, WOLFTPM2_SESSION* session, TPM_ALG_ID policyHashAlg,
|
||||
TPM_ALG_ID pcrAlg, word32* pcrArray, word32 pcrArraySz,
|
||||
const byte* sealData, word32 sealSz, const byte* nonce, word32 nonceSz,
|
||||
const byte* policySignedSig, word32 policySignedSigSz, word32 sealNvIndex,
|
||||
word32 policyDigestNvIndex);
|
||||
|
||||
|
|
Loading…
Reference in New Issue