1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include <memory>
8 #include "nss.h"
9 #include "prerror.h"
10 #include "pk11pub.h"
11 #include "sechash.h"
12 #include "cryptohi.h"
13
14 #include "cpputil.h"
15 #include "databuffer.h"
16 #include "pk11_signature_test.h"
17
18 #include "gtest/gtest.h"
19 #include "nss_scoped_ptrs.h"
20
21 #include "testvectors/dsa-vectors.h"
22
23 namespace nss_test {
24 CK_MECHANISM_TYPE
DsaHashToComboMech(SECOidTag hash)25 DsaHashToComboMech(SECOidTag hash) {
26 switch (hash) {
27 case SEC_OID_SHA1:
28 return CKM_DSA_SHA1;
29 case SEC_OID_SHA224:
30 return CKM_DSA_SHA224;
31 case SEC_OID_SHA256:
32 return CKM_DSA_SHA256;
33 case SEC_OID_SHA384:
34 return CKM_DSA_SHA384;
35 case SEC_OID_SHA512:
36 return CKM_DSA_SHA512;
37 default:
38 break;
39 }
40 return CKM_INVALID_MECHANISM;
41 }
42
43 class Pkcs11DsaTestBase : public Pk11SignatureTest {
44 protected:
Pkcs11DsaTestBase(SECOidTag hashOid)45 Pkcs11DsaTestBase(SECOidTag hashOid)
46 : Pk11SignatureTest(CKM_DSA, hashOid, DsaHashToComboMech(hashOid)) {}
47
Verify(const DsaTestVector vec)48 void Verify(const DsaTestVector vec) {
49 /* DSA vectors encode the signature in DER, we need to unwrap it before
50 * we can send the raw signatures to PKCS #11. */
51 DataBuffer pubKeyBuffer(vec.public_key.data(), vec.public_key.size());
52 ScopedSECKEYPublicKey nssPubKey(ImportPublicKey(pubKeyBuffer));
53 SECItem sigItem = {siBuffer, toUcharPtr(vec.sig.data()),
54 static_cast<unsigned int>(vec.sig.size())};
55 ScopedSECItem decodedSigItem(
56 DSAU_DecodeDerSigToLen(&sigItem, SECKEY_SignatureLen(nssPubKey.get())));
57 if (!decodedSigItem) {
58 ASSERT_FALSE(vec.valid) << "Failed to decode DSA signature Error: "
59 << PORT_ErrorToString(PORT_GetError()) << "\n";
60 return;
61 }
62
63 Pkcs11SignatureTestParams params = {
64 DataBuffer(), pubKeyBuffer, DataBuffer(vec.msg.data(), vec.msg.size()),
65 DataBuffer(decodedSigItem.get()->data, decodedSigItem.get()->len)};
66 Pk11SignatureTest::Verify(params, (bool)vec.valid);
67 }
68 };
69
70 class Pkcs11DsaTest : public Pkcs11DsaTestBase,
71 public ::testing::WithParamInterface<DsaTestVector> {
72 public:
Pkcs11DsaTest()73 Pkcs11DsaTest() : Pkcs11DsaTestBase(GetParam().hash_oid) {}
74 };
75
TEST_P(Pkcs11DsaTest,WycheproofVectors)76 TEST_P(Pkcs11DsaTest, WycheproofVectors) { Verify(GetParam()); }
77
78 INSTANTIATE_TEST_SUITE_P(DsaTest, Pkcs11DsaTest,
79 ::testing::ValuesIn(kDsaWycheproofVectors));
80
81 } // namespace nss_test
82