Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for PCR selection and keygen with -sym= option #372

Merged
merged 3 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/gpio/gpio_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ int TPM2_GPIO_Config_Example(void* userCtx, int argc, char *argv[])
#endif

/* Prepare GPIO configuration according to Nuvoton requirements */
if(gpioMode == TPM_GPIO_MODE_PUSHPULL) {
if (gpioMode == TPM_GPIO_MODE_PUSHPULL) {
/* For NUVOTON_GPIO_MODE_PUSHPULL */
newConfig.GpioPushPull |= (1 << gpioNum);
}
Expand Down
2 changes: 1 addition & 1 deletion examples/gpio/gpio_read.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ int TPM2_GPIO_Read_Example(void* userCtx, int argc, char *argv[])
return 0;
}
pin = XATOI(argv[1]);
if(pin < TPM_GPIO_NUM_MIN || pin > TPM_GPIO_NUM_MAX) {
if (pin < TPM_GPIO_NUM_MIN || pin > TPM_GPIO_NUM_MAX) {
usage();
return 0;
}
Expand Down
66 changes: 23 additions & 43 deletions examples/keygen/keygen.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,6 @@
#include <examples/tpm_test.h>
#include <examples/tpm_test_keys.h>

#define SYM_EXTRA_OPTS_LEN 14 /* 5 chars for "-sym=" and 9 for extra options */
#define SYM_EXTRA_OPTS_POS 4 /* Array pos of the equal sign for extra opts */
#define SYM_EXTRA_OPTS_AES_MODE_POS 8
#define SYM_EXTRA_OPTS_KEY_BITS_POS 11



/******************************************************************************/
/* --- BEGIN TPM Keygen Example -- */
Expand Down Expand Up @@ -79,35 +73,22 @@ static void usage(void)
printf("\t\t keygen -sym=aescbc256 -xor\n");
}

