pk11_eddsa_unittest.cc (5850B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #include <memory> 6 #include "nss.h" 7 #include "pk11pub.h" 8 #include "sechash.h" 9 #include "cryptohi.h" 10 11 #include "cpputil.h" 12 #include "json_reader.h" 13 #include "nss_scoped_ptrs.h" 14 #include "testvectors_base/test-structs.h" 15 16 #include "pk11_eddsa_vectors.h" 17 #include "pk11_signature_test.h" 18 #include "pk11_keygen.h" 19 20 namespace nss_test { 21 static const Pkcs11SignatureTestParams kEddsaVectors[] = { 22 {DataBuffer(kEd25519Pkcs8_1, sizeof(kEd25519Pkcs8_1)), 23 DataBuffer(kEd25519Spki_1, sizeof(kEd25519Spki_1)), 24 DataBuffer(kEd25519Message_1, sizeof(kEd25519Message_1)), 25 DataBuffer(kEd25519Signature_1, sizeof(kEd25519Signature_1))}, 26 27 {DataBuffer(kEd25519Pkcs8_2, sizeof(kEd25519Pkcs8_2)), 28 DataBuffer(kEd25519Spki_2, sizeof(kEd25519Spki_2)), 29 DataBuffer(kEd25519Message_2, sizeof(kEd25519Message_2)), 30 DataBuffer(kEd25519Signature_2, sizeof(kEd25519Signature_2))}, 31 32 {DataBuffer(kEd25519Pkcs8_3, sizeof(kEd25519Pkcs8_3)), 33 DataBuffer(kEd25519Spki_3, sizeof(kEd25519Spki_3)), 34 DataBuffer(kEd25519Message_3, sizeof(kEd25519Message_3)), 35 DataBuffer(kEd25519Signature_3, sizeof(kEd25519Signature_3))}}; 36 37 class Pkcs11EddsaTest 38 : public Pk11SignatureTest, 39 public ::testing::WithParamInterface<Pkcs11SignatureTestParams> { 40 protected: 41 Pkcs11EddsaTest() : Pk11SignatureTest(CKM_EDDSA) {} 42 }; 43 44 TEST_P(Pkcs11EddsaTest, SignAndVerify) { SignAndVerifyRaw(GetParam()); } 45 46 TEST_P(Pkcs11EddsaTest, ImportExport) { ImportExport(GetParam().pkcs8_); } 47 48 TEST_P(Pkcs11EddsaTest, ImportConvertToPublic) { 49 ScopedSECKEYPrivateKey privKey(ImportPrivateKey(GetParam().pkcs8_)); 50 ASSERT_TRUE(privKey); 51 52 ScopedSECKEYPublicKey pubKey(SECKEY_ConvertToPublicKey(privKey.get())); 53 ASSERT_TRUE(pubKey); 54 } 55 56 TEST_P(Pkcs11EddsaTest, ImportPublicCreateSubjectPKInfo) { 57 ScopedSECKEYPrivateKey privKey(ImportPrivateKey(GetParam().pkcs8_)); 58 ASSERT_TRUE(privKey); 59 60 ScopedSECKEYPublicKey pubKey( 61 (SECKEYPublicKey*)SECKEY_ConvertToPublicKey(privKey.get())); 62 ASSERT_TRUE(pubKey); 63 64 ScopedSECItem der_spki(SECKEY_EncodeDERSubjectPublicKeyInfo(pubKey.get())); 65 ASSERT_TRUE(der_spki); 66 ASSERT_EQ(der_spki->len, GetParam().spki_.len()); 67 ASSERT_EQ(0, memcmp(der_spki->data, GetParam().spki_.data(), der_spki->len)); 68 } 69 70 INSTANTIATE_TEST_SUITE_P(EddsaSignVerify, Pkcs11EddsaTest, 71 ::testing::ValuesIn(kEddsaVectors)); 72 73 class Pkcs11EddsaRoundtripTest 74 : public Pk11SignatureTest, 75 public ::testing::WithParamInterface<Pkcs11SignatureTestParams> { 76 protected: 77 Pkcs11EddsaRoundtripTest() : Pk11SignatureTest(CKM_EDDSA) {} 78 79 protected: 80 void GenerateExportImportSignVerify(Pkcs11SignatureTestParams params) { 81 Pkcs11KeyPairGenerator generator(CKM_EC_EDWARDS_KEY_PAIR_GEN); 82 ScopedSECKEYPrivateKey priv; 83 ScopedSECKEYPublicKey pub; 84 generator.GenerateKey(&priv, &pub, false); 85 86 DataBuffer exported; 87 ExportPrivateKey(&priv, exported); 88 89 ScopedSECKEYPrivateKey privKey(ImportPrivateKey(exported)); 90 ASSERT_NE(privKey, nullptr); 91 DataBuffer sig; 92 93 SignRaw(privKey, params.data_, &sig); 94 Verify(pub, params.data_, sig); 95 } 96 }; 97 98 TEST_P(Pkcs11EddsaRoundtripTest, GenerateExportImportSignVerify) { 99 GenerateExportImportSignVerify(GetParam()); 100 } 101 102 INSTANTIATE_TEST_SUITE_P(EddsaRound, Pkcs11EddsaRoundtripTest, 103 ::testing::ValuesIn(kEddsaVectors)); 104 105 class Pkcs11EddsaWycheproofTest : public ::testing::Test { 106 protected: 107 void Run(const std::string& name) { 108 WycheproofHeader(name, "EDDSA", "eddsa_verify_schema.json", 109 [this](JsonReader& r) { RunGroup(r); }); 110 } 111 112 private: 113 void RunGroup(JsonReader& r) { 114 std::vector<EddsaTestVector> tests; 115 std::vector<uint8_t> public_key; 116 117 while (r.NextItem()) { 118 std::string n = r.ReadLabel(); 119 if (n == "") { 120 break; 121 } 122 123 if (n == "jwk" || n == "key" || n == "keyPem") { 124 r.SkipValue(); 125 } else if (n == "keyDer") { 126 public_key = r.ReadHex(); 127 } else if (n == "type") { 128 ASSERT_EQ("EddsaVerify", r.ReadString()); 129 } else if (n == "tests") { 130 WycheproofReadTests(r, &tests, ReadTestAttr); 131 } else { 132 FAIL() << "unknown label in group: " << n; 133 } 134 } 135 136 for (auto& t : tests) { 137 std::cout << "Running test " << t.id << std::endl; 138 t.public_key = public_key; 139 Derive(t); 140 } 141 } 142 143 static void ReadTestAttr(EddsaTestVector& t, const std::string& n, 144 JsonReader& r) { 145 if (n == "msg") { 146 t.msg = r.ReadHex(); 147 } else if (n == "sig") { 148 t.sig = r.ReadHex(); 149 } else { 150 FAIL() << "unknown test key: " << n; 151 } 152 } 153 154 void Derive(const EddsaTestVector& vec) { 155 SECItem spki_item = {siBuffer, toUcharPtr(vec.public_key.data()), 156 static_cast<unsigned int>(vec.public_key.size())}; 157 SECItem sig_item = {siBuffer, toUcharPtr(vec.sig.data()), 158 static_cast<unsigned int>(vec.sig.size())}; 159 SECItem msg_item = {siBuffer, toUcharPtr(vec.msg.data()), 160 static_cast<unsigned int>(vec.msg.size())}; 161 162 ScopedCERTSubjectPublicKeyInfo cert_spki( 163 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); 164 ASSERT_TRUE(cert_spki); 165 166 ScopedSECKEYPublicKey pub_key(SECKEY_ExtractPublicKey(cert_spki.get())); 167 ASSERT_TRUE(pub_key); 168 169 SECStatus rv = PK11_VerifyWithMechanism(pub_key.get(), CKM_EDDSA, nullptr, 170 &sig_item, &msg_item, nullptr); 171 EXPECT_EQ(rv, vec.valid ? SECSuccess : SECFailure); 172 }; 173 }; 174 175 TEST_F(Pkcs11EddsaWycheproofTest, Ed25519) { Run("eddsa"); } 176 177 } // namespace nss_test