tpm2: Refactor Ecc-specific AlgorithmProfile.c code for reuse

Refactor some Ecc-specific code in AlgorithmProfile.c so it can be reused
for other algorithms later on as well.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
Stefan Berger 2026-02-21 11:57:49 -05:00 committed by Stefan Berger
parent cfbffd84e7
commit 5a6cc8bda5

View File

@ -132,23 +132,25 @@ static const struct {
/* all newly added algorithms must have .canBedisable=true so they can be disabled */
};
static const struct {
struct AlgorithmShortcuts {
const char *name;
BOOL canBeDisabled;
const char *prefix;
} s_EccShortcuts[] = {
};
static const struct AlgorithmShortcuts s_EccShortcuts[] = {
#define ECC_SHORTCUT(NAME, CANDISABLE, PREFIX) \
{ .name = NAME, .canBeDisabled = CANDISABLE, .prefix = PREFIX }
[RUNTIME_ALGORITHM_ECC_NIST_BIT] = ECC_SHORTCUT("ecc-nist", true, "ecc-nist-p"),
[RUNTIME_ALGORITHM_ECC_BN_BIT] = ECC_SHORTCUT("ecc-bn", true, "ecc-bn-p"),
};
static const struct {
struct AlgorithmProperties {
const char *name;
UINT16 keySize;
BOOL canBeDisabled;
unsigned int stateFormatLevel; /* required stateFormatLevel to support this */
} s_EccAlgorithmProperties[] = {
};
static const struct AlgorithmProperties s_EccAlgorithmProperties[] = {
#define ECC(ENABLED, NAME, KEYSIZE, CANDISABLE, SFL) \
{ .name = ENABLED ? NAME : NULL, .keySize = KEYSIZE, .canBeDisabled = CANDISABLE, .stateFormatLevel = SFL }
@ -239,6 +241,64 @@ RuntimeAlgorithmSetDefault(struct RuntimeAlgorithm *RuntimeAlgorithm)
RuntimeAlgorithmEnableAllAlgorithms(RuntimeAlgorithm);
}
static TPM_RC RuntimeAlgorithmSetProfileShortcuts(
const struct AlgorithmShortcuts *shortcuts, size_t shortcuts_len,
const struct AlgorithmProperties *algProps, size_t algProps_len,
const char *token, const size_t token_len,
unsigned int *stateFormatLevel, const unsigned int maxStateFormatLevel,
unsigned char *enabledShortcuts, size_t enabledShortcuts_len,
unsigned char *enabledAlgorithms, size_t enabledAlgorithms_len,
const char *type,
bool *found)
{
size_t prefix_len = token_len;
const char *prefix = token;
bool match_one = true;
size_t cmplen = 0;
size_t idx;
size_t algId;
for (idx = 0; idx < shortcuts_len; idx++) {
cmplen = MAX(strlen(shortcuts[idx].name), token_len);
if (!strncmp(token, shortcuts[idx].name, cmplen)) {
SetBit(idx, enabledShortcuts, enabledShortcuts_len);
match_one = false;
prefix = shortcuts[idx].prefix;
prefix_len = strlen(prefix);
break;
}
}
for (algId = 0; algId < algProps_len; algId++) {
if (!algProps[algId].name)
continue;
if (match_one)
cmplen = MAX(strlen(algProps[algId].name), token_len);
else
cmplen = prefix_len;
if (!strncmp(prefix, algProps[algId].name, cmplen)) {
if (algProps[algId].stateFormatLevel > maxStateFormatLevel) {
/* specific match that is not allowed causes error, otherwise skip */
if (match_one) {
TPMLIB_LogTPM2Error("Requested %s %s requires StateFormatLevel %u but maximum allowed is %u.\n",
type,
algProps[algId].name,
algProps[algId].stateFormatLevel,
maxStateFormatLevel);
return TPM_RC_VALUE;
}
continue;
}
*stateFormatLevel = MAX(*stateFormatLevel,
algProps[algId].stateFormatLevel);
SetBit(algId, enabledAlgorithms, enabledAlgorithms_len);
*found = true;
}
}
return TPM_RC_SUCCESS;
}
/* Set the given profile and runtime-enable the given algorithms. A NULL pointer
* for the profile parameter sets the default profile which enables all algorithms
* and all key sizes without any restrictions.
@ -253,8 +313,8 @@ RuntimeAlgorithmSetProfile(struct RuntimeAlgorithm *RuntimeAlgorithm,
unsigned int maxStateFormatLevel // IN: maximum allowed stateFormatLevel
)
{
size_t toklen, cmplen, i, prefix_len, idx;
const char *token, *comma, *prefix;
size_t toklen, cmplen, i;
const char *token, *comma;
const struct KeySizes *keysizes;
TPM_RC retVal = TPM_RC_SUCCESS;
unsigned long minKeySize;
@ -350,51 +410,18 @@ RuntimeAlgorithmSetProfile(struct RuntimeAlgorithm *RuntimeAlgorithm,
}
if (!found) {
bool match_one = true;
/* handling of ECC curves: shortcuts */
for (idx = 0; idx < ARRAY_SIZE(s_EccShortcuts); idx++) {
cmplen = MAX(strlen(s_EccShortcuts[idx].name), toklen);
if (!strncmp(token, s_EccShortcuts[idx].name, cmplen)) {
SET_BIT(idx, RuntimeAlgorithm->enabledEccShortcuts);
match_one = false;
prefix = s_EccShortcuts[idx].prefix;
prefix_len = strlen(prefix);
break;
}
}
if (match_one) {
prefix = token;
prefix_len = toklen;
}
for (curveId = 0; curveId < ARRAY_SIZE(s_EccAlgorithmProperties); curveId++) {
if (!s_EccAlgorithmProperties[curveId].name)
continue;
if (match_one)
cmplen = MAX(strlen(s_EccAlgorithmProperties[curveId].name), toklen);
else
cmplen = prefix_len;
if (!strncmp(prefix, s_EccAlgorithmProperties[curveId].name, cmplen)) {
if (s_EccAlgorithmProperties[curveId].stateFormatLevel > maxStateFormatLevel) {
/* specific match that is not allowed causes error, otherwise skip */
if (match_one) {
TPMLIB_LogTPM2Error("Requested curve %s requires StateFormatLevel %u but maximum allowed is %u.\n",
s_EccAlgorithmProperties[curveId].name,
s_EccAlgorithmProperties[curveId].stateFormatLevel,
maxStateFormatLevel);
retVal = TPM_RC_VALUE;
goto exit;
}
continue;
}
*stateFormatLevel = MAX(*stateFormatLevel,
s_EccAlgorithmProperties[curveId].stateFormatLevel);
SET_BIT(curveId, RuntimeAlgorithm->enabledEccCurves);
found = true;
}
}
retVal = RuntimeAlgorithmSetProfileShortcuts(
s_EccShortcuts, ARRAY_SIZE(s_EccShortcuts),
s_EccAlgorithmProperties, ARRAY_SIZE(s_EccAlgorithmProperties),
token, toklen,
stateFormatLevel, maxStateFormatLevel,
RuntimeAlgorithm->enabledEccShortcuts, sizeof(RuntimeAlgorithm->enabledEccShortcuts),
RuntimeAlgorithm->enabledEccCurves, sizeof(RuntimeAlgorithm->enabledEccCurves),
"curve",
&found);
if (retVal != TPM_RC_SUCCESS)
goto exit;
}
if (!found) {
@ -552,84 +579,102 @@ RuntimeAlgorithmKeySizeCheckEnabled(struct RuntimeAlgorithm *RuntimeAlgorithm,
}
static char *
RuntimeAlgorithmGetEcc(struct RuntimeAlgorithm *RuntimeAlgorithm,
enum RuntimeAlgorithmType rat,
char *buffer,
BOOL *first)
RuntimeAlgorithmGet(
const struct AlgorithmShortcuts *shortcuts, size_t shortcuts_len,
const struct AlgorithmProperties *algProps, size_t algProps_len,
unsigned char *enabledShortcuts, size_t enabledShortcuts_len,
unsigned char *enabledAlgorithms, size_t enabledAlgorithms_len,
enum RuntimeAlgorithmType rat,
char *buffer,
BOOL *first)
{
TPM_ECC_CURVE curveId;
char *nbuffer = NULL;
size_t idx;
int n;
for (idx = 0; idx < ARRAY_SIZE(s_EccShortcuts); idx++) {
switch (rat) {
case RUNTIME_ALGO_IMPLEMENTED:
// no filter;
break;
case RUNTIME_ALGO_CAN_BE_DISABLED:
if (!s_EccShortcuts[idx].canBeDisabled)
continue;
break;
case RUNTIME_ALGO_ENABLED:
if (!TEST_BIT(idx, RuntimeAlgorithm->enabledEccShortcuts))
continue;
break;
case RUNTIME_ALGO_DISABLED:
if (TEST_BIT(idx, RuntimeAlgorithm->enabledEccShortcuts))
continue;
break;
default:
break;
}
n = asprintf(&nbuffer, "%s%s%s",
buffer,
*first ? "" : ALGO_SEPARATOR_STR,
s_EccShortcuts[idx].name);
free(buffer);
if (n < 0)
return NULL;
buffer = nbuffer;
*first = false;
for (idx = 0; idx < shortcuts_len; idx++) {
switch (rat) {
case RUNTIME_ALGO_IMPLEMENTED:
// no filter;
break;
case RUNTIME_ALGO_CAN_BE_DISABLED:
if (!shortcuts[idx].canBeDisabled)
continue;
break;
case RUNTIME_ALGO_ENABLED:
if (!TestBit(idx, enabledShortcuts, enabledShortcuts_len))
continue;
break;
case RUNTIME_ALGO_DISABLED:
if (TestBit(idx, enabledShortcuts, enabledShortcuts_len))
continue;
break;
default:
break;
}
n = asprintf(&nbuffer, "%s%s%s",
buffer,
*first ? "" : ALGO_SEPARATOR_STR,
shortcuts[idx].name);
free(buffer);
if (n < 0)
return NULL;
buffer = nbuffer;
*first = false;
}
for (curveId = 0; curveId < ARRAY_SIZE(s_EccAlgorithmProperties); curveId++) {
if (!s_EccAlgorithmProperties[curveId].name)
continue;
for (idx = 0; idx < algProps_len; idx++) {
if (!algProps[idx].name)
continue;
switch (rat) {
case RUNTIME_ALGO_IMPLEMENTED:
// no filter
break;
case RUNTIME_ALGO_CAN_BE_DISABLED:
if (!s_EccAlgorithmProperties[curveId].canBeDisabled)
continue;
break;
case RUNTIME_ALGO_ENABLED:
if (!TEST_BIT(curveId, RuntimeAlgorithm->enabledEccCurves))
continue;
break;
case RUNTIME_ALGO_DISABLED:
if (TEST_BIT(curveId, RuntimeAlgorithm->enabledEccCurves))
continue;
break;
default:
break;
}
n = asprintf(&nbuffer, "%s%s%s",
buffer,
*first ? "" : ALGO_SEPARATOR_STR,
s_EccAlgorithmProperties[curveId].name);
free(buffer);
if (n < 0)
return NULL;
buffer = nbuffer;
*first = FALSE;
switch (rat) {
case RUNTIME_ALGO_IMPLEMENTED:
// no filter
break;
case RUNTIME_ALGO_CAN_BE_DISABLED:
if (!algProps[idx].canBeDisabled)
continue;
break;
case RUNTIME_ALGO_ENABLED:
if (!TestBit(idx, enabledAlgorithms, enabledAlgorithms_len))
continue;
break;
case RUNTIME_ALGO_DISABLED:
if (TestBit(idx, enabledAlgorithms, enabledAlgorithms_len))
continue;
break;
default:
break;
}
n = asprintf(&nbuffer, "%s%s%s",
buffer,
*first ? "" : ALGO_SEPARATOR_STR,
algProps[idx].name);
free(buffer);
if (n < 0)
return NULL;
buffer = nbuffer;
*first = FALSE;
}
return buffer;
}
static char *
RuntimeAlgorithmGetEcc(struct RuntimeAlgorithm *RuntimeAlgorithm,
enum RuntimeAlgorithmType rat,
char *buffer,
BOOL *first)
{
return RuntimeAlgorithmGet(
s_EccShortcuts, ARRAY_SIZE(s_EccShortcuts),
s_EccAlgorithmProperties, ARRAY_SIZE(s_EccAlgorithmProperties),
RuntimeAlgorithm->enabledEccShortcuts, sizeof(RuntimeAlgorithm->enabledEccShortcuts),
RuntimeAlgorithm->enabledEccCurves, sizeof(RuntimeAlgorithm->enabledEccCurves),
rat, buffer, first
);
}
LIB_EXPORT char *
RuntimeAlgorithmPrint(struct RuntimeAlgorithm *RuntimeAlgorithm,
enum RuntimeAlgorithmType rat)