tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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