Skip to content
Open
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
6 changes: 6 additions & 0 deletions .github/configs/os-check-linux.json
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,12 @@
"configure": ["--enable-cryptonly", "--disable-dh", "--enable-eccsi",
"--enable-sakke", "--enable-rsavfy", "--enable-sp-math", "--enable-sp",
"--disable-examples"]},
{"name": "eccsi-sp-no-p256",
"comment": "ECCSI on SP-ECC without SP P-256.",
"configure": ["--enable-eccsi", "--enable-sp=ec384", "--enable-ecccustcurves=all"]},
{"name": "eccsi-sp-custcurves",
"comment": "ECCSI on SP P-256 with the custom curves.",
"configure": ["--enable-eccsi", "--enable-sp", "--enable-ecccustcurves=all"]},
{"name": "cryptonly-no-asn-rsa", "minutes": 0.2, "check": false,
"comment": "RSA with ASN.1 disabled. Build only, since wolfcrypt test and benchmark do not support this combination.",
"configure": ["--enable-cryptonly", "--disable-asn", "--enable-lowresource",
Expand Down
173 changes: 168 additions & 5 deletions tests/api/test_eccsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,11 +485,7 @@ int test_wc_Eccsi_DecisionCoverage(void)
#endif

/* --- wc_ValidateEccsiPvt() (CLIENT) ---
* eccsi.c ~line 1579: (key==NULL) | (pvt==NULL) || (valid==NULL)
* (first two operands are combined with a bitwise '|', not '&&'/'||',
* so both are always evaluated; MC/DC's baseline+single-flip pattern
* still applies since the result is the same 0/1 boolean algebra.)
*/
* eccsi.c: (key==NULL) || (pvt==NULL) || (valid==NULL) */
ExpectIntEQ(wc_ValidateEccsiPvt(NULL, pvt, &valid),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_ValidateEccsiPvt(&keyPub, NULL, &valid),
Expand Down Expand Up @@ -860,3 +856,170 @@ int test_wc_Eccsi_FeatureCoverage(void)
#endif
return EXPECT_RESULT();
}

/* Reuse one KMS key object across key generations and signatures. */
int test_wc_Eccsi_KeyReuse(void)
{
EXPECT_DECLS;
#ifdef WOLFCRYPT_HAVE_ECCSI
EccsiKey key;
WC_RNG rng;
mp_int ssk;
ecc_point* pvt = NULL;
ecc_point* badPvt = NULL;
char mail[] = "test@wolfssl.com";
byte* id = (byte*)mail;
word32 idSz;
int valid;
int verified;
int round;
byte hash[WC_MAX_DIGEST_SIZE];
byte hashSz = 0;
byte sig[32 * 4 + 1];
word32 sigSz;
byte msg[1] = { 0x00 };

XMEMSET(&key, 0, sizeof(key));
XMEMSET(&rng, 0, sizeof(rng));
XMEMSET(&ssk, 0, sizeof(ssk));
idSz = (word32)XSTRLEN(mail);

ExpectIntEQ(wc_InitRng(&rng), 0);
ExpectNotNull(pvt = wc_ecc_new_point());
ExpectNotNull(badPvt = wc_ecc_new_point());
ExpectIntEQ(mp_init(&ssk), MP_OKAY);
ExpectIntEQ(wc_InitEccsiKey(&key, HEAP_HINT, INVALID_DEVID), 0);

/* The second round regenerates the KPAK after a verify used it. */
for (round = 0; round < 2; round++) {
verified = 0;
ExpectIntEQ(wc_MakeEccsiKey(&key, &rng), 0);
if (round > 0) {
/* The identity hash set in the first round is for the old KPAK. */
sigSz = sizeof(sig);
ExpectIntEQ(wc_SignEccsiHash(&key, &rng, WC_HASH_TYPE_SHA256, msg,
(word32)sizeof(msg), sig, &sigSz),
WC_NO_ERR_TRACE(BAD_STATE_E));
}
ExpectIntEQ(wc_MakeEccsiPair(&key, &rng, WC_HASH_TYPE_SHA256, id,
idSz, &ssk, pvt), 0);
valid = 0;
ExpectIntEQ(wc_ValidateEccsiPvt(&key, pvt, &valid), 0);
Comment thread
Frauschi marked this conversation as resolved.
Resolved
ExpectIntEQ(valid, 1);
ExpectIntEQ(wc_HashEccsiId(&key, WC_HASH_TYPE_SHA256, id, idSz, pvt,
hash, &hashSz), 0);
ExpectIntEQ(wc_SetEccsiHash(&key, hash, hashSz), 0);
ExpectIntEQ(wc_SetEccsiPair(&key, &ssk, pvt), 0);
sigSz = sizeof(sig);
ExpectIntEQ(wc_SignEccsiHash(&key, &rng, WC_HASH_TYPE_SHA256, msg,
(word32)sizeof(msg), sig, &sigSz), 0);
valid = 0;
ExpectIntEQ(wc_ValidateEccsiPvt(&key, pvt, &valid), 0);
ExpectIntEQ(valid, 1);
ExpectIntEQ(wc_VerifyEccsiHash(&key, WC_HASH_TYPE_SHA256, msg,
(word32)sizeof(msg), sig, sigSz, &verified), 0);
ExpectIntEQ(verified, 1);
valid = 0;
ExpectIntEQ(wc_ValidateEccsiPvt(&key, pvt, &valid), 0);
ExpectIntEQ(valid, 1);
}

/* A PVT off the curve or at infinity is rejected. */
ExpectIntEQ(wc_ecc_copy_point(pvt, badPvt), 0);
ExpectIntEQ(mp_add_d(badPvt->y, 1, badPvt->y), MP_OKAY);
valid = 1;
ExpectIntEQ(wc_ValidateEccsiPvt(&key, badPvt, &valid), 0);
ExpectIntEQ(valid, 0);
ExpectIntEQ(mp_set(badPvt->x, 0), MP_OKAY);
ExpectIntEQ(mp_set(badPvt->y, 0), MP_OKAY);
valid = 1;
ExpectIntEQ(wc_ValidateEccsiPvt(&key, badPvt, &valid), 0);
ExpectIntEQ(valid, 0);

if (badPvt != NULL) {
wc_ecc_del_point(badPvt);
}
if (pvt != NULL) {
wc_ecc_del_point(pvt);
}
mp_free(&ssk);
wc_FreeRng(&rng);
wc_FreeEccsiKey(&key);
#endif
return EXPECT_RESULT();
}

/* Sign and verify on each 256-bit curve compiled in. */
int test_wc_Eccsi_Curves(void)
{
EXPECT_DECLS;
#ifdef WOLFCRYPT_HAVE_ECCSI
static const int curves[] = {
ECC_SECP256R1,
#ifdef HAVE_ECC_BRAINPOOL
ECC_BRAINPOOLP256R1,
#endif
#ifdef HAVE_ECC_KOBLITZ
ECC_SECP256K1,
#endif
};
EccsiKey key;
WC_RNG rng;
mp_int ssk;
ecc_point* pvt = NULL;
char mail[] = "test@wolfssl.com";
byte* id = (byte*)mail;
word32 idSz;
int valid;
int verified;
int i;
byte hash[WC_MAX_DIGEST_SIZE];
byte hashSz = 0;
byte sig[32 * 4 + 1];
word32 sigSz;
byte msg[1] = { 0x00 };

XMEMSET(&rng, 0, sizeof(rng));
XMEMSET(&ssk, 0, sizeof(ssk));
idSz = (word32)XSTRLEN(mail);

ExpectIntEQ(wc_InitRng(&rng), 0);
ExpectNotNull(pvt = wc_ecc_new_point());
ExpectIntEQ(mp_init(&ssk), MP_OKAY);

for (i = 0; i < (int)(sizeof(curves) / sizeof(curves[0])); i++) {
verified = 0;
XMEMSET(&key, 0, sizeof(key));
ExpectIntEQ(wc_InitEccsiKey_ex(&key, 32, curves[i], HEAP_HINT,
INVALID_DEVID), 0);
ExpectIntEQ(wc_MakeEccsiKey(&key, &rng), 0);
ExpectIntEQ(wc_MakeEccsiPair(&key, &rng, WC_HASH_TYPE_SHA256, id,
idSz, &ssk, pvt), 0);
valid = 0;
ExpectIntEQ(wc_ValidateEccsiPair(&key, WC_HASH_TYPE_SHA256, id, idSz,
&ssk, pvt, &valid), 0);
ExpectIntEQ(valid, 1);
valid = 0;
ExpectIntEQ(wc_ValidateEccsiPvt(&key, pvt, &valid), 0);
ExpectIntEQ(valid, 1);
ExpectIntEQ(wc_HashEccsiId(&key, WC_HASH_TYPE_SHA256, id, idSz, pvt,
hash, &hashSz), 0);
ExpectIntEQ(wc_SetEccsiHash(&key, hash, hashSz), 0);
ExpectIntEQ(wc_SetEccsiPair(&key, &ssk, pvt), 0);
sigSz = sizeof(sig);
ExpectIntEQ(wc_SignEccsiHash(&key, &rng, WC_HASH_TYPE_SHA256, msg,
(word32)sizeof(msg), sig, &sigSz), 0);
ExpectIntEQ(wc_VerifyEccsiHash(&key, WC_HASH_TYPE_SHA256, msg,
(word32)sizeof(msg), sig, sigSz, &verified), 0);
ExpectIntEQ(verified, 1);
wc_FreeEccsiKey(&key);
}

if (pvt != NULL) {
wc_ecc_del_point(pvt);
}
mp_free(&ssk);
wc_FreeRng(&rng);
#endif
return EXPECT_RESULT();
}
6 changes: 5 additions & 1 deletion tests/api/test_eccsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@

int test_wc_Eccsi_DecisionCoverage(void);
int test_wc_Eccsi_FeatureCoverage(void);
int test_wc_Eccsi_KeyReuse(void);
int test_wc_Eccsi_Curves(void);

#define TEST_ECCSI_DECLS \
TEST_DECL_GROUP("eccsi", test_wc_Eccsi_DecisionCoverage), \
TEST_DECL_GROUP("eccsi", test_wc_Eccsi_FeatureCoverage)
TEST_DECL_GROUP("eccsi", test_wc_Eccsi_FeatureCoverage), \
TEST_DECL_GROUP("eccsi", test_wc_Eccsi_KeyReuse), \
TEST_DECL_GROUP("eccsi", test_wc_Eccsi_Curves)

#endif /* WOLFCRYPT_TEST_ECCSI_H */
Loading
Loading