Skip to content
Draft
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
157 changes: 157 additions & 0 deletions tests/api/test_ed25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -725,3 +725,160 @@ int test_wc_Ed25519KeyToDer_oneasymkey_version(void)
return EXPECT_RESULT();
}

/*
* Test wc_ed25519_verify_msg() in non-blocking mode.
* Uses RFC 8032 test vectors 1-3 (1-, 1-, and 2-byte messages).
* Each verify is driven in a do/while loop until it returns 0 (done)
* or a real error, mirroring how an embedded application would yield
* between steps. A corrupted signature is also checked for rejection.
*/
int test_wc_ed25519_verify_msg_nonblock(void)
{
EXPECT_DECLS;
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_VERIFY) && \
defined(WC_ED25519_NONBLOCK)
/* RFC 8032 test vectors 1-3 */
static const byte pKey1[] = {
0xd7,0x5a,0x98,0x01,0x82,0xb1,0x0a,0xb7,
0xd5,0x4b,0xfe,0xd3,0xc9,0x64,0x07,0x3a,
0x0e,0xe1,0x72,0xf3,0xda,0xa6,0x23,0x25,
0xaf,0x02,0x1a,0x68,0xf7,0x07,0x51,0x1a
};
static const byte pKey2[] = {
0x3d,0x40,0x17,0xc3,0xe8,0x43,0x89,0x5a,
0x92,0xb7,0x0a,0xa7,0x4d,0x1b,0x7e,0xbc,
0x9c,0x98,0x2c,0xcf,0x2e,0xc4,0x96,0x8c,
0xc0,0xcd,0x55,0xf1,0x2a,0xf4,0x66,0x0c
};
static const byte pKey3[] = {
0xfc,0x51,0xcd,0x8e,0x62,0x18,0xa1,0xa3,
0x8d,0xa4,0x7e,0xd0,0x02,0x30,0xf0,0x58,
0x08,0x16,0xed,0x13,0xba,0x33,0x03,0xac,
0x5d,0xeb,0x91,0x15,0x48,0x90,0x80,0x25
};
static const byte sig1[] = {
0xe5,0x56,0x43,0x00,0xc3,0x60,0xac,0x72,
0x90,0x86,0xe2,0xcc,0x80,0x6e,0x82,0x8a,
0x84,0x87,0x7f,0x1e,0xb8,0xe5,0xd9,0x74,
0xd8,0x73,0xe0,0x65,0x22,0x49,0x01,0x55,
0x5f,0xb8,0x82,0x15,0x90,0xa3,0x3b,0xac,
0xc6,0x1e,0x39,0x70,0x1c,0xf9,0xb4,0x6b,
0xd2,0x5b,0xf5,0xf0,0x59,0x5b,0xbe,0x24,
0x65,0x51,0x41,0x43,0x8e,0x7a,0x10,0x0b
};
static const byte sig2[] = {
0x92,0xa0,0x09,0xa9,0xf0,0xd4,0xca,0xb8,
0x72,0x0e,0x82,0x0b,0x5f,0x64,0x25,0x40,
0xa2,0xb2,0x7b,0x54,0x16,0x50,0x3f,0x8f,
0xb3,0x76,0x22,0x23,0xeb,0xdb,0x69,0xda,
0x08,0x5a,0xc1,0xe4,0x3e,0x15,0x99,0x6e,
0x45,0x8f,0x36,0x13,0xd0,0xf1,0x1d,0x8c,
0x38,0x7b,0x2e,0xae,0xb4,0x30,0x2a,0xee,
0xb0,0x0d,0x29,0x16,0x12,0xbb,0x0c,0x00
};
static const byte sig3[] = {
0x62,0x91,0xd6,0x57,0xde,0xec,0x24,0x02,
0x48,0x27,0xe6,0x9c,0x3a,0xbe,0x01,0xa3,
0x0c,0xe5,0x48,0xa2,0x84,0x74,0x3a,0x44,
0x5e,0x36,0x80,0xd7,0xdb,0x5a,0xc3,0xac,
0x18,0xff,0x9b,0x53,0x8d,0x16,0xf2,0x90,
0xae,0x67,0xf7,0x60,0x98,0x4d,0xc6,0x59,
0x4a,0x7c,0x15,0xe9,0x71,0x6e,0xd2,0x8d,
0xc0,0x27,0xbe,0xce,0xea,0x1e,0xc4,0x0a
};
static const byte msg1[] = { 0x00 }; /* Workaround since C-lang doesn't allow zero length array */
static const byte msg2[] = { 0x72 };
static const byte msg3[] = { 0xAF, 0x82 };

static const byte* pKeys[] = { pKey1, pKey2, pKey3 };
static const byte* sigs[] = { sig1, sig2, sig3 };
static const byte* msgs[] = { msg1, msg2, msg3 };
static const word32 msgSz[] = { 0, sizeof(msg2), sizeof(msg3) };

ed25519_key key;
ed25519_nb_ctx_t nb_ctx;
byte bad_sig[ED25519_SIG_SIZE];
byte bad_msg[2];
int verify;
int ret;
int i;

XMEMSET(&key, 0, sizeof(key));
XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));

ExpectIntEQ(wc_ed25519_init(&key), 0);
ExpectIntEQ(wc_ed25519_set_nonblock(&key, &nb_ctx), 0);

