diff --git a/examples/bench/bench.c b/examples/bench/bench.c index 038aa479..e85f9cbc 100644 --- a/examples/bench/bench.c +++ b/examples/bench/bench.c @@ -160,6 +160,7 @@ static int bench_sym_aes(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* storageKey, double start; TPMT_PUBLIC publicTemplate; WOLFTPM2_KEY aesKey; + byte iv[MAX_AES_BLOCK_SIZE_BYTES]; XMEMSET(&aesKey, 0, sizeof(aesKey)); rc = wolfTPM2_GetKeyTemplate_Symmetric(&publicTemplate, keyBits, algo, @@ -175,8 +176,9 @@ static int bench_sym_aes(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* storageKey, bench_stats_start(&count, &start); do { - rc = wolfTPM2_EncryptDecrypt(dev, &aesKey, in, out, inOutSz, NULL, 0, - isDecrypt); + XMEMSET(iv, 0, sizeof(iv)); + rc = wolfTPM2_EncryptDecrypt(dev, &aesKey, in, out, inOutSz, iv, + sizeof(iv), isDecrypt); if (WOLFTPM_IS_COMMAND_UNAVAILABLE(rc)) { printf("Encrypt/Decrypt unavailable\n"); break; diff --git a/examples/wrap/wrap_test.c b/examples/wrap/wrap_test.c index fd95be54..384c9bae 100644 --- a/examples/wrap/wrap_test.c +++ b/examples/wrap/wrap_test.c @@ -960,14 +960,16 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[]) XMEMSET(cipher.buffer, 0, sizeof(cipher.buffer)); cipher.size = message.size; + XMEMSET(aesIv, 0, sizeof(aesIv)); rc = wolfTPM2_EncryptDecrypt(&dev, &aesKey, message.buffer, cipher.buffer, - message.size, NULL, 0, WOLFTPM2_ENCRYPT); + message.size, aesIv, (word32)sizeof(aesIv), WOLFTPM2_ENCRYPT); if (rc != 0 && !WOLFTPM_IS_COMMAND_UNAVAILABLE(rc)) goto exit; XMEMSET(plain.buffer, 0, sizeof(plain.buffer)); plain.size = message.size; + XMEMSET(aesIv, 0, sizeof(aesIv)); rc = wolfTPM2_EncryptDecrypt(&dev, &aesKey, cipher.buffer, plain.buffer, - cipher.size, NULL, 0, WOLFTPM2_DECRYPT); + cipher.size, aesIv, (word32)sizeof(aesIv), WOLFTPM2_DECRYPT); wolfTPM2_UnloadHandle(&dev, &aesKey.handle); diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index cbbd53f2..a8b74d0b 100644 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -6635,18 +6635,23 @@ int wolfTPM2_EncryptDecryptBlock(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key, XMEMSET(&encDecIn, 0, sizeof(encDecIn)); encDecIn.keyHandle = key->handle.hndl; + /* use symmetric algorithm from key */ + encDecIn.mode = key->pub.publicArea.parameters.symDetail.sym.mode.aes; if (iv == NULL || ivSz == 0) { + /* Modes other than ECB and NULL require an explicit IV */ + if (encDecIn.mode != TPM_ALG_ECB && encDecIn.mode != TPM_ALG_NULL) { + return BAD_FUNC_ARG; + } encDecIn.ivIn.size = MAX_AES_BLOCK_SIZE_BYTES; /* zeros */ } else { + if (ivSz > sizeof(encDecIn.ivIn.buffer)) { + return BUFFER_E; + } encDecIn.ivIn.size = ivSz; - if (encDecIn.ivIn.size > sizeof(encDecIn.ivIn.buffer)) - encDecIn.ivIn.size = sizeof(encDecIn.ivIn.buffer); /* truncate */ XMEMCPY(encDecIn.ivIn.buffer, iv, encDecIn.ivIn.size); } encDecIn.decrypt = isDecrypt; - /* use symmetric algorithm from key */ - encDecIn.mode = key->pub.publicArea.parameters.symDetail.sym.mode.aes; encDecIn.inData.size = inOutSz; XMEMCPY(encDecIn.inData.buffer, in, inOutSz); diff --git a/tests/unit_tests.c b/tests/unit_tests.c index 380f47a9..04631051 100644 --- a/tests/unit_tests.c +++ b/tests/unit_tests.c @@ -2626,6 +2626,78 @@ static void test_wolfTPM2_LoadPrivateKey_NullParent(void) printf("Test TPM Wrapper:\tLoadPrivateKey NullParent:\tPassed\n"); } +static void test_wolfTPM2_EncryptDecryptBlock(void) +{ + int rc; + WOLFTPM2_DEV dev; + WOLFTPM2_KEY key; + byte in[MAX_AES_BLOCK_SIZE_BYTES]; + byte out[MAX_AES_BLOCK_SIZE_BYTES]; + byte iv[MAX_AES_BLOCK_SIZE_BYTES]; + byte bigIv[MAX_SYM_BLOCK_SIZE + 1]; + + XMEMSET(in, 0, sizeof(in)); + XMEMSET(out, 0, sizeof(out)); + XMEMSET(iv, 0, sizeof(iv)); + XMEMSET(bigIv, 0, sizeof(bigIv)); + + rc = wolfTPM2_Init(&dev, TPM2_IoCb, NULL); + AssertIntEQ(rc, 0); + + XMEMSET(&key, 0, sizeof(key)); + + /* CBC mode: NULL IV should return BAD_FUNC_ARG */ + key.pub.publicArea.parameters.symDetail.sym.mode.aes = TPM_ALG_CBC; + rc = wolfTPM2_EncryptDecryptBlock(&dev, &key, in, out, + sizeof(in), NULL, 0, WOLFTPM2_ENCRYPT); + AssertIntEQ(rc, BAD_FUNC_ARG); + + /* CBC mode: ivSz == 0 with non-NULL iv should return BAD_FUNC_ARG */ + rc = wolfTPM2_EncryptDecryptBlock(&dev, &key, in, out, + sizeof(in), iv, 0, WOLFTPM2_ENCRYPT); + AssertIntEQ(rc, BAD_FUNC_ARG); + + /* CFB mode: NULL IV should return BAD_FUNC_ARG */ + key.pub.publicArea.parameters.symDetail.sym.mode.aes = TPM_ALG_CFB; + rc = wolfTPM2_EncryptDecryptBlock(&dev, &key, in, out, + sizeof(in), NULL, 0, WOLFTPM2_ENCRYPT); + AssertIntEQ(rc, BAD_FUNC_ARG); + + /* CTR mode: NULL IV should return BAD_FUNC_ARG */ + key.pub.publicArea.parameters.symDetail.sym.mode.aes = TPM_ALG_CTR; + rc = wolfTPM2_EncryptDecryptBlock(&dev, &key, in, out, + sizeof(in), NULL, 0, WOLFTPM2_ENCRYPT); + AssertIntEQ(rc, BAD_FUNC_ARG); + + /* OFB mode: NULL IV should return BAD_FUNC_ARG */ + key.pub.publicArea.parameters.symDetail.sym.mode.aes = TPM_ALG_OFB; + rc = wolfTPM2_EncryptDecryptBlock(&dev, &key, in, out, + sizeof(in), NULL, 0, WOLFTPM2_ENCRYPT); + AssertIntEQ(rc, BAD_FUNC_ARG); + + /* Oversized IV should return BUFFER_E */ + key.pub.publicArea.parameters.symDetail.sym.mode.aes = TPM_ALG_CBC; + rc = wolfTPM2_EncryptDecryptBlock(&dev, &key, in, out, + sizeof(in), bigIv, sizeof(bigIv), WOLFTPM2_ENCRYPT); + AssertIntEQ(rc, BUFFER_E); + + /* ECB mode: NULL IV should NOT return BAD_FUNC_ARG */ + key.pub.publicArea.parameters.symDetail.sym.mode.aes = TPM_ALG_ECB; + rc = wolfTPM2_EncryptDecryptBlock(&dev, &key, in, out, + sizeof(in), NULL, 0, WOLFTPM2_ENCRYPT); + AssertIntNE(rc, BAD_FUNC_ARG); + + /* NULL mode: NULL IV should NOT return BAD_FUNC_ARG */ + key.pub.publicArea.parameters.symDetail.sym.mode.aes = TPM_ALG_NULL; + rc = wolfTPM2_EncryptDecryptBlock(&dev, &key, in, out, + sizeof(in), NULL, 0, WOLFTPM2_ENCRYPT); + AssertIntNE(rc, BAD_FUNC_ARG); + + wolfTPM2_Cleanup(&dev); + + printf("Test TPM Wrapper:\tEncryptDecryptBlock IV validate:\tPassed\n"); +} + #endif /* !WOLFTPM2_NO_WRAPPER */ #ifndef NO_MAIN_DRIVER @@ -2688,6 +2760,7 @@ int unit_tests(int argc, char *argv[]) test_wolfTPM2_DecodeDer_DefaultAttribs(); #endif test_wolfTPM2_LoadPrivateKey_NullParent(); + test_wolfTPM2_EncryptDecryptBlock(); test_wolfTPM2_KeyBlob(TPM_ALG_RSA); test_wolfTPM2_KeyBlob(TPM_ALG_ECC); #if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(HAVE_ECC) && \