Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Bug 1649226 - Add Wycheproof ECDSA tests. r=bbeurdouche
Differential Revision: https://phabricator.services.mozilla.com/D81589

--HG--
extra : moz-landing-system : lando
  • Loading branch information
Kevin Jacobs committed Jun 29, 2020
1 parent 7727d38 commit 470a4fa
Show file tree
Hide file tree
Showing 6 changed files with 32,377 additions and 0 deletions.
7,948 changes: 7,948 additions & 0 deletions gtests/common/testvectors/p256ecdsa-sha256-vectors.h

Large diffs are not rendered by default.

10,173 changes: 10,173 additions & 0 deletions gtests/common/testvectors/p384ecdsa-sha384-vectors.h

Large diffs are not rendered by default.

14,146 changes: 14,146 additions & 0 deletions gtests/common/testvectors/p521ecdsa-sha512-vectors.h

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions gtests/common/testvectors_base/test-structs.h
Expand Up @@ -57,6 +57,15 @@ typedef struct ChaChaTestVectorStr {
bool invalid_iv;
} ChaChaTestVector;

typedef struct EcdsaTestVectorStr {
SECOidTag hash_oid;
uint32_t id;
std::vector<uint8_t> sig;
std::vector<uint8_t> public_key;
std::vector<uint8_t> msg;
bool valid;
} EcdsaTestVector;

typedef struct EcdhTestVectorStr {
uint32_t id;
std::vector<uint8_t> private_key;
Expand Down
53 changes: 53 additions & 0 deletions gtests/common/wycheproof/genTestVectors.py
Expand Up @@ -158,6 +158,23 @@ def format_testcase(self, testcase, curve):

return result

class ECDSA():
"""Class that provides the generator function for a single ECDSA test case."""

def format_testcase(self, testcase, key, hash_oid, keySize):
result = '\n// Comment: {}'.format(testcase['comment'])
result += '\n// tcID: {}\n'.format(testcase['tcId'])
result += '{{{}, {},\n'.format(hash_oid, testcase['tcId'])
result += '{},\n'.format(string_to_hex_array(testcase['sig']))
result += '{},\n'.format(string_to_hex_array(key))
result += '{},\n'.format(string_to_hex_array(testcase['msg']))
valid = testcase['result'] == 'valid'
if not valid and testcase['result'] == 'acceptable':
valid = 'MissingZero' in testcase['flags']
result += '{}}},\n'.format(str(valid).lower())

return result

class RSA_PKCS1_SIGNATURE():
pub_keys = {}

Expand Down Expand Up @@ -464,6 +481,39 @@ def generate_vectors_file(params):
'comment' : ''
}

p256ecdsa_sha256_params = {
'source_dir': 'source_vectors/',
'source_file': 'ecdsa_secp256r1_sha256_test.json',
'target': '../testvectors/p256ecdsa-sha256-vectors.h',
'array_init': 'const EcdsaTestVector kP256EcdsaSha256Vectors[] = {\n',
'formatter' : ECDSA(),
'crop_size_end': -2,
'section': 'p256ecdsa_sha256_vectors_h__',
'comment' : ''
}

p384ecdsa_sha384_params = {
'source_dir': 'source_vectors/',
'source_file': 'ecdsa_secp384r1_sha384_test.json',
'target': '../testvectors/p384ecdsa-sha384-vectors.h',
'array_init': 'const EcdsaTestVector kP384EcdsaSha384Vectors[] = {\n',
'formatter' : ECDSA(),
'crop_size_end': -2,
'section': 'p384ecdsa_sha384_vectors_h__',
'comment' : ''
}

p521ecdsa_sha512_params = {
'source_dir': 'source_vectors/',
'source_file': 'ecdsa_secp521r1_sha512_test.json',
'target': '../testvectors/p521ecdsa-sha512-vectors.h',
'array_init': 'const EcdsaTestVector kP521EcdsaSha512Vectors[] = {\n',
'formatter' : ECDSA(),
'crop_size_end': -2,
'section': 'p521ecdsa_sha512_vectors_h__',
'comment' : ''
}

