F-12710 - Advertise supported ECC curves

pull/588/head
Aidan Garske 2026-08-31 09:36:59 -07:00
parent 17c6926f80
commit 3507da0429
7 changed files with 408 additions and 43 deletions

View File

@ -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)

View File

@ -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 |

View File

@ -39,6 +39,7 @@
#include <wolftpm/fwtpm/fwtpm_nv.h>
#include <wolftpm/fwtpm/fwtpm_crypto.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -44,6 +44,15 @@
#include <wolftpm/fwtpm/fwtpm_tis.h>
#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))