for (i = 0; i < 3; i++) {
ExpectIntEQ(wc_ed25519_import_public(pKeys[i], ED25519_KEY_SIZE, &key),
0);

/* non-blocking verify good signature */
verify = 0;
do {
ret = wc_ed25519_verify_msg(sigs[i], ED25519_SIG_SIZE,
msgs[i], msgSz[i], &verify, &key);
} while (ret == MP_WOULDBLOCK);
ExpectIntEQ(ret, 0);
ExpectIntEQ(verify, 1);

/* verify corrupted last byte of signature - must fail */
XMEMCPY(bad_sig, sigs[i], ED25519_SIG_SIZE);
bad_sig[ED25519_SIG_SIZE - 1] = bad_sig[ED25519_SIG_SIZE - 1] + 1;
verify = 0;
do {
ret = wc_ed25519_verify_msg(bad_sig, ED25519_SIG_SIZE,
msgs[i], msgSz[i], &verify, &key);
} while (ret == MP_WOULDBLOCK);
ExpectIntNE(ret, 0);
ExpectIntEQ(verify, 0);

/* verify corrupted first byte of signature - must fail */
XMEMCPY(bad_sig, sigs[i], ED25519_SIG_SIZE);
bad_sig[0] = bad_sig[0] + 1;
verify = 0;
do {
ret = wc_ed25519_verify_msg(bad_sig, ED25519_SIG_SIZE,
msgs[i], msgSz[i], &verify, &key);
} while (ret == MP_WOULDBLOCK);
ExpectIntNE(ret, 0);
ExpectIntEQ(verify, 0);
}

/* tampered message with valid signature must fail (pKey3/sig3 still loaded) */
XMEMCPY(bad_msg, msg3, sizeof(msg3));
bad_msg[0] ^= 0x01;
verify = 0;
do {
ret = wc_ed25519_verify_msg(sig3, ED25519_SIG_SIZE,
bad_msg, sizeof(msg3), &verify, &key);
} while (ret == MP_WOULDBLOCK);
ExpectIntNE(ret, 0);
ExpectIntEQ(verify, 0);

/* bad args */
ExpectIntEQ(wc_ed25519_verify_msg(NULL, ED25519_SIG_SIZE,
msg3, sizeof(msg3), &verify, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_ed25519_verify_msg(sig3, ED25519_SIG_SIZE,
NULL, sizeof(msg3), &verify, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_ed25519_verify_msg(sig3, ED25519_SIG_SIZE,
msg3, sizeof(msg3), NULL, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_ed25519_verify_msg(sig3, ED25519_SIG_SIZE,
msg3, sizeof(msg3), &verify, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_ed25519_verify_msg(sig3, ED25519_SIG_SIZE - 1,
msg3, sizeof(msg3), &verify, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_ed25519_verify_msg(sig3, ED25519_SIG_SIZE + 1,
msg3, sizeof(msg3), &verify, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

/* verify falls back to blocking after disabling non-block mode */
wc_ed25519_set_nonblock(&key, NULL);
verify = 0;
ExpectIntEQ(wc_ed25519_verify_msg(sig3, ED25519_SIG_SIZE,
msg3, sizeof(msg3), &verify, &key), 0);
ExpectIntEQ(verify, 1);

wc_ed25519_free(&key);
#endif
return EXPECT_RESULT();
}

30 changes: 16 additions & 14 deletions tests/api/test_ed25519.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,22 @@ int test_wc_Ed25519PublicKeyToDer(void);
int test_wc_Ed25519KeyToDer(void);
int test_wc_Ed25519PrivateKeyToDer(void);
int test_wc_Ed25519KeyToDer_oneasymkey_version(void);
int test_wc_ed25519_verify_msg_nonblock(void);

#define TEST_ED25519_DECLS \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_make_key), \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_init), \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_sign_msg), \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_sign_msg_pubonly_fails), \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_import_public), \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_import_private_key), \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_export), \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_size), \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_exportKey), \
TEST_DECL_GROUP("ed25519", test_wc_Ed25519PublicKeyToDer), \
TEST_DECL_GROUP("ed25519", test_wc_Ed25519KeyToDer), \
TEST_DECL_GROUP("ed25519", test_wc_Ed25519PrivateKeyToDer), \
TEST_DECL_GROUP("ed25519", test_wc_Ed25519KeyToDer_oneasymkey_version)
#define TEST_ED25519_DECLS \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_make_key), \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_init), \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_sign_msg), \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_sign_msg_pubonly_fails), \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_import_public), \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_import_private_key), \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_export), \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_size), \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_exportKey), \
TEST_DECL_GROUP("ed25519", test_wc_Ed25519PublicKeyToDer), \
TEST_DECL_GROUP("ed25519", test_wc_Ed25519KeyToDer), \
TEST_DECL_GROUP("ed25519", test_wc_Ed25519PrivateKeyToDer), \
TEST_DECL_GROUP("ed25519", test_wc_Ed25519KeyToDer_oneasymkey_version), \
TEST_DECL_GROUP("ed25519", test_wc_ed25519_verify_msg_nonblock)

#endif /* WOLFCRYPT_TEST_ED25519_H */
Loading