mirror of https://github.com/wolfSSL/wolfTPM.git
commit
bfadb256d5
|
@ -55,6 +55,7 @@ pkcs7tpmsignedex.p7s
|
||||||
examples/tls/tls_server
|
examples/tls/tls_server
|
||||||
examples/tls/tls_client_notpm
|
examples/tls/tls_client_notpm
|
||||||
tests/unit.test
|
tests/unit.test
|
||||||
|
examples/keygen/create_primary
|
||||||
examples/keygen/keyload
|
examples/keygen/keyload
|
||||||
examples/keygen/keygen
|
examples/keygen/keygen
|
||||||
examples/keygen/keyimport
|
examples/keygen/keyimport
|
||||||
|
@ -83,6 +84,16 @@ certs/server-*.pem
|
||||||
certs/client-*.der
|
certs/client-*.der
|
||||||
certs/client-*.pem
|
certs/client-*.pem
|
||||||
certs/serial.old
|
certs/serial.old
|
||||||
|
certs/0*.pem
|
||||||
|
certs/1*.pem
|
||||||
|
certs/2*.pem
|
||||||
|
certs/3*.pem
|
||||||
|
certs/4*.pem
|
||||||
|
certs/5*.pem
|
||||||
|
certs/6*.pem
|
||||||
|
certs/7*.pem
|
||||||
|
certs/8*.pem
|
||||||
|
certs/9*.pem
|
||||||
|
|
||||||
# Test files
|
# Test files
|
||||||
quote.blob
|
quote.blob
|
||||||
|
|
|
@ -24,8 +24,13 @@ Portable TPM 2.0 project designed for embedded use.
|
||||||
* TLS Client
|
* TLS Client
|
||||||
* TLS Server
|
* TLS Server
|
||||||
* Use of the TPM's Non-volatile memory
|
* Use of the TPM's Non-volatile memory
|
||||||
* Attestation (TPM2_Quote and TPM2_GetTime)
|
* Attestation (activate and make credential)
|
||||||
* Benchmarking TPM algorithms and TLS
|
* Benchmarking TPM algorithms and TLS
|
||||||
|
* Key Generation (primary, RSA/ECC and symmetric), loading and storing to flash (NV memory)
|
||||||
|
* Sealing and Unsealing data with an RSA key
|
||||||
|
* Time signed or set
|
||||||
|
* PCR read/reset
|
||||||
|
* GPIO configure, read and write.
|
||||||
* Parameter encryption support using AES-CFB or XOR.
|
* Parameter encryption support using AES-CFB or XOR.
|
||||||
* Support for salted unbound authenticated sessions.
|
* Support for salted unbound authenticated sessions.
|
||||||
* Support for HMAC Sessions.
|
* Support for HMAC Sessions.
|
||||||
|
@ -58,6 +63,8 @@ Contains hash digests for SHA-1 and SHA-256 with an index 0-23. These hash diges
|
||||||
|
|
||||||
This project uses the terms append vs. marshall and parse vs. unmarshall.
|
This project uses the terms append vs. marshall and parse vs. unmarshall.
|
||||||
|
|
||||||
|
Acronyms:
|
||||||
|
* NV: Non-Volatile memory.
|
||||||
|
|
||||||
## Platform
|
## Platform
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,252 @@
|
||||||
|
/* create_primary.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2022 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 creating and storing primary keys using TPM2.0 */
|
||||||
|
|
||||||
|
#include <wolftpm/tpm2_wrap.h>
|
||||||
|
|
||||||
|
#include <examples/keygen/keygen.h>
|
||||||
|
#include <examples/tpm_io.h>
|
||||||
|
#include <examples/tpm_test.h>
|
||||||
|
#include <examples/tpm_test_keys.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h> /* atoi */
|
||||||
|
|
||||||
|
#ifndef WOLFTPM2_NO_WRAPPER
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* --- BEGIN TPM Create Primary Key Example -- */
|
||||||
|
/******************************************************************************/
|
||||||
|
static void usage(void)
|
||||||
|
{
|
||||||
|
printf("Expected usage:\n");
|
||||||
|
printf("./examples/keygen/create_primary [-ecc/-rsa] [-oh/-eh/-ph] "
|
||||||
|
"[-unique=] [-auth=] [-aes/-xor] [-store=]\n");
|
||||||
|
printf("Primary Key Type:\n");
|
||||||
|
printf("\t-rsa: Use RSA for asymmetric key generation (DEFAULT)\n");
|
||||||
|
printf("\t-ecc: Use ECC for asymmetric key generation \n");
|
||||||
|
printf("Hierarchy:\n");
|
||||||
|
printf("\t-oh: Create keys under the Owner Hierarchy (DEFAULT)\n");
|
||||||
|
printf("\t-eh: Create keys under the Endorsement Hierarchy\n");
|
||||||
|
printf("\t-ph: Create keys under the Platform Hierarchy\n");
|
||||||
|
printf("Unique Template:\n");
|
||||||
|
printf("\t-unique=[value]\n");
|
||||||
|
printf("\t\tOptional unique value for the KDF of the create\n");
|
||||||
|
printf("Authentication:\n");
|
||||||
|
printf("\t-auth=[value]\n");
|
||||||
|
printf("\t\tOptional authentication string for primary\n");
|
||||||
|
printf("Parameter Encryption:\n");
|
||||||
|
printf("\t-aes: Use AES CFB parameter encryption\n");
|
||||||
|
printf("\t-xor: Use XOR parameter obfuscation\n");
|
||||||
|
printf("NV Storage:\n");
|
||||||
|
printf("\t-store=[handle]\n");
|
||||||
|
printf("\t\tPersistent primary key handle range: 0x81000000 - 0x810FFFF\n");
|
||||||
|
printf("\t\tUse leading 0x for hex\n");
|
||||||
|
|
||||||
|
printf("Example usage:\n");
|
||||||
|
printf("\t* Create SRK used by wolfTPM:\n");
|
||||||
|
printf("\t\tcreate_primary -rsa -oh -auth=ThisIsMyStorageKeyAuth "
|
||||||
|
"-store=0x81000200\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int TPM2_CreatePrimaryKey_Example(void* userCtx, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
WOLFTPM2_DEV dev;
|
||||||
|
WOLFTPM2_KEY primary;
|
||||||
|
TPMT_PUBLIC publicTemplate;
|
||||||
|
TPMI_ALG_PUBLIC alg = TPM_ALG_RSA;
|
||||||
|
TPM_ALG_ID paramEncAlg = TPM_ALG_NULL;
|
||||||
|
TPM_RH hierarchy = TPM_RH_OWNER;
|
||||||
|
WOLFTPM2_SESSION tpmSession;
|
||||||
|
const char* uniqueStr = NULL;
|
||||||
|
const char* authStr = NULL;
|
||||||
|
word32 persistHandle = 0;
|
||||||
|
|
||||||
|
if (argc >= 2) {
|
||||||
|
if (XSTRNCMP(argv[1], "-?", 2) == 0 ||
|
||||||
|
XSTRNCMP(argv[1], "-h", 2) == 0 ||
|
||||||
|
XSTRNCMP(argv[1], "--help", 6) == 0) {
|
||||||
|
usage();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (argc > 1) {
|
||||||
|
if (XSTRNCMP(argv[argc-1], "-rsa", 4) == 0) {
|
||||||
|
alg = TPM_ALG_RSA;
|
||||||
|
}
|
||||||
|
if (XSTRNCMP(argv[argc-1], "-ecc", 4) == 0) {
|
||||||
|
alg = TPM_ALG_ECC;
|
||||||
|
}
|
||||||
|
if (XSTRNCMP(argv[argc-1], "-aes", 4) == 0) {
|
||||||
|
paramEncAlg = TPM_ALG_CFB;
|
||||||
|
}
|
||||||
|
if (XSTRNCMP(argv[argc-1], "-xor", 4) == 0) {
|
||||||
|
paramEncAlg = TPM_ALG_XOR;
|
||||||
|
}
|
||||||
|
if (XSTRNCMP(argv[argc-1], "-eh", 3) == 0) {
|
||||||
|
hierarchy = TPM_RH_ENDORSEMENT;
|
||||||
|
}
|
||||||
|
if (XSTRNCMP(argv[argc-1], "-ph", 3) == 0) {
|
||||||
|
hierarchy = TPM_RH_PLATFORM;
|
||||||
|
}
|
||||||
|
if (XSTRNCMP(argv[argc-1], "-oh", 3) == 0) {
|
||||||
|
hierarchy = TPM_RH_OWNER;
|
||||||
|
}
|
||||||
|
if (XSTRNCMP(argv[argc-1], "-unique=", 8) == 0) {
|
||||||
|
uniqueStr = argv[argc-1] + 8;
|
||||||
|
}
|
||||||
|
if (XSTRNCMP(argv[argc-1], "-auth=", 6) == 0) {
|
||||||
|
authStr = argv[argc-1] + 6;
|
||||||
|
}
|
||||||
|
if (XSTRNCMP(argv[argc-1], "-store=", 7) == 0) {
|
||||||
|
persistHandle = (word32)strtol(argv[argc-1] + 7, NULL, 0);
|
||||||
|
if (persistHandle < 0x81000000 && persistHandle > 0x810FFFF) {
|
||||||
|
printf("Invalid storage handle %s\n", argv[argc-1] + 7);
|
||||||
|
persistHandle = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
argc--;
|
||||||
|
}
|
||||||
|
|
||||||
|
XMEMSET(&primary, 0, sizeof(primary));
|
||||||
|
XMEMSET(&tpmSession, 0, sizeof(tpmSession));
|
||||||
|
|
||||||
|
printf("TPM2.0 Primary Key generation example\n");
|
||||||
|
printf("\tAlgorithm: %s\n", TPM2_GetAlgName(alg));
|
||||||
|
printf("\tUnique: %s\n", uniqueStr);
|
||||||
|
printf("\tAuth: %s\n", authStr);
|
||||||
|
printf("\tStore Handle: 0x%08x\n", persistHandle);
|
||||||
|
printf("\tUse Parameter Encryption: %s\n", TPM2_GetAlgName(paramEncAlg));
|
||||||
|
|
||||||
|
rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx);
|
||||||
|
if (rc != TPM_RC_SUCCESS) {
|
||||||
|
printf("\nwolfTPM2_Init failed\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See if handle already exists */
|
||||||
|
if (persistHandle > 0) {
|
||||||
|
if (wolfTPM2_ReadPublicKey(&dev, &primary, persistHandle) == 0) {
|
||||||
|
printf("Primary Handle 0x%08x already exists\n", persistHandle);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Supported algorithms for primary key are only RSA 2048-bit & ECC P256 */
|
||||||
|
if (alg == TPM_ALG_RSA) {
|
||||||
|
rc = wolfTPM2_GetKeyTemplate_RSA_SRK(&publicTemplate);
|
||||||
|
}
|
||||||
|
else if (alg == TPM_ALG_ECC) {
|
||||||
|
rc = wolfTPM2_GetKeyTemplate_ECC_SRK(&publicTemplate);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rc = BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
if (rc != TPM_RC_SUCCESS) goto exit;
|
||||||
|
|
||||||
|
if (paramEncAlg != TPM_ALG_NULL) {
|
||||||
|
/* Start an authenticated session (salted / unbound) with parameter encryption */
|
||||||
|
rc = wolfTPM2_StartSession(&dev, &tpmSession, NULL, NULL,
|
||||||
|
TPM_SE_HMAC, paramEncAlg);
|
||||||
|
if (rc != TPM_RC_SUCCESS) goto exit;
|
||||||
|
printf("TPM2_StartAuthSession: sessionHandle 0x%x\n",
|
||||||
|
(word32)tpmSession.handle.hndl);
|
||||||
|
|
||||||
|
/* set session for authorization of the primary key */
|
||||||
|
rc = wolfTPM2_SetAuthSession(&dev, 1, &tpmSession,
|
||||||
|
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt | TPMA_SESSION_continueSession));
|
||||||
|
if (rc != TPM_RC_SUCCESS) goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* optionally set a unique field */
|
||||||
|
if (uniqueStr != NULL) {
|
||||||
|
rc = wolfTPM2_SetKeyTemplate_Unique(&publicTemplate,
|
||||||
|
(const byte*)uniqueStr, (int)XSTRLEN(uniqueStr));
|
||||||
|
if (rc != TPM_RC_SUCCESS) goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Creating new %s primary key...\n", TPM2_GetAlgName(alg));
|
||||||
|
|
||||||
|
rc = wolfTPM2_CreatePrimaryKey(&dev, &primary, hierarchy, &publicTemplate,
|
||||||
|
(const byte*)authStr, authStr ? (int)XSTRLEN(authStr) : 0);
|
||||||
|
if (rc != TPM_RC_SUCCESS) {
|
||||||
|
printf("wolfTPM2_CreatePrimaryKey failed\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_WOLFTPM
|
||||||
|
printf("Primary Key Public (%d bytes)\n", primary.pub.size);
|
||||||
|
TPM2_PrintBin((const byte*)&primary.pub.publicArea, primary.pub.size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (persistHandle > 0) {
|
||||||
|
#ifndef WOLFTPM_WINAPI
|
||||||
|
/* Move storage key into persistent NV */
|
||||||
|
printf("Storing Primary key to handle 0x%08x\n", persistHandle);
|
||||||
|
rc = wolfTPM2_NVStoreKey(&dev, hierarchy, &primary,
|
||||||
|
persistHandle);
|
||||||
|
if (rc != TPM_RC_SUCCESS) goto exit;
|
||||||
|
#else
|
||||||
|
printf("Windows TBS does not allow persisting handles to "
|
||||||
|
"Non-Volatile (NV) Memory\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
|
||||||
|
if (rc != 0) {
|
||||||
|
printf("\nFailure 0x%x: %s\n\n", rc, wolfTPM2_GetRCString(rc));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close handles */
|
||||||
|
wolfTPM2_UnloadHandle(&dev, &primary.handle);
|
||||||
|
if (paramEncAlg != TPM_ALG_NULL) {
|
||||||
|
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
wolfTPM2_Cleanup(&dev);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* --- END TPM Create Primary Key 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_CreatePrimaryKey_Example(NULL, argc, argv);
|
||||||
|
#else
|
||||||
|
printf("Create Primary key code not compiled in\n");
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -4,6 +4,13 @@
|
||||||
if BUILD_EXAMPLES
|
if BUILD_EXAMPLES
|
||||||
noinst_HEADERS += examples/keygen/keygen.h
|
noinst_HEADERS += examples/keygen/keygen.h
|
||||||
|
|
||||||
|
noinst_PROGRAMS += examples/keygen/create_primary
|
||||||
|
examples_keygen_create_primary_SOURCES = examples/keygen/create_primary.c \
|
||||||
|
examples/tpm_test_keys.c \
|
||||||
|
examples/tpm_io.c
|
||||||
|
examples_keygen_create_primary_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
|
||||||
|
examples_keygen_create_primary_DEPENDENCIES = src/libwolftpm.la
|
||||||
|
|
||||||
noinst_PROGRAMS += examples/keygen/keyload
|
noinst_PROGRAMS += examples/keygen/keyload
|
||||||
examples_keygen_keyload_SOURCES = examples/keygen/keyload.c \
|
examples_keygen_keyload_SOURCES = examples/keygen/keyload.c \
|
||||||
examples/tpm_test_keys.c \
|
examples/tpm_test_keys.c \
|
||||||
|
@ -28,10 +35,12 @@ endif
|
||||||
|
|
||||||
example_keygendir = $(exampledir)/keygen
|
example_keygendir = $(exampledir)/keygen
|
||||||
dist_example_keygen_DATA = \
|
dist_example_keygen_DATA = \
|
||||||
|
examples/keygen/create_primary.c \
|
||||||
examples/keygen/keyload.c \
|
examples/keygen/keyload.c \
|
||||||
examples/keygen/keygen.c \
|
examples/keygen/keygen.c \
|
||||||
examples/keygen/keyimport.c
|
examples/keygen/keyimport.c
|
||||||
|
|
||||||
|
DISTCLEANFILES+= examples/keygen/.libs/create_primary
|
||||||
DISTCLEANFILES+= examples/keygen/.libs/keyload
|
DISTCLEANFILES+= examples/keygen/.libs/keyload
|
||||||
DISTCLEANFILES+= examples/keygen/.libs/keygen
|
DISTCLEANFILES+= examples/keygen/.libs/keygen
|
||||||
DISTCLEANFILES+= examples/keygen/.libs/keyimport
|
DISTCLEANFILES+= examples/keygen/.libs/keyimport
|
||||||
|
|
|
@ -53,10 +53,13 @@ static void usage(void)
|
||||||
printf("* -eh: Create keys under the Endorsement Hierarchy (EK)\n");
|
printf("* -eh: Create keys under the Endorsement Hierarchy (EK)\n");
|
||||||
printf("* -rsa: Use RSA for asymmetric key generation (DEFAULT)\n");
|
printf("* -rsa: Use RSA for asymmetric key generation (DEFAULT)\n");
|
||||||
printf("* -ecc: Use ECC for asymmetric key generation \n");
|
printf("* -ecc: Use ECC for asymmetric key generation \n");
|
||||||
printf("* -sym: Use Symmetric Cypher for key generation\n");
|
printf("* -sym: Use Symmetric Cipher for key generation\n");
|
||||||
printf("\tDefault Symmetric Cypher is AES CTR with 256 bits\n");
|
printf("\tDefault Symmetric Cipher is AES CTR with 256 bits\n");
|
||||||
printf("* -t: Use default template (otherwise AIK)\n");
|
printf("* -t: Use default template (otherwise AIK)\n");
|
||||||
printf("* -aes/xor: Use Parameter Encryption\n");
|
printf("* -aes/xor: Use Parameter Encryption\n");
|
||||||
|
printf("* -unique=[value]\n");
|
||||||
|
printf("\t* Used for the KDF of the create\n");
|
||||||
|
|
||||||
printf("Example usage:\n");
|
printf("Example usage:\n");
|
||||||
printf("\t* RSA, default template\n");
|
printf("\t* RSA, default template\n");
|
||||||
printf("\t\t keygen -t\n");
|
printf("\t\t keygen -t\n");
|
||||||
|
@ -120,7 +123,7 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
||||||
WOLFTPM2_KEYBLOB primaryBlob; /* Primary key as WOLFTPM2_KEYBLOB */
|
WOLFTPM2_KEYBLOB primaryBlob; /* Primary key as WOLFTPM2_KEYBLOB */
|
||||||
TPMT_PUBLIC publicTemplate;
|
TPMT_PUBLIC publicTemplate;
|
||||||
TPMI_ALG_PUBLIC alg = TPM_ALG_RSA; /* default, see usage() for options */
|
TPMI_ALG_PUBLIC alg = TPM_ALG_RSA; /* default, see usage() for options */
|
||||||
TPM_ALG_ID algSym = TPM_ALG_CTR; /* default Symmetric Cypher, see usage */
|
TPM_ALG_ID algSym = TPM_ALG_CTR; /* default Symmetric Cipher, see usage */
|
||||||
TPM_ALG_ID paramEncAlg = TPM_ALG_NULL;
|
TPM_ALG_ID paramEncAlg = TPM_ALG_NULL;
|
||||||
WOLFTPM2_SESSION tpmSession;
|
WOLFTPM2_SESSION tpmSession;
|
||||||
TPM2B_AUTH auth;
|
TPM2B_AUTH auth;
|
||||||
|
@ -128,6 +131,7 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
||||||
int pemFiles = 0;
|
int pemFiles = 0;
|
||||||
int bAIK = 1;
|
int bAIK = 1;
|
||||||
int keyBits = 256;
|
int keyBits = 256;
|
||||||
|
const char* uniqueStr = NULL;
|
||||||
const char *outputFile = "keyblob.bin";
|
const char *outputFile = "keyblob.bin";
|
||||||
const char *ekPubFile = "ek.pub";
|
const char *ekPubFile = "ek.pub";
|
||||||
const char *srkPubFile = "srk.pub";
|
const char *srkPubFile = "srk.pub";
|
||||||
|
@ -189,6 +193,10 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
||||||
if (XSTRNCMP(argv[argc-1], "-xor", 4) == 0) {
|
if (XSTRNCMP(argv[argc-1], "-xor", 4) == 0) {
|
||||||
paramEncAlg = TPM_ALG_XOR;
|
paramEncAlg = TPM_ALG_XOR;
|
||||||
}
|
}
|
||||||
|
if (XSTRNCMP(argv[argc-1], "-unique=", 8) == 0) {
|
||||||
|
uniqueStr = argv[argc-1] + 8;
|
||||||
|
}
|
||||||
|
|
||||||
argc--;
|
argc--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,6 +310,13 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
||||||
}
|
}
|
||||||
if (rc != 0) goto exit;
|
if (rc != 0) goto exit;
|
||||||
|
|
||||||
|
/* optionally set a unique field */
|
||||||
|
if (uniqueStr != NULL) {
|
||||||
|
rc = wolfTPM2_SetKeyTemplate_Unique(&publicTemplate, (byte*)uniqueStr,
|
||||||
|
(int)XSTRLEN(uniqueStr));
|
||||||
|
if (rc != 0) goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
printf("Creating new %s key...\n", TPM2_GetAlgName(alg));
|
printf("Creating new %s key...\n", TPM2_GetAlgName(alg));
|
||||||
|
|
||||||
rc = wolfTPM2_CreateKey(&dev, &newKeyBlob, &primary->handle,
|
rc = wolfTPM2_CreateKey(&dev, &newKeyBlob, &primary->handle,
|
||||||
|
@ -390,7 +405,7 @@ exit:
|
||||||
wolfTPM2_UnloadHandle(&dev, &primary->handle);
|
wolfTPM2_UnloadHandle(&dev, &primary->handle);
|
||||||
wolfTPM2_UnloadHandle(&dev, &newKeyBlob.handle);
|
wolfTPM2_UnloadHandle(&dev, &newKeyBlob.handle);
|
||||||
/* EK policy is destroyed after use, flush parameter encryption session */
|
/* EK policy is destroyed after use, flush parameter encryption session */
|
||||||
if(!endorseKey) {
|
if (paramEncAlg != TPM_ALG_NULL && !endorseKey) {
|
||||||
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
|
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int TPM2_CreatePrimaryKey_Example(void* userCtx, int argc, char *argv[]);
|
||||||
int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[]);
|
int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[]);
|
||||||
int TPM2_Keyload_Example(void* userCtx, int argc, char *argv[]);
|
int TPM2_Keyload_Example(void* userCtx, int argc, char *argv[]);
|
||||||
int TPM2_Keyimport_Example(void* userCtx, int argc, char *argv[]);
|
int TPM2_Keyimport_Example(void* userCtx, int argc, char *argv[]);
|
||||||
|
|
122
src/tpm2_wrap.c
122
src/tpm2_wrap.c
|
@ -303,6 +303,13 @@ WOLFTPM2_HANDLE* wolfTPM2_GetHandleRefFromSession(WOLFTPM2_SESSION* session)
|
||||||
return (session != NULL) ? &session->handle : NULL;
|
return (session != NULL) ? &session->handle : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TPM_HANDLE wolfTPM2_GetHandleValue(WOLFTPM2_HANDLE* handle)
|
||||||
|
{
|
||||||
|
TPM_HANDLE hndl = 0;
|
||||||
|
if (handle)
|
||||||
|
hndl = handle->hndl;
|
||||||
|
return hndl;
|
||||||
|
}
|
||||||
|
|
||||||
int wolfTPM2_GetKeyBlobAsBuffer(byte *buffer, word32 bufferSz,
|
int wolfTPM2_GetKeyBlobAsBuffer(byte *buffer, word32 bufferSz,
|
||||||
WOLFTPM2_KEYBLOB* key)
|
WOLFTPM2_KEYBLOB* key)
|
||||||
|
@ -4253,8 +4260,8 @@ static int GetKeyTemplateECC(TPMT_PUBLIC* publicTemplate,
|
||||||
XMEMSET(publicTemplate, 0, sizeof(TPMT_PUBLIC));
|
XMEMSET(publicTemplate, 0, sizeof(TPMT_PUBLIC));
|
||||||
publicTemplate->type = TPM_ALG_ECC;
|
publicTemplate->type = TPM_ALG_ECC;
|
||||||
publicTemplate->nameAlg = nameAlg;
|
publicTemplate->nameAlg = nameAlg;
|
||||||
publicTemplate->unique.ecc.x.size = curveSz / 8;
|
publicTemplate->unique.ecc.x.size = curveSz;
|
||||||
publicTemplate->unique.ecc.y.size = curveSz / 8;
|
publicTemplate->unique.ecc.y.size = curveSz;
|
||||||
publicTemplate->objectAttributes = objectAttributes;
|
publicTemplate->objectAttributes = objectAttributes;
|
||||||
if (objectAttributes & TPMA_OBJECT_fixedTPM) {
|
if (objectAttributes & TPMA_OBJECT_fixedTPM) {
|
||||||
publicTemplate->parameters.eccDetail.symmetric.algorithm = TPM_ALG_AES;
|
publicTemplate->parameters.eccDetail.symmetric.algorithm = TPM_ALG_AES;
|
||||||
|
@ -4439,6 +4446,117 @@ int wolfTPM2_GetKeyTemplate_ECC_AIK(TPMT_PUBLIC* publicTemplate)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns key size (in bytes) for the public template */
|
||||||
|
static int GetKeyTemplateSize(TPMT_PUBLIC* publicTemplate)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
if (publicTemplate == NULL) {
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
switch (publicTemplate->type) {
|
||||||
|
case TPM_ALG_RSA:
|
||||||
|
ret = publicTemplate->parameters.rsaDetail.keyBits / 8;
|
||||||
|
break;
|
||||||
|
case TPM_ALG_ECC:
|
||||||
|
ret = TPM2_GetCurveSize(
|
||||||
|
publicTemplate->parameters.eccDetail.curveID);
|
||||||
|
break;
|
||||||
|
case TPM_ALG_SYMCIPHER:
|
||||||
|
ret = publicTemplate->parameters.symDetail.sym.keyBits.sym / 8;
|
||||||
|
break;
|
||||||
|
case TPM_ALG_KEYEDHASH:
|
||||||
|
default:
|
||||||
|
ret = BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wolfTPM2_SetKeyTemplate_Unique(TPMT_PUBLIC* publicTemplate,
|
||||||
|
const byte* unique, int uniqueSz)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
int keySz;
|
||||||
|
|
||||||
|
if (publicTemplate == NULL || (unique != NULL && uniqueSz <= 0)) {
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
keySz = GetKeyTemplateSize(publicTemplate);
|
||||||
|
if (keySz <= 0) {
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (publicTemplate->type) {
|
||||||
|
case TPM_ALG_RSA:
|
||||||
|
if (uniqueSz == 0) {
|
||||||
|
uniqueSz = keySz;
|
||||||
|
}
|
||||||
|
else if (uniqueSz > keySz) {
|
||||||
|
uniqueSz = keySz;
|
||||||
|
}
|
||||||
|
if (uniqueSz > (int)sizeof(publicTemplate->unique.rsa.buffer)) {
|
||||||
|
uniqueSz = (int)sizeof(publicTemplate->unique.rsa.buffer);
|
||||||
|
}
|
||||||
|
if (unique == NULL) {
|
||||||
|
XMEMSET(publicTemplate->unique.rsa.buffer, 0, uniqueSz);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
XMEMCPY(publicTemplate->unique.rsa.buffer, unique, uniqueSz);
|
||||||
|
}
|
||||||
|
publicTemplate->unique.rsa.size = uniqueSz;
|
||||||
|
break;
|
||||||
|
case TPM_ALG_ECC:
|
||||||
|
/* ECC uses X and Y */
|
||||||
|
if (uniqueSz == 0) {
|
||||||
|
uniqueSz = keySz * 2;
|
||||||
|
}
|
||||||
|
else if (uniqueSz > keySz * 2) {
|
||||||
|
uniqueSz = keySz * 2;
|
||||||
|
}
|
||||||
|
uniqueSz /= 2;
|
||||||
|
if (uniqueSz > (int)sizeof(publicTemplate->unique.ecc.x.buffer)) {
|
||||||
|
uniqueSz = (int)sizeof(publicTemplate->unique.ecc.x.buffer);
|
||||||
|
}
|
||||||
|
if (unique == NULL) {
|
||||||
|
XMEMSET(publicTemplate->unique.ecc.x.buffer, 0, uniqueSz);
|
||||||
|
XMEMSET(publicTemplate->unique.ecc.y.buffer, 0, uniqueSz);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
XMEMCPY(publicTemplate->unique.ecc.x.buffer, unique, uniqueSz);
|
||||||
|
XMEMCPY(publicTemplate->unique.ecc.y.buffer, unique + uniqueSz, uniqueSz);
|
||||||
|
}
|
||||||
|
publicTemplate->unique.ecc.x.size = uniqueSz;
|
||||||
|
publicTemplate->unique.ecc.y.size = uniqueSz;
|
||||||
|
break;
|
||||||
|
case TPM_ALG_SYMCIPHER:
|
||||||
|
if (uniqueSz == 0) {
|
||||||
|
uniqueSz = keySz;
|
||||||
|
}
|
||||||
|
else if (uniqueSz > keySz) {
|
||||||
|
uniqueSz = keySz;
|
||||||
|
}
|
||||||
|
if (uniqueSz > (int)sizeof(publicTemplate->unique.sym.buffer)) {
|
||||||
|
uniqueSz = (int)sizeof(publicTemplate->unique.sym.buffer);
|
||||||
|
}
|
||||||
|
if (unique == NULL) {
|
||||||
|
XMEMSET(publicTemplate->unique.sym.buffer, 0, uniqueSz);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
XMEMCPY(publicTemplate->unique.sym.buffer, unique, uniqueSz);
|
||||||
|
}
|
||||||
|
publicTemplate->unique.sym.size = uniqueSz;
|
||||||
|
break;
|
||||||
|
case TPM_ALG_KEYEDHASH:
|
||||||
|
/* not supported */
|
||||||
|
ret = BAD_FUNC_ARG;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = BAD_FUNC_ARG;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int wolfTPM2_GetNvAttributesTemplate(TPM_HANDLE auth, word32* nvAttributes)
|
int wolfTPM2_GetNvAttributesTemplate(TPM_HANDLE auth, word32* nvAttributes)
|
||||||
{
|
{
|
||||||
if (nvAttributes == NULL)
|
if (nvAttributes == NULL)
|
||||||
|
|
|
@ -2160,6 +2160,21 @@ WOLFTPM_API int wolfTPM2_GetKeyTemplate_RSA_AIK(TPMT_PUBLIC* publicTemplate);
|
||||||
*/
|
*/
|
||||||
WOLFTPM_API int wolfTPM2_GetKeyTemplate_ECC_AIK(TPMT_PUBLIC* publicTemplate);
|
WOLFTPM_API int wolfTPM2_GetKeyTemplate_ECC_AIK(TPMT_PUBLIC* publicTemplate);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup wolfTPM2_Wrappers
|
||||||
|
\brief Sets the unique area of a public template used by Create or CreatePrimary.
|
||||||
|
\return TPM_RC_SUCCESS: successful
|
||||||
|
\return BAD_FUNC_ARG: check the provided arguments
|
||||||
|
|
||||||
|
\param publicTemplate pointer to an empty structure of TPMT_PUBLIC type, to store the new template
|
||||||
|
\param unique optional pointer to buffer to populate unique area of public template. If NULL, the buffer will be zeroized.
|
||||||
|
\param uniqueSz size to fill the unique field. If zero the key size is used.
|
||||||
|
|
||||||
|
\sa wolfTPM2_CreateKey
|
||||||
|
\sa wolfTPM2_CreatePrimaryKey
|
||||||
|
*/
|
||||||
|
WOLFTPM_API int wolfTPM2_SetKeyTemplate_Unique(TPMT_PUBLIC* publicTemplate, const byte* unique, int uniqueSz);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup wolfTPM2_Wrappers
|
\ingroup wolfTPM2_Wrappers
|
||||||
\brief Prepares a TPM NV Index template
|
\brief Prepares a TPM NV Index template
|
||||||
|
@ -2500,6 +2515,16 @@ WOLFTPM_API WOLFTPM2_HANDLE* wolfTPM2_GetHandleRefFromKeyBlob(WOLFTPM2_KEYBLOB*
|
||||||
*/
|
*/
|
||||||
WOLFTPM_API WOLFTPM2_HANDLE* wolfTPM2_GetHandleRefFromSession(WOLFTPM2_SESSION* session);
|
WOLFTPM_API WOLFTPM2_HANDLE* wolfTPM2_GetHandleRefFromSession(WOLFTPM2_SESSION* session);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup wolfTPM2_Wrappers
|
||||||
|
\brief Get the 32-bit handle value from the WOLFTPM2_HANDLE
|
||||||
|
|
||||||
|
\return TPM_HANDLE value from TPM
|
||||||
|
|
||||||
|
\param handle pointer to WOLFTPM2_HANDLE structure
|
||||||
|
*/
|
||||||
|
WOLFTPM_API TPM_HANDLE wolfTPM2_GetHandleValue(WOLFTPM2_HANDLE* handle);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup wolfTPM2_Wrappers
|
\ingroup wolfTPM2_Wrappers
|
||||||
\brief Set the authentication data for a key
|
\brief Set the authentication data for a key
|
||||||
|
|
|
@ -358,5 +358,33 @@ namespace tpm_csharp_test
|
||||||
ret = device.UnloadHandle(key);
|
ret = device.UnloadHandle(key);
|
||||||
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TryCreateCustomPrimaryKey()
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
Key key = new Key();
|
||||||
|
Template template = new Template();
|
||||||
|
|
||||||
|
/* Test creating custom SRK (different than one Windows uses) */
|
||||||
|
ret = template.GetKeyTemplate_RSA_SRK();
|
||||||
|
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
||||||
|
|
||||||
|
ret = template.SetKeyTemplate_Unique("myUniqueValue");
|
||||||
|
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
||||||
|
|
||||||
|
ret = device.CreatePrimaryKey(key, TPM_RH.OWNER, template, null);
|
||||||
|
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
||||||
|
|
||||||
|
/* use temporary handle (in memory), cannot store to
|
||||||
|
* Non-Volatile (NV) Memory on Windows */
|
||||||
|
Console.WriteLine("Primary Key Handle 0x{0}",
|
||||||
|
device.GetHandleValue(key.GetHandle()).ToString("X8"));
|
||||||
|
|
||||||
|
ret = device.UnloadHandle(key);
|
||||||
|
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -352,6 +352,13 @@ namespace wolfTPM
|
||||||
{
|
{
|
||||||
return wolfTPM2_GetKeyTemplate_ECC_AIK(template);
|
return wolfTPM2_GetKeyTemplate_ECC_AIK(template);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_SetKeyTemplate_Unique")]
|
||||||
|
private static extern int wolfTPM2_SetKeyTemplate_Unique(IntPtr publicTemplate, string unique, int uniqueSz);
|
||||||
|
public int SetKeyTemplate_Unique(string unique)
|
||||||
|
{
|
||||||
|
return wolfTPM2_SetKeyTemplate_Unique(template, unique, unique.Length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Session
|
public class Session
|
||||||
|
@ -730,5 +737,13 @@ namespace wolfTPM
|
||||||
return wolfTPM2_UnloadHandle(device, tpmSession.GetHandle());
|
return wolfTPM2_UnloadHandle(device, tpmSession.GetHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_GetHandleValue")]
|
||||||
|
private static extern long wolfTPM2_GetHandleValue(IntPtr handle);
|
||||||
|
|
||||||
|
public long GetHandleValue(IntPtr handle)
|
||||||
|
{
|
||||||
|
return wolfTPM2_GetHandleValue(handle);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue