Skip to content
Merged
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
4 changes: 2 additions & 2 deletions src/pk/ecc/ecc_verify_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ int ecc_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
}
else if (sigformat == LTC_ECCSIG_RFC7518) {
/* RFC7518 format - raw (r,s) */
i = mp_unsigned_bin_size(key->dp.order);
if (siglen != (2*i)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also preferred this version of the check TBH

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm not convinced that {0x05, 0x01} should be a valid signature blob for ECDSA, let alone that it should be in a security/proofing library.

Copy link
Member

@sjaeckel sjaeckel Oct 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also don't like that it could be a valid signature, but it's a valid edge-case... :/

... and history has proven that there are always implementations who do worse than your implementation so this (0x000..05...) is a good another example of Postel's Law IMO :)

if ((siglen % 2) == 1) {
err = CRYPT_INVALID_PACKET;
goto error;
}
i = siglen / 2;
if ((err = mp_read_unsigned_bin(r, (unsigned char *)sig, i)) != CRYPT_OK) { goto error; }
if ((err = mp_read_unsigned_bin(s, (unsigned char *)sig+i, i)) != CRYPT_OK) { goto error; }
}
Expand Down
53 changes: 53 additions & 0 deletions tests/ecc_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ static int _ecc_test_shamir(void)
}
#endif

/* https://github.com/libtom/libtomcrypt/issues/108 */
static int _ecc_issue108(void)
{
void *a, *modulus, *order;
Expand Down Expand Up @@ -151,6 +152,57 @@ static int _ecc_issue108(void)
return err;
}

/* https://github.com/libtom/libtomcrypt/issues/443 */
static int _ecc_issue443(void)
{
const ltc_ecc_curve* cu;
ecc_key key;
int stat = 0;
unsigned char hash[64];
unsigned long hashlen;
const unsigned char msg[] = { 0x54,0x65,0x73,0x74 };
/* msg+pub1+sig1 test vector is from wycheproof - ecdsa_webcrypto_test (incorrect size of signature) */
const unsigned char pub1[] = {
0x04,
0x4a,0x03,0xef,0x9f,0x92,0xeb,0x26,0x8c,0xaf,0xa6,0x01,0x07,0x24,0x89,0xa5,0x63,
0x80,0xfa,0x0d,0xc4,0x31,0x71,0xd7,0x71,0x28,0x13,0xb3,0xa1,0x9a,0x1e,0xb5,0xe5,
0x3e,0x21,0x3e,0x28,0xa6,0x08,0xce,0x9a,0x2f,0x4a,0x17,0xfd,0x83,0x0c,0x66,0x54,
0x01,0x8a,0x79,0xb3,0xe0,0x26,0x3d,0x91,0xa8,0xba,0x90,0x62,0x2d,0xf6,0xf2,0xf0
};
const unsigned char sig1[] = { 0x05, 0x01 };
/* msg+pub2+sig2 test vector is from wycheproof - ecdsa_webcrypto_test (incorrect size of signature) */
const unsigned char pub2[] = {
0x04,
0x00,0x5f,0x50,0x59,0x30,0x83,0x49,0xf9,0xeb,0xbb,0x4d,0x1c,0x55,0xc0,0xaf,0xcc,0xf6,0x21,0x62,0xec,0x1d,0xd1,
0x2e,0xf3,0xed,0x90,0x66,0x56,0x92,0x4f,0xfd,0x99,0xca,0xb9,0xf0,0x6b,0x0e,0xb2,0x18,0xcf,0xf0,0x78,0xa4,0x67,
0x7a,0x5c,0xe1,0xcc,0x07,0x65,0x2b,0xc9,0x76,0xae,0xfc,0x73,0x2c,0x28,0xf6,0x7e,0xf0,0x78,0xa4,0x34,0xe9,0x99,
0x00,0xa5,0xd1,0x4d,0xf3,0x10,0x63,0x0d,0x76,0xec,0x03,0xcb,0x6f,0x9b,0x95,0xbf,0x1a,0x22,0x43,0x81,0x05,0xc8,
0x8c,0xd9,0xfd,0x3d,0xac,0x80,0xf8,0x57,0xad,0xd3,0x82,0x71,0xd8,0xba,0x90,0x16,0x84,0xb2,0x6d,0x43,0x6d,0x4a,
0x85,0x9a,0xd4,0xcd,0xa5,0xe9,0x67,0x7b,0x73,0xca,0xb3,0xf3,0xe5,0xe4,0x1a,0x3d,0x79,0x96,0x60,0x72,0x79,0xab
};
const unsigned char sig2[] = { 0x01, 0x01 };

hashlen = sizeof(hash);
DO(hash_memory(find_hash("sha256"), msg, sizeof(msg), hash, &hashlen));
DO(ecc_find_curve("secp256r1", &cu));
DO(ecc_set_curve(cu, &key));
DO(ecc_set_key(pub1, sizeof(pub1), PK_PUBLIC, &key));
DO(ecc_verify_hash_rfc7518(sig1, sizeof(sig1), hash, hashlen, &stat, &key));
ecc_free(&key);
if (stat != 1) return CRYPT_FAIL_TESTVECTOR;

hashlen = sizeof(hash);
DO(hash_memory(find_hash("sha512"), msg, sizeof(msg), hash, &hashlen));
DO(ecc_find_curve("secp521r1", &cu));
DO(ecc_set_curve(cu, &key));
DO(ecc_set_key(pub2, sizeof(pub2), PK_PUBLIC, &key));
DO(ecc_verify_hash_rfc7518(sig2, sizeof(sig2), hash, hashlen, &stat, &key));
ecc_free(&key);
if (stat != 1) return CRYPT_FAIL_TESTVECTOR;

return CRYPT_OK;
}

static int _ecc_test_mp(void)
{
void *a, *modulus, *order;
Expand Down Expand Up @@ -1113,6 +1165,7 @@ int ecc_tests(void)
DO(_ecc_import_export());
DO(_ecc_test_mp());
DO(_ecc_issue108());
DO(_ecc_issue443());
#ifdef LTC_ECC_SHAMIR
DO(_ecc_test_shamir());
DO(_ecc_test_recovery());
Expand Down