diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f014bf1..c7675e10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -556,6 +556,7 @@ if(WOLFTPM_FWTPM) ) target_compile_definitions(fwtpm_unit_test PRIVATE "WOLFTPM_FWTPM" + "WOLFTPM_FWTPM_UNIT_TEST" "FWTPM_NV_FILE=\"fwtpm_test_nv.bin\"" ) if(WOLFTPM_FWTPM_NV_APPEND_ONLY) diff --git a/docs/FWTPM.md b/docs/FWTPM.md index a63b0620..61829959 100644 --- a/docs/FWTPM.md +++ b/docs/FWTPM.md @@ -643,7 +643,8 @@ disabled, the corresponding TPM commands are excluded from the build. | `NO_RSA` | not defined | Excludes RSA keygen, sign, verify, `RSA_Encrypt`, `RSA_Decrypt` | | `HAVE_ECC` | defined | Enables ECC keygen, sign, verify, `ECDH_KeyGen`, `ECDH_ZGen`, `ECC_Parameters` | | `HAVE_ECC384` | defined | Enables P-384 curve support | -| `HAVE_ECC521` | defined | Enables P-521 curve support | +| `HAVE_ECC521` or `HAVE_ALL_CURVES` | build-dependent | Enables P-521 when `MAX_ECC_KEY_BITS >= 521` provides 66-byte TPM ECC fields | +| `ECC_MIN_KEY_SZ` | wolfCrypt-defined | Excludes smaller curves from `ECC_Parameters` and `TPM_CAP_ECC_CURVES` | | `NO_AES` | not defined | Excludes `EncryptDecrypt`, `EncryptDecrypt2`, AES parameter encryption | | `WOLFSSL_SHA384` | defined | Enables SHA-384 PCR bank | diff --git a/src/fwtpm/fwtpm_command.c b/src/fwtpm/fwtpm_command.c index eab309ea..787445ca 100644 --- a/src/fwtpm/fwtpm_command.c +++ b/src/fwtpm/fwtpm_command.c @@ -39,6 +39,7 @@ #include #include +#include #include #include @@ -1207,6 +1208,55 @@ static void FwPatchMoreData(TPM2_Packet* rsp, int pos, byte v) rsp->buf[pos] = v; } +#ifdef HAVE_ECC +typedef struct FWTPM_ECC_CURVE_INFO { + UINT16 tpmCurve; + UINT16 keyBits; +} FWTPM_ECC_CURVE_INFO; + +static const FWTPM_ECC_CURVE_INFO gFwEccCurves[] = { + { TPM_ECC_NIST_P256, 256 }, + { TPM_ECC_NIST_P384, 384 }, +#ifdef FWTPM_HAVE_ECC521 + { TPM_ECC_NIST_P521, 521 }, +#endif +}; + +static const FWTPM_ECC_CURVE_INFO* FwGetEccCurveInfo(UINT16 curve) +{ + int i; + + for (i = 0; i < (int)(sizeof(gFwEccCurves) / + sizeof(gFwEccCurves[0])); i++) { + if (gFwEccCurves[i].tpmCurve == curve) { + return &gFwEccCurves[i]; + } + } + return NULL; +} + +static const ecc_set_type* FwGetEccCurveParams(UINT16 curve) +{ + const FWTPM_ECC_CURVE_INFO* curveInfo; + int wcCurve; + int curveIdx; + + curveInfo = FwGetEccCurveInfo(curve); + if (curveInfo == NULL || curveInfo->keyBits < ECC_MIN_KEY_SZ) { + return NULL; + } + wcCurve = FwGetWcCurveId(curve); + if (wcCurve < 0) { + return NULL; + } + curveIdx = wc_ecc_get_curve_idx(wcCurve); + if (curveIdx < 0) { + return NULL; + } + return wc_ecc_get_curve_params(curveIdx); +} +#endif /* HAVE_ECC */ + /* Select the numerically lowest handle in handleClass that is at or above * property and, after the first selection, greater than previous. The slot * tables are intentionally rescanned per result: their configured defaults @@ -1789,9 +1839,35 @@ static TPM_RC FwCmd_GetCapability(FWTPM_CTX* ctx, TPM2_Packet* cmd, } break; } + case TPM_CAP_ECC_CURVES: { + #ifdef HAVE_ECC + UINT32 count = 0; + int countPos = rsp->pos; + + TPM2_Packet_AppendU32(rsp, 0); /* back-patched below */ + for (i = 0; i < (UINT32)(sizeof(gFwEccCurves) / + sizeof(gFwEccCurves[0])); i++) { + if ((UINT32)gFwEccCurves[i].tpmCurve >= property && + FwGetEccCurveParams(gFwEccCurves[i].tpmCurve) != NULL) { + if (count < propertyCount) { + TPM2_Packet_AppendU16(rsp, + gFwEccCurves[i].tpmCurve); + count++; + } + else { + FwPatchMoreData(rsp, moreDataPos, 1); + break; + } + } + } + FwPatchU32BE(rsp, countPos, count); + #else + TPM2_Packet_AppendU32(rsp, 0); + #endif + break; + } case TPM_CAP_PP_COMMANDS: case TPM_CAP_AUDIT_COMMANDS: - case TPM_CAP_ECC_CURVES: TPM2_Packet_AppendU32(rsp, 0); break; @@ -15515,59 +15591,89 @@ static TPM_RC FwCmd_ActivateCredential(FWTPM_CTX* ctx, TPM2_Packet* cmd, /* ================================================================== */ #ifndef FWTPM_NO_ECDH -/* Convert hex string to binary. Returns byte count, or -1 on error. */ +static int FwHexNibble(char c) +{ + if (c >= '0' && c <= '9') { + return c - '0'; + } + if (c >= 'A' && c <= 'F') { + return c - 'A' + 10; + } + if (c >= 'a' && c <= 'f') { + return c - 'a' + 10; + } + return -1; +} + +/* Convert a big-endian hex value to binary. An odd leading digit is the low + * nibble of the first output byte. Returns byte count, or -1 on error. */ static int FwHexToBin(const char* hex, byte* out, int outSz) { - int i, len; - if (hex == NULL) return -1; - len = (int)XSTRLEN(hex); - if (len & 1) return -1; - len /= 2; - if (len > outSz) return -1; - for (i = 0; i < len; i++) { - byte hi, lo; - char ch = hex[i * 2]; - char cl = hex[i * 2 + 1]; - hi = (byte)((ch >= 'A' && ch <= 'F') ? (ch - 'A' + 10) : - (ch >= 'a' && ch <= 'f') ? (ch - 'a' + 10) : (ch - '0')); - lo = (byte)((cl >= 'A' && cl <= 'F') ? (cl - 'A' + 10) : - (cl >= 'a' && cl <= 'f') ? (cl - 'a' + 10) : (cl - '0')); - out[i] = (byte)((hi << 4) | lo); + int i, len, decodedLen, outPos = 0; + int hi, lo; + size_t hexLen; + + if (hex == NULL || out == NULL || outSz < 0) return -1; + hexLen = XSTRLEN(hex); + if (hexLen > (size_t)INT_MAX) return -1; + len = (int)hexLen; + decodedLen = len / 2 + (len & 1); + if (decodedLen > outSz) { + return -1; } - return len; + + i = 0; + if ((len & 1) != 0) { + lo = FwHexNibble(hex[i++]); + if (lo < 0) return -1; + out[outPos++] = (byte)lo; + } + while (i < len) { + hi = FwHexNibble(hex[i++]); + lo = FwHexNibble(hex[i++]); + if (hi < 0 || lo < 0) return -1; + out[outPos++] = (byte)((hi << 4) | lo); + } + return outPos; } +#ifdef WOLFTPM_FWTPM_UNIT_TEST +int FWTPM_TestHexToBin(const char* hex, byte* out, int outSz); + +int FWTPM_TestHexToBin(const char* hex, byte* out, int outSz) +{ + return FwHexToBin(hex, out, outSz); +} +#endif + /* --- TPM2_ECC_Parameters (CC 0x0178) --- * Returns curve parameters from wolfCrypt's ecc_set_type via * wc_ecc_get_curve_params(). Automatically supports P-256, P-384, - * and P-521 (when HAVE_ECC521 is defined). */ + * and P-521 when wolfCrypt and the TPM ECC buffers support it. */ static TPM_RC FwCmd_ECC_Parameters(FWTPM_CTX* ctx, TPM2_Packet* cmd, int cmdSize, TPM2_Packet* rsp, UINT16 cmdTag) { TPM_RC rc = TPM_RC_SUCCESS; UINT16 curveID; - int wcCurve, curveIdx, f; + UINT16 keyBits; + int f; + const FWTPM_ECC_CURVE_INFO* curveInfo = NULL; const ecc_set_type* params = NULL; byte paramBuf[MAX_ECC_BYTES]; int paramSz; + int padSz; const char* fields[6]; (void)ctx; (void)cmdSize; (void)cmdTag; TPM2_Packet_ParseU16(cmd, &curveID); - wcCurve = FwGetWcCurveId(curveID); - if (wcCurve < 0) { + curveInfo = FwGetEccCurveInfo(curveID); + params = FwGetEccCurveParams(curveID); + if (curveInfo == NULL || params == NULL) { rc = TPM_RC_CURVE; } - - if (rc == 0) { - curveIdx = wc_ecc_get_curve_idx(wcCurve); - params = wc_ecc_get_curve_params(curveIdx); - if (params == NULL) { - rc = TPM_RC_CURVE; - } - } + keyBits = (curveInfo != NULL) ? curveInfo->keyBits : 0; #ifdef DEBUG_WOLFTPM if (rc == 0) { @@ -15578,7 +15684,7 @@ static TPM_RC FwCmd_ECC_Parameters(FWTPM_CTX* ctx, TPM2_Packet* cmd, if (rc == 0) { TPM2_Packet_AppendU16(rsp, curveID); - TPM2_Packet_AppendU16(rsp, (UINT16)(params->size * 8)); /* bits */ + TPM2_Packet_AppendU16(rsp, keyBits); TPM2_Packet_AppendU16(rsp, TPM_ALG_NULL); /* kdf */ TPM2_Packet_AppendU16(rsp, TPM_ALG_NULL); /* sign */ @@ -15597,7 +15703,15 @@ static TPM_RC FwCmd_ECC_Parameters(FWTPM_CTX* ctx, TPM2_Packet* cmd, rc = TPM_RC_FAILURE; break; } - TPM2_Packet_AppendU16(rsp, (UINT16)paramSz); + if (paramSz > params->size) { + rc = TPM_RC_FAILURE; + break; + } + padSz = params->size - paramSz; + TPM2_Packet_AppendU16(rsp, (UINT16)(padSz + paramSz)); + while (padSz-- > 0) { + TPM2_Packet_AppendU8(rsp, 0); + } TPM2_Packet_AppendBytes(rsp, paramBuf, paramSz); } diff --git a/src/fwtpm/fwtpm_crypto.c b/src/fwtpm/fwtpm_crypto.c index 95448298..215ce863 100644 --- a/src/fwtpm/fwtpm_crypto.c +++ b/src/fwtpm/fwtpm_crypto.c @@ -417,36 +417,63 @@ int FwAppendCreationHashAndTicket(FWTPM_CTX* ctx, TPM2_Packet* rsp, /* Map TPM ECC curve to wolfCrypt curve ID */ int FwGetWcCurveId(UINT16 tpmCurve) { + int curveIdx; + int keyBits; + int wcCurve; + switch (tpmCurve) { case TPM_ECC_NIST_P256: - return ECC_SECP256R1; + keyBits = 256; + wcCurve = ECC_SECP256R1; + break; case TPM_ECC_NIST_P384: - return ECC_SECP384R1; - #ifdef HAVE_ECC521 + keyBits = 384; + wcCurve = ECC_SECP384R1; + break; + #ifdef FWTPM_HAVE_ECC521 case TPM_ECC_NIST_P521: - return ECC_SECP521R1; + keyBits = 521; + wcCurve = ECC_SECP521R1; + break; #endif default: return -1; } + + if (keyBits < ECC_MIN_KEY_SZ) { + return -1; + } + curveIdx = wc_ecc_get_curve_idx(wcCurve); + if (curveIdx < 0 || wc_ecc_get_curve_params(curveIdx) == NULL) { + return -1; + } + return wcCurve; } #endif /* HAVE_ECC */ /* Get ECC key size in bytes from TPM curve */ int FwGetEccKeySize(UINT16 tpmCurve) { +#ifdef HAVE_ECC + if (FwGetWcCurveId(tpmCurve) < 0) { + return 0; + } switch (tpmCurve) { case TPM_ECC_NIST_P256: return 32; case TPM_ECC_NIST_P384: return 48; - #ifdef HAVE_ECC521 + #ifdef FWTPM_HAVE_ECC521 case TPM_ECC_NIST_P521: return 66; #endif default: return 0; } +#else + (void)tpmCurve; + return 0; +#endif } /* ================================================================== */ @@ -532,7 +559,7 @@ TPM_RC FwGenerateEccKey(WC_RNG* rng, FWTPM_ALLOC_VAR(eccKey, ecc_key); - if (wcCurve < 0 || keySz == 0) { + if (wcCurve < 0 || keySz == 0 || keySz > MAX_ECC_KEY_BYTES) { FWTPM_FREE_VAR(eccKey); return TPM_RC_CURVE; } @@ -1147,7 +1174,7 @@ static int FwDhkemParamsLookup(int wcCurve, TPMI_ALG_HASH kdfHash, *hkdfHashOut = WC_HASH_TYPE_SHA384; return 0; } -#ifdef HAVE_ECC521 +#ifdef FWTPM_HAVE_ECC521 if (wcCurve == ECC_SECP521R1 && kdfHash == TPM_ALG_SHA512) { *kemIdOut = 0x0012; *nSecretOut = 64; *nPkOut = 133; *hkdfHashOut = WC_HASH_TYPE_SHA512; diff --git a/tests/fwtpm_unit_tests.c b/tests/fwtpm_unit_tests.c index bae3bbd2..86bd9052 100644 --- a/tests/fwtpm_unit_tests.c +++ b/tests/fwtpm_unit_tests.c @@ -1161,6 +1161,213 @@ static void test_fwtpm_getcap_paging(void) fwtpm_pass("GetCapability paging convergence:", 0); } +static int getcap_ecc_curves(FWTPM_CTX* ctx, UINT32 property, + UINT32 propertyCount, UINT16* curves, int curveCapacity, byte* moreData) +{ + UINT32 count; + int rc, rspSize, cmdSz, i; + + cmdSz = BuildCmdHeader(gCmd, TPM_ST_NO_SESSIONS, 0, + TPM_CC_GetCapability); + PutU32BE(gCmd + cmdSz, TPM_CAP_ECC_CURVES); cmdSz += 4; + PutU32BE(gCmd + cmdSz, property); cmdSz += 4; + PutU32BE(gCmd + cmdSz, propertyCount); cmdSz += 4; + PutU32BE(gCmd + 2, (UINT32)cmdSz); + rspSize = 0; + rc = FWTPM_ProcessCommand(ctx, gCmd, cmdSz, gRsp, &rspSize, 0); + AssertIntEQ(rc, TPM_RC_SUCCESS); + AssertIntEQ(GetRspRC(gRsp), TPM_RC_SUCCESS); + AssertTrue(rspSize >= TPM2_HEADER_SIZE + 9); + AssertIntEQ(GetU32BE(gRsp + TPM2_HEADER_SIZE + 1), + (int)TPM_CAP_ECC_CURVES); + + *moreData = gRsp[TPM2_HEADER_SIZE]; + count = GetU32BE(gRsp + TPM2_HEADER_SIZE + 5); + AssertTrue((int)count <= curveCapacity); + AssertTrue(rspSize >= TPM2_HEADER_SIZE + 9 + ((int)count * 2)); + for (i = 0; i < (int)count; i++) { + curves[i] = GetU16BE(gRsp + TPM2_HEADER_SIZE + 9 + (i * 2)); + } + return (int)count; +} + +#if defined(HAVE_ECC) && !defined(FWTPM_NO_ECDH) +static UINT16 test_ecc_curve_bits(UINT16 curve) +{ + switch (curve) { + case TPM_ECC_NIST_P256: + return 256; + case TPM_ECC_NIST_P384: + return 384; + case TPM_ECC_NIST_P521: + return 521; + default: + return 0; + } +} + +static void check_ecc_parameters(FWTPM_CTX* ctx, UINT16 curve) +{ + UINT16 fieldSz; + UINT16 keyBits; + int rc, rspSize, cmdSz, pos, field; + int keyBytes; + + cmdSz = BuildCmdHeader(gCmd, TPM_ST_NO_SESSIONS, 0, + TPM_CC_ECC_Parameters); + PutU16BE(gCmd + cmdSz, curve); cmdSz += 2; + PutU32BE(gCmd + 2, (UINT32)cmdSz); + rspSize = 0; + rc = FWTPM_ProcessCommand(ctx, gCmd, cmdSz, gRsp, &rspSize, 0); + AssertIntEQ(rc, TPM_RC_SUCCESS); + AssertIntEQ(GetRspRC(gRsp), TPM_RC_SUCCESS); + pos = TPM2_HEADER_SIZE; + AssertIntEQ(GetU16BE(gRsp + pos), curve); + pos += 2; + + keyBits = test_ecc_curve_bits(curve); + AssertIntNE(keyBits, 0); + AssertIntEQ(GetU16BE(gRsp + pos), keyBits); + pos += 2; + keyBytes = (keyBits + 7) / 8; + + AssertIntEQ(GetU16BE(gRsp + pos), TPM_ALG_NULL); /* kdf */ + pos += 2; + AssertIntEQ(GetU16BE(gRsp + pos), TPM_ALG_NULL); /* sign */ + pos += 2; + + /* Curve parameters use a consistent fixed-width big-endian encoding. */ + for (field = 0; field < 6; field++) { + AssertTrue(pos + 2 <= rspSize); + fieldSz = GetU16BE(gRsp + pos); + pos += 2; + AssertIntEQ(fieldSz, keyBytes); + AssertTrue(pos + fieldSz <= rspSize); + if (curve == TPM_ECC_NIST_P521 && field == 0) { + /* p = 0x01 followed by 65 0xff bytes. */ + AssertIntEQ(gRsp[pos], 0x01); + AssertIntEQ(gRsp[pos + fieldSz - 1], 0xff); + } + else if (curve == TPM_ECC_NIST_P521 && field == 3) { + /* Gx is 65 bytes and must be left-padded to the 66-byte field. */ + AssertIntEQ(gRsp[pos], 0x00); + AssertIntEQ(gRsp[pos + 1], 0xc6); + } + pos += fieldSz; + } + + AssertTrue(pos + 2 <= rspSize); + fieldSz = GetU16BE(gRsp + pos); /* cofactor h */ + pos += 2; + AssertIntEQ(fieldSz, 1); + AssertTrue(pos + fieldSz <= rspSize); + pos += fieldSz; + AssertIntEQ(pos, rspSize); +} + +#endif /* HAVE_ECC && !FWTPM_NO_ECDH */ + +/* Curve capability pages expose every compiled curve in ascending order and + * each advertised curve is accepted by ECC_Parameters when that command is + * enabled. */ +static void test_fwtpm_getcap_ecc_curves(void) +{ + FWTPM_CTX ctx; + UINT16 expected[3]; + UINT16 actual[3]; + UINT32 property; + byte moreData; + int expectedCount = 0; + int count, i; + +#ifdef HAVE_ECC + int curveIdx; + static const struct { + UINT16 tpmCurve; + UINT16 keyBits; + int wcCurve; + } candidates[] = { + { TPM_ECC_NIST_P256, 256, ECC_SECP256R1 }, + { TPM_ECC_NIST_P384, 384, ECC_SECP384R1 }, + #ifdef FWTPM_HAVE_ECC521 + { TPM_ECC_NIST_P521, 521, ECC_SECP521R1 }, + #endif + }; + + for (i = 0; i < (int)(sizeof(candidates) / + sizeof(candidates[0])); i++) { + curveIdx = wc_ecc_get_curve_idx(candidates[i].wcCurve); + if (candidates[i].keyBits >= ECC_MIN_KEY_SZ && curveIdx >= 0 && + wc_ecc_get_curve_params(curveIdx) != NULL) { + AssertIntEQ(FwGetWcCurveId(candidates[i].tpmCurve), + candidates[i].wcCurve); + AssertIntEQ(FwGetEccKeySize(candidates[i].tpmCurve), + (candidates[i].keyBits + 7) / 8); + expected[expectedCount++] = candidates[i].tpmCurve; + } + else { + AssertIntEQ(FwGetWcCurveId(candidates[i].tpmCurve), -1); + AssertIntEQ(FwGetEccKeySize(candidates[i].tpmCurve), 0); + } + } +#endif + + XMEMSET(&ctx, 0, sizeof(ctx)); + AssertIntEQ(fwtpm_test_startup(&ctx), 0); + + count = getcap_ecc_curves(&ctx, 0, 0, actual, 3, &moreData); + AssertIntEQ(count, 0); + AssertIntEQ(moreData, expectedCount > 0); + + count = getcap_ecc_curves(&ctx, 0, 3, actual, 3, &moreData); + AssertIntEQ(count, expectedCount); + AssertIntEQ(moreData, 0); + for (i = 0; i < expectedCount; i++) { + AssertIntEQ(actual[i], expected[i]); + #if defined(HAVE_ECC) && !defined(FWTPM_NO_ECDH) + check_ecc_parameters(&ctx, actual[i]); + #endif + } + + property = 0; + for (i = 0; i < expectedCount; i++) { + count = getcap_ecc_curves(&ctx, property, 1, actual, 3, + &moreData); + AssertIntEQ(count, 1); + AssertIntEQ(actual[0], expected[i]); + AssertIntEQ(moreData, i + 1 < expectedCount); + property = (UINT32)actual[0] + 1u; + } + count = getcap_ecc_curves(&ctx, property, 1, actual, 3, &moreData); + AssertIntEQ(count, 0); + AssertIntEQ(moreData, 0); + + FWTPM_Cleanup(&ctx); + fwtpm_pass("GetCapability(ECC_CURVES):", 0); +} + +#if defined(HAVE_ECC) && !defined(FWTPM_NO_ECDH) && \ + defined(WOLFTPM_FWTPM_UNIT_TEST) +int FWTPM_TestHexToBin(const char* hex, byte* out, int outSz); + +static void test_fwtpm_hex_to_bin(void) +{ + byte out[2]; + + XMEMSET(out, 0, sizeof(out)); + AssertIntEQ(FWTPM_TestHexToBin("abc", out, sizeof(out)), 2); + AssertIntEQ(out[0], 0x0a); + AssertIntEQ(out[1], 0xbc); + AssertIntEQ(FWTPM_TestHexToBin("f", out, sizeof(out)), 1); + AssertIntEQ(out[0], 0x0f); + AssertIntEQ(FWTPM_TestHexToBin("0g", out, sizeof(out)), -1); + AssertIntEQ(FWTPM_TestHexToBin("1234", out, 1), -1); + AssertIntEQ(FWTPM_TestHexToBin(NULL, out, sizeof(out)), -1); + + fwtpm_pass("ECC parameter hex decoding:", 0); +} +#endif + #if FWTPM_MAX_OBJECTS >= 2 || FWTPM_MAX_PERSISTENT >= 2 || \ FWTPM_MAX_SESSIONS >= 2 || \ (!defined(FWTPM_NO_NV) && FWTPM_MAX_NV_INDICES >= 2) @@ -2681,7 +2888,7 @@ static void test_fwtpm_ecc_dhkem_p384_roundtrip(void) "Encap/Decap ECC DHKEM (P-384/HKDF-SHA384) Roundtrip:"); } -#ifdef HAVE_ECC521 +#ifdef FWTPM_HAVE_ECC521 static void test_fwtpm_ecc_dhkem_p521_roundtrip(void) { RunEccDhkemRoundtrip(TPM_ECC_NIST_P521, TPM_ALG_SHA512, @@ -13487,6 +13694,11 @@ int fwtpm_unit_tests(int argc, char *argv[]) test_fwtpm_getcap_properties(); test_fwtpm_getcap_pcrs(); test_fwtpm_getcap_paging(); + test_fwtpm_getcap_ecc_curves(); +#if defined(HAVE_ECC) && !defined(FWTPM_NO_ECDH) && \ + defined(WOLFTPM_FWTPM_UNIT_TEST) + test_fwtpm_hex_to_bin(); +#endif #if FWTPM_MAX_OBJECTS >= 2 || FWTPM_MAX_PERSISTENT >= 2 || \ FWTPM_MAX_SESSIONS >= 2 || \ (!defined(FWTPM_NO_NV) && FWTPM_MAX_NV_INDICES >= 2) @@ -13567,7 +13779,7 @@ int fwtpm_unit_tests(int argc, char *argv[]) test_fwtpm_signsequence_handle_auth_required(); test_fwtpm_verifysequence_long_message(); test_fwtpm_ecc_dhkem_p384_roundtrip(); -#ifdef HAVE_ECC521 +#ifdef FWTPM_HAVE_ECC521 test_fwtpm_ecc_dhkem_p521_roundtrip(); #endif #ifdef WOLFTPM_HASH_MLDSA diff --git a/tests/include.am b/tests/include.am index 05b58006..4b6985a8 100644 --- a/tests/include.am +++ b/tests/include.am @@ -32,7 +32,8 @@ tests_fwtpm_unit_test_SOURCES = \ src/tpm2_crypto.c \ src/tpm2_param_enc.c tests_fwtpm_unit_test_CFLAGS = -DWOLFTPM_FWTPM -DFWTPM_NV_FILE=\"fwtpm_test_nv.bin\" $(AM_CFLAGS) -tests_fwtpm_unit_test_CPPFLAGS = -DWOLFTPM_FWTPM $(AM_CPPFLAGS) +tests_fwtpm_unit_test_CPPFLAGS = \ + -DWOLFTPM_FWTPM -DWOLFTPM_FWTPM_UNIT_TEST $(AM_CPPFLAGS) tests_fwtpm_unit_test_LDADD = $(LIB_STATIC_ADD) endif diff --git a/wolftpm/fwtpm/fwtpm.h b/wolftpm/fwtpm/fwtpm.h index a6f7ceb1..f3c110cc 100644 --- a/wolftpm/fwtpm/fwtpm.h +++ b/wolftpm/fwtpm/fwtpm.h @@ -44,6 +44,15 @@ #include #endif +/* P-521 needs both wolfCrypt curve support and 66-byte TPM ECC fields. */ +#if defined(HAVE_ECC) && \ + (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && \ + MAX_ECC_KEY_BYTES >= 66 + #if !defined(ECC_MIN_KEY_SZ) || ECC_MIN_KEY_SZ <= 521 + #define FWTPM_HAVE_ECC521 + #endif +#endif + /* Endian byte-array helpers - use shared TPM2_Packet helpers. * Note: argument order differs (Fw: buf,val; TPM2_Packet: val,buf) */ #define FwStoreU16BE(buf, val) TPM2_Packet_U16ToByteArray((val), (buf))