rsa_signature_2048_sha224_params = {
'source_dir': 'source_vectors/',
'source_file': 'rsa_signature_2048_sha224_test.json',
Expand Down Expand Up @@ -780,6 +830,9 @@ def generate_test_vectors():
aes_gcm_params,
chacha_poly_params,
curve25519_params,
p256ecdsa_sha256_params,
p384ecdsa_sha384_params,
p521ecdsa_sha512_params,
p256ecdh_params,
p384ecdh_params,
p521ecdh_params,
Expand Down
48 changes: 48 additions & 0 deletions gtests/pk11_gtest/pk11_ecdsa_unittest.cc
Expand Up @@ -6,12 +6,16 @@
#include "nss.h"
#include "pk11pub.h"
#include "sechash.h"
#include "cryptohi.h"

#include "gtest/gtest.h"
#include "nss_scoped_ptrs.h"

#include "pk11_ecdsa_vectors.h"
#include "pk11_signature_test.h"
#include "testvectors/p256ecdsa-sha256-vectors.h"
#include "testvectors/p384ecdsa-sha384-vectors.h"
#include "testvectors/p521ecdsa-sha512-vectors.h"

namespace nss_test {

Expand Down Expand Up @@ -172,4 +176,48 @@ TEST_F(Pkcs11EcdsaSha256Test, ImportSpkiPointNotOnCurve) {
EXPECT_EQ(handle, static_cast<decltype(handle)>(CK_INVALID_HANDLE));
}

class Pkcs11EcdsaWycheproofTest
: public ::testing::TestWithParam<EcdsaTestVector> {
protected:
void Derive(const EcdsaTestVector vec) {
SECItem spki_item = {siBuffer, toUcharPtr(vec.public_key.data()),
static_cast<unsigned int>(vec.public_key.size())};
SECItem sig_item = {siBuffer, toUcharPtr(vec.sig.data()),
static_cast<unsigned int>(vec.sig.size())};

DataBuffer hash;
hash.Allocate(static_cast<size_t>(HASH_ResultLenByOidTag(vec.hash_oid)));
SECStatus rv = PK11_HashBuf(vec.hash_oid, toUcharPtr(hash.data()),
toUcharPtr(vec.msg.data()), vec.msg.size());
ASSERT_EQ(rv, SECSuccess);
SECItem hash_item = {siBuffer, toUcharPtr(hash.data()),
static_cast<unsigned int>(hash.len())};

ScopedCERTSubjectPublicKeyInfo cert_spki(
SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item));
ASSERT_TRUE(cert_spki);
ScopedSECKEYPublicKey pub_key(SECKEY_ExtractPublicKey(cert_spki.get()));
ASSERT_TRUE(pub_key);

rv = VFY_VerifyDigestDirect(&hash_item, pub_key.get(), &sig_item,
SEC_OID_ANSIX962_EC_PUBLIC_KEY, vec.hash_oid,
nullptr);
EXPECT_EQ(rv, vec.valid ? SECSuccess : SECFailure);
};
};

TEST_P(Pkcs11EcdsaWycheproofTest, Verify) { Derive(GetParam()); }

INSTANTIATE_TEST_CASE_P(WycheproofP256SignatureSha256Test,
Pkcs11EcdsaWycheproofTest,
::testing::ValuesIn(kP256EcdsaSha256Vectors));

INSTANTIATE_TEST_CASE_P(WycheproofP384SignatureSha384Test,
Pkcs11EcdsaWycheproofTest,
::testing::ValuesIn(kP384EcdsaSha384Vectors));

INSTANTIATE_TEST_CASE_P(WycheproofP521SignatureSha512Test,
Pkcs11EcdsaWycheproofTest,
::testing::ValuesIn(kP521EcdsaSha512Vectors));

} // namespace nss_test

0 comments on commit 470a4fa

Please sign in to comment.