tor-browser

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

pk11_keygen.cc (5692B)


      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 "kyber.h"
      6 #include "pk11_keygen.h"
      7 
      8 #include "pk11pub.h"
      9 #include "pk11pqg.h"
     10 #include "prerror.h"
     11 
     12 #include "gtest/gtest.h"
     13 
     14 namespace nss_test {
     15 
     16 class ParamHolder {
     17 public:
     18  virtual void* get() = 0;
     19  virtual ~ParamHolder() = default;
     20 
     21 protected:
     22  ParamHolder() = default;
     23 };
     24 
     25 void Pkcs11KeyPairGenerator::GenerateKey(ScopedSECKEYPrivateKey* priv_key,
     26                                         ScopedSECKEYPublicKey* pub_key,
     27                                         bool sensitive) const {
     28  // This function returns if an assertion fails, so don't leak anything.
     29  priv_key->reset(nullptr);
     30  pub_key->reset(nullptr);
     31 
     32  auto params = MakeParams();
     33  ASSERT_NE(nullptr, params);
     34 
     35  ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
     36  ASSERT_TRUE(slot);
     37 
     38  SECKEYPublicKey* pub_tmp = NULL;
     39  ScopedSECKEYPrivateKey priv_tmp(
     40      PK11_GenerateKeyPair(slot.get(), mech_, params->get(), &pub_tmp, PR_FALSE,
     41                           sensitive ? PR_TRUE : PR_FALSE, nullptr));
     42 #ifdef NSS_DISABLE_DSA
     43  if (mech_ == CKM_DSA_KEY_PAIR_GEN) {
     44    ASSERT_EQ(nullptr, priv_tmp);
     45    ASSERT_EQ(nullptr, pub_tmp);
     46    ASSERT_EQ(PORT_GetError(), SEC_ERROR_INVALID_ALGORITHM);
     47    return;
     48  }
     49 #endif
     50  ASSERT_NE(nullptr, priv_tmp)
     51      << "PK11_GenerateKeyPair failed: " << PORT_ErrorToName(PORT_GetError());
     52  ASSERT_NE(nullptr, pub_tmp);
     53 
     54  priv_key->swap(priv_tmp);
     55  pub_key->reset(pub_tmp);
     56 }
     57 
     58 class RsaParamHolder : public ParamHolder {
     59 public:
     60  RsaParamHolder() : params_({1024, 0x010001}) {}
     61  ~RsaParamHolder() = default;
     62 
     63  void* get() override { return &params_; }
     64 
     65 private:
     66  PK11RSAGenParams params_;
     67 };
     68 
     69 class PqgParamHolder : public ParamHolder {
     70 public:
     71  PqgParamHolder(PQGParams* params) : params_(params) {}
     72  ~PqgParamHolder() = default;
     73 
     74  void* get() override { return params_.get(); }
     75 
     76 private:
     77  ScopedPQGParams params_;
     78 };
     79 
     80 class DhParamHolder : public PqgParamHolder {
     81 public:
     82  DhParamHolder(PQGParams* params)
     83      : PqgParamHolder(params),
     84        params_({nullptr, params->prime, params->base}) {}
     85  ~DhParamHolder() = default;
     86 
     87  void* get() override { return &params_; }
     88 
     89 private:
     90  SECKEYDHParams params_;
     91 };
     92 
     93 /* Also used for EdDSA. */
     94 class EcParamHolder : public ParamHolder {
     95 public:
     96  EcParamHolder(SECOidTag curve_oid) {
     97    /* For the case of ED curve_oid contains a EdDSA OID. */
     98    SECOidData* curve = SECOID_FindOIDByTag(curve_oid);
     99    EXPECT_NE(nullptr, curve);
    100 
    101    size_t plen = curve->oid.len + 2;
    102    extra_.reset(new uint8_t[plen]);
    103    extra_[0] = SEC_ASN1_OBJECT_ID;
    104    extra_[1] = static_cast<uint8_t>(curve->oid.len);
    105    memcpy(&extra_[2], curve->oid.data, curve->oid.len);
    106 
    107    ec_params_ = {siBuffer, extra_.get(), static_cast<unsigned int>(plen)};
    108  }
    109  ~EcParamHolder() = default;
    110 
    111  void* get() override { return &ec_params_; }
    112 
    113 private:
    114  SECKEYECParams ec_params_;
    115  std::unique_ptr<uint8_t[]> extra_;
    116 };
    117 
    118 class KyberParamHolder : public ParamHolder {
    119 public:
    120  KyberParamHolder(CK_NSS_KEM_PARAMETER_SET_TYPE aParams) : mParams(aParams) {}
    121  void* get() override { return &mParams; }
    122 
    123 private:
    124  CK_NSS_KEM_PARAMETER_SET_TYPE mParams;
    125 };
    126 
    127 std::unique_ptr<ParamHolder> Pkcs11KeyPairGenerator::MakeParams() const {
    128  switch (mech_) {
    129    case CKM_RSA_PKCS_KEY_PAIR_GEN:
    130      std::cerr << "Generate RSA pair" << std::endl;
    131      return std::unique_ptr<ParamHolder>(new RsaParamHolder());
    132 
    133    case CKM_DSA_KEY_PAIR_GEN:
    134    case CKM_DH_PKCS_KEY_PAIR_GEN: {
    135      PQGParams* pqg_params = nullptr;
    136      PQGVerify* pqg_verify = nullptr;
    137      const unsigned int key_size = 1024;
    138      SECStatus rv = PK11_PQG_ParamGenV2(key_size, 0, key_size / 16,
    139                                         &pqg_params, &pqg_verify);
    140      if (rv != SECSuccess) {
    141        ADD_FAILURE() << "PK11_PQG_ParamGenV2 failed";
    142        return nullptr;
    143      }
    144      EXPECT_NE(nullptr, pqg_verify);
    145      EXPECT_NE(nullptr, pqg_params);
    146      PK11_PQG_DestroyVerify(pqg_verify);
    147      if (mech_ == CKM_DSA_KEY_PAIR_GEN) {
    148        std::cerr << "Generate DSA pair" << std::endl;
    149        return std::unique_ptr<ParamHolder>(new PqgParamHolder(pqg_params));
    150      }
    151      std::cerr << "Generate DH pair" << std::endl;
    152      return std::unique_ptr<ParamHolder>(new DhParamHolder(pqg_params));
    153    }
    154 
    155    case CKM_EC_EDWARDS_KEY_PAIR_GEN:
    156      std::cerr << "Generate ED pair on " << curve_ << std::endl;
    157      return std::unique_ptr<ParamHolder>(
    158          new EcParamHolder(SEC_OID_ED25519_PUBLIC_KEY));
    159 
    160    case CKM_EC_MONTGOMERY_KEY_PAIR_GEN:
    161      std::cerr << "Generate X25519 pair on " << curve_ << std::endl;
    162      return std::unique_ptr<ParamHolder>(new EcParamHolder(SEC_OID_X25519));
    163 
    164    case CKM_EC_KEY_PAIR_GEN:
    165      std::cerr << "Generate EC pair on " << curve_ << std::endl;
    166      return std::unique_ptr<ParamHolder>(new EcParamHolder(curve_));
    167 
    168    case CKM_NSS_KYBER_KEY_PAIR_GEN:
    169      std::cerr << "Generate Kyber768 pair" << std::endl;
    170      return std::unique_ptr<ParamHolder>(
    171          new KyberParamHolder(CKP_NSS_KYBER_768_ROUND3));
    172 
    173    case CKM_NSS_ML_KEM_KEY_PAIR_GEN:
    174      std::cerr << "Generate ML-KEM768 pair" << std::endl;
    175      return std::unique_ptr<ParamHolder>(new KyberParamHolder(CKP_ML_KEM_768));
    176 
    177    case CKM_ML_KEM_KEY_PAIR_GEN:
    178      std::cerr << "Generate ML-KEM1024 pair" << std::endl;
    179      return std::unique_ptr<ParamHolder>(
    180          new KyberParamHolder(CKP_ML_KEM_1024));
    181 
    182    default:
    183      ADD_FAILURE() << "unknown OID " << mech_;
    184  }
    185  return nullptr;
    186 }
    187 
    188 }  // namespace nss_test