static int symChoice(const char* arg, TPM_ALG_ID* algSym, int* keyBits,
char* symMode)
static int symChoice(const char* symMode, TPM_ALG_ID* algSym, int* keyBits)
{
size_t len = XSTRLEN(arg);

if (len != SYM_EXTRA_OPTS_LEN) {
return TPM_RC_FAILURE;
}
if (XSTRCMP(&arg[SYM_EXTRA_OPTS_POS+1], "aes")) {
return TPM_RC_FAILURE;
}

/* Copy string for user information later */
XMEMCPY(symMode, &arg[SYM_EXTRA_OPTS_POS+1], 6);

if (XSTRCMP(&arg[SYM_EXTRA_OPTS_AES_MODE_POS], "cfb") == 0) {
if (XSTRNCMP(symMode, "aescfb", 6) == 0) {
*algSym = TPM_ALG_CFB;
}
else if (XSTRCMP(&arg[SYM_EXTRA_OPTS_AES_MODE_POS], "ctr") == 0) {
else if (XSTRNCMP(symMode, "aesctr", 6) == 0) {
*algSym = TPM_ALG_CTR;
}
else if (XSTRCMP(&arg[SYM_EXTRA_OPTS_AES_MODE_POS], "cbc") == 0) {
else if (XSTRNCMP(symMode, "aescbc", 6) == 0) {
*algSym = TPM_ALG_CBC;
}
else {
return TPM_RC_FAILURE;
}

*keyBits = XATOI(&arg[SYM_EXTRA_OPTS_KEY_BITS_POS]);
*keyBits = XATOI(&symMode[6]);
if (*keyBits != 128 && *keyBits != 192 && *keyBits != 256) {
return TPM_RC_FAILURE;
}
Expand Down Expand Up @@ -147,8 +128,7 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
const char *pemFilename = NULL;
#endif
#endif
size_t len = 0;
char symMode[] = "aesctr";
const char* symMode = "aesctr";

if (argc >= 2) {
if (XSTRCMP(argv[1], "-?") == 0 ||
Expand All @@ -157,8 +137,6 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
usage();
return 0;
}
if (argv[1][0] != '-')
outputFile = argv[1];
}
while (argc > 1) {
if (XSTRCMP(argv[argc-1], "-rsa") == 0) {
Expand All @@ -167,20 +145,12 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
else if (XSTRCMP(argv[argc-1], "-ecc") == 0) {
alg = TPM_ALG_ECC;
}
else if (XSTRNCMP(argv[argc-1], "-sym=", XSTRLEN("-sym=")) == 0) {
symMode = argv[argc-1] + XSTRLEN("-sym=");
alg = TPM_ALG_SYMCIPHER;
bAIK = 0;
}
else if (XSTRCMP(argv[argc-1], "-sym") == 0) {
len = XSTRLEN(argv[argc-1]);
if (len >= SYM_EXTRA_OPTS_LEN) {
/* Did the user provide specific options? */
if (argv[argc-1][SYM_EXTRA_OPTS_POS] == '=') {
rc = symChoice(argv[argc-1], &algSym, &keyBits, symMode);
/* In case of incorrect extra options, abort execution */
if (rc != TPM_RC_SUCCESS) {
usage();
return 0;
}
}
/* Otherwise, defaults are used: AES CTR, 256 key bits */
}
alg = TPM_ALG_SYMCIPHER;
bAIK = 0;
}
Expand All @@ -206,7 +176,10 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
else if (XSTRNCMP(argv[argc-1], "-unique=", XSTRLEN("-unique=")) == 0) {
uniqueStr = argv[argc-1] + XSTRLEN("-unique=");
}
else if (argv[argc-1][0] == '-') {
else if (argv[argc-1][0] != '-') {
outputFile = argv[argc-1];
}
else {
printf("Warning: Unrecognized option: %s\n", argv[argc-1]);
}

Expand All @@ -223,11 +196,18 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])

if (alg == TPM_ALG_RSA)
srkAlg = TPM_ALG_RSA;
if (alg == TPM_ALG_SYMCIPHER) {
rc = symChoice(symMode, &algSym, &keyBits);
if (rc != TPM_RC_SUCCESS) {
usage();
return 0;
}
}

printf("TPM2.0 Key generation example\n");
printf("\tKey Blob: %s\n", outputFile);
printf("\tAlgorithm: %s\n", TPM2_GetAlgName(alg));
if(alg == TPM_ALG_SYMCIPHER) {
if (alg == TPM_ALG_SYMCIPHER) {
printf("\t\t %s mode, %d keybits\n", symMode, keyBits);
}
printf("\tTemplate: %s\n", bAIK ? "AIK" : "Default");
Expand Down
31 changes: 24 additions & 7 deletions examples/run_examples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,30 @@ if [ $WOLFCRYPT_ENABLE -eq 1 ]; then
fi
rm -f ececcblob.bin

./examples/keygen/keygen symkeyblob.bin -sym=aescfb128 >> run.out 2>&1
RESULT=$?
[ $RESULT -ne 0 ] && echo -e "keygen sym aes failed! $RESULT" && exit 1
./examples/keygen/keyload symkeyblob.bin >> run.out 2>&1
RESULT=$?
rm -f symkeyblob.bin
[ $RESULT -ne 0 ] && echo -e "keygen sym aes load failed! $RESULT" && exit 1

# KeyGen AES Tests
run_keygen_aes_test() { # Usage: run_keygen_aes_test [aescfb128]
echo -e "KeyGen test: $1"
./examples/keygen/keygen symkeyblob.bin -sym=$1 >> run.out 2>&1
RESULT=$?
[ $RESULT -ne 0 ] && echo -e "keygen sym $1 failed! $RESULT" && exit 1
./examples/keygen/keyload symkeyblob.bin >> run.out 2>&1
RESULT=$?
rm -f symkeyblob.bin
[ $RESULT -ne 0 ] && echo -e "keygen sym $1 load failed! $RESULT" && exit 1
}

run_keygen_aes_test "aescfb128"
run_keygen_aes_test "aescfb256"
run_keygen_aes_test "aesctr128"
run_keygen_aes_test "aesctr256"
run_keygen_aes_test "aescbc128"
run_keygen_aes_test "aescbc256"

# AES 192-bit not supported with SWTPM
#run_keygen_aes_test "aescfb192"
#run_keygen_aes_test "aesctr192"
#run_keygen_aes_test "aescbc192"

./examples/keygen/keygen keyedhashblob.bin -keyedhash >> run.out 2>&1
RESULT=$?
Expand Down
21 changes: 18 additions & 3 deletions src/tpm2.c
Original file line number Diff line number Diff line change
Expand Up @@ -5650,6 +5650,7 @@ int TPM2_GetName(TPM2_CTX* ctx, UINT32 handleValue, int handleCnt, int idx, TPM2
return TPM_RC_SUCCESS;
}

/* Caller must zeroize/memset(0) pcr (TPML_PCR_SELECTION) */
void TPM2_SetupPCRSel(TPML_PCR_SELECTION* pcr, TPM_ALG_ID alg, int pcrIndex)
{
int i = 0;
Expand All @@ -5662,21 +5663,35 @@ void TPM2_SetupPCRSel(TPML_PCR_SELECTION* pcr, TPM_ALG_ID alg, int pcrIndex)
else {
/* iterate over all banks until the alg matches */
for (i = 0; (word32)i < pcr->count; i++) {
if (pcr->pcrSelections[0].hash == alg)
if (pcr->pcrSelections[i].hash == alg)
break;
}

/* if no match increase the number of banks */
if ((word32)i >= pcr->count)
if ((word32)i >= pcr->count) {
if (pcr->count + 1 > HASH_COUNT) {
#ifdef DEBUG_WOLFTPM
printf("TPM2_SetupPCRSel: Hash algorithm count error\n");
#endif
return;
}
pcr->count++;
}
}

pcr->pcrSelections[i].hash = alg;
pcr->pcrSelections[i].sizeofSelect = PCR_SELECT_MAX;
pcr->pcrSelections[i].pcrSelect[pcrIndex >> 3] = (1 << (pcrIndex & 0x7));
pcr->pcrSelections[i].pcrSelect[pcrIndex >> 3] |=
(1 << (pcrIndex & 0x7));
}
#ifdef DEBUG_WOLFTPM
else {
printf("Invalid PCR Index %d\n", pcrIndex);
}
#endif
}

/* Caller must zeroize/memset(0) pcr (TPML_PCR_SELECTION) */
void TPM2_SetupPCRSelArray(TPML_PCR_SELECTION* pcr, TPM_ALG_ID alg,
byte* pcrArray, word32 pcrArraySz)
{
Expand Down
59 changes: 59 additions & 0 deletions tests/unit_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,64 @@ static void test_wolfTPM2_GetRandom(void)
rc == 0 ? "Passed" : "Failed");
}

static void test_TPM2_PCRSel(void)
{
int rc = 0;
TPML_PCR_SELECTION pcr;
byte pcrArray[PCR_SELECT_MAX];
word32 pcrArraySz;

XMEMSET(&pcr, 0, sizeof(pcr));
XMEMSET(pcrArray, 0, sizeof(pcrArray));

pcrArraySz = 0;
pcrArray[pcrArraySz++] = 1;
pcrArray[pcrArraySz++] = 2;
pcrArray[pcrArraySz++] = 3;
TPM2_SetupPCRSelArray(&pcr, TPM_ALG_SHA, pcrArray, pcrArraySz);

pcrArraySz = 0;
pcrArray[pcrArraySz++] = 4;
pcrArray[pcrArraySz++] = 5;
pcrArray[pcrArraySz++] = 6;
TPM2_SetupPCRSelArray(&pcr, TPM_ALG_SHA256, pcrArray, pcrArraySz);

if (pcr.count != 2 ||
pcr.pcrSelections[0].hash != TPM_ALG_SHA ||
pcr.pcrSelections[0].pcrSelect[0] != 0x0E ||
pcr.pcrSelections[1].hash != TPM_ALG_SHA256 ||
pcr.pcrSelections[1].pcrSelect[0] != 0x70
) {
rc = BAD_FUNC_ARG;
}
AssertIntEQ(rc, 0);

/* Test bad case - invalid PCR */
XMEMSET(&pcr, 0, sizeof(pcr));
pcrArray[0] = PCR_SELECT_MAX+1;
TPM2_SetupPCRSelArray(&pcr, TPM_ALG_SHA256, pcrArray, 1);
if (pcr.count != 0) {
rc = BAD_FUNC_ARG;
}

/* Test bad case - too many hash algorithms */
XMEMSET(&pcr, 0, sizeof(pcr));
pcrArray[0] = 1;
TPM2_SetupPCRSelArray(&pcr, TPM_ALG_SHA, pcrArray, 1);
pcrArray[0] = 2;
TPM2_SetupPCRSelArray(&pcr, TPM_ALG_SHA256, pcrArray, 1);
pcrArray[0] = 3;
TPM2_SetupPCRSelArray(&pcr, TPM_ALG_SHA384, pcrArray, 1);
pcrArray[0] = 4;
TPM2_SetupPCRSelArray(&pcr, TPM_ALG_SHA512, pcrArray, 1);
if (pcr.count != HASH_COUNT) {
rc = BAD_FUNC_ARG;
}

printf("Test TPM Wrapper:\tPCR Select Array:\t%s\n",
rc == 0 ? "Passed" : "Failed");
}

static void test_wolfTPM2_Cleanup(void)
{
int rc;
Expand Down Expand Up @@ -603,6 +661,7 @@ int unit_tests(int argc, char *argv[])
test_wolfTPM2_OpenExisting();
test_wolfTPM2_GetCapabilities();
test_wolfTPM2_GetRandom();
test_TPM2_PCRSel();
test_TPM2_KDFa();
test_wolfTPM2_ReadPublicKey();
test_wolfTPM2_CSR();
Expand Down
19 changes: 12 additions & 7 deletions wolftpm/tpm2.h
Original file line number Diff line number Diff line change
Expand Up @@ -3363,15 +3363,15 @@ WOLFTPM_API int TPM2_GetNonce(byte* nonceBuf, int nonceSz);
\brief Helper function to prepare a correct PCR selection
For example, when preparing to create a TPM2_Quote

\param pcr pointer to a structure of type TPML_PCR_SELECTION
\param pcr pointer to a structure of type TPML_PCR_SELECTION. Note: Caller must zeroize/memset(0)
\param alg value of type TPM_ALG_ID specifying the type of hash algorithm used
\param pcrIndex value between 0 and 23 specifying the PCR register for use

_Example_
\code
int pcrIndex = 16; // This is a PCR register for DEBUG & testing purposes
PCR_Read_In pcrRead;

XMEMSET(&pcrRead, 0, sizeof(pcrRead));
TPM2_SetupPCRSel(&pcrRead.pcrSelectionIn, TPM_ALG_SHA256, pcrIndex);
\endcode

Expand All @@ -3388,17 +3388,22 @@ WOLFTPM_API void TPM2_SetupPCRSel(TPML_PCR_SELECTION* pcr, TPM_ALG_ID alg,
\brief Helper function to prepare a correct PCR selection with multiple indices
For example, when preparing to create a TPM2_Quote

\param pcr pointer to a structure of type TPML_PCR_SELECTION
\param pcr pointer to a structure of type TPML_PCR_SELECTION. Note: Caller must zeroize/memset(0)
\param alg value of type TPM_ALG_ID specifying the type of hash algorithm used
\param pcrArray array of values between 0 and 23 specifying the PCR register for use
\param pcrArrayLen length of the pcrArray
\param pcrArraySz length of the pcrArray

_Example_
\code
int pcrIndex = 16; // This is a PCR register for DEBUG & testing purposes
PCR_Read_In pcrRead;
byte pcrArray[PCR_SELECT_MAX];
word32 pcrArraySz = 0;

TPM2_SetupPCRSel(&pcrRead.pcrSelectionIn, TPM_ALG_SHA256, pcrIndex);
XMEMSET(&pcrRead, 0, sizeof(pcrRead));
XMEMSET(pcrArray, 0, sizeof(pcrArray));
pcrArray[pcrArraySz++] = 16; // This is a PCR register for DEBUG & testing purposes

TPM2_SetupPCRSelArray(&pcrRead.pcrSelectionIn, TPM_ALG_SHA256, pcrArray, pcrArraySz);
\endcode

\sa TPM2_PCR_Read
Expand All @@ -3407,7 +3412,7 @@ WOLFTPM_API void TPM2_SetupPCRSel(TPML_PCR_SELECTION* pcr, TPM_ALG_ID alg,
\sa TPM2_Quote
*/
WOLFTPM_API void TPM2_SetupPCRSelArray(TPML_PCR_SELECTION* pcr, TPM_ALG_ID alg,
byte* pcrArray, word32 pcrArrayLen);
byte* pcrArray, word32 pcrArraySz);

/*!
\ingroup TPM2_Proprietary
Expand Down
Loading