tor-browser

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

pk11_kem_unittest.cc (5377B)


      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 "gtest/gtest.h"
      6 #include "nss_scoped_ptrs.h"
      7 
      8 #include "pk11_keygen.h"
      9 #include "pk11pub.h"
     10 
     11 #include "blapi.h"
     12 #include "secport.h"
     13 
     14 namespace nss_test {
     15 
     16 class Pkcs11KEMTest
     17    : public ::testing::Test,
     18      public ::testing::WithParamInterface<CK_NSS_KEM_PARAMETER_SET_TYPE> {
     19 protected:
     20  PK11SymKey *Encapsulate(const ScopedSECKEYPublicKey &pub,
     21                          CK_MECHANISM_TYPE target, PK11AttrFlags attrFlags,
     22                          CK_FLAGS opFlags, ScopedSECItem *ciphertext) {
     23    PK11SymKey *sharedSecretRawPtr;
     24    SECItem *ciphertextRawPtr;
     25 
     26    EXPECT_EQ(SECSuccess,
     27              PK11_Encapsulate(pub.get(), target, attrFlags, opFlags,
     28                               &sharedSecretRawPtr, &ciphertextRawPtr));
     29 
     30    ciphertext->reset(ciphertextRawPtr);
     31 
     32    return sharedSecretRawPtr;
     33  }
     34 
     35  PK11SymKey *Decapsulate(const ScopedSECKEYPrivateKey &priv,
     36                          const ScopedSECItem &ciphertext,
     37                          CK_MECHANISM_TYPE target, PK11AttrFlags attrFlags,
     38                          CK_FLAGS opFlags) {
     39    PK11SymKey *sharedSecretRawPtr;
     40 
     41    EXPECT_EQ(SECSuccess,
     42              PK11_Decapsulate(priv.get(), ciphertext.get(), target, attrFlags,
     43                               opFlags, &sharedSecretRawPtr));
     44 
     45    return sharedSecretRawPtr;
     46  }
     47 
     48  SECItem *getRawKeyData(const ScopedPK11SymKey &key) {
     49    SECStatus rv = PK11_ExtractKeyValue(key.get());
     50    EXPECT_EQ(SECSuccess, rv);
     51 
     52    SECItem *keyData = PK11_GetKeyData(key.get());
     53    EXPECT_NE(nullptr, keyData);
     54    EXPECT_NE(nullptr, keyData->data);
     55 
     56    return keyData;
     57  }
     58 
     59  void checkSymKeyAttributeValue(const ScopedPK11SymKey &key,
     60                                 CK_ATTRIBUTE_TYPE attr,
     61                                 uint8_t *expectedValue) {
     62    SECItem attrValue;
     63 
     64    EXPECT_EQ(SECSuccess, PK11_ReadRawAttribute(PK11_TypeSymKey, key.get(),
     65                                                attr, &attrValue));
     66    EXPECT_EQ(0, memcmp(expectedValue, attrValue.data, attrValue.len));
     67 
     68    SECITEM_FreeItem(&attrValue, PR_FALSE);
     69  }
     70 
     71  CK_MECHANISM_TYPE keyGenMech() {
     72    switch (GetParam()) {
     73      case CKP_NSS_KYBER_768_ROUND3:
     74        return CKM_NSS_KYBER_KEY_PAIR_GEN;
     75      case CKP_NSS_ML_KEM_768:
     76        return CKM_NSS_ML_KEM_KEY_PAIR_GEN;
     77      case CKP_ML_KEM_768:
     78      case CKP_ML_KEM_1024:
     79        return CKM_ML_KEM_KEY_PAIR_GEN;
     80      default:
     81        EXPECT_TRUE(false);
     82        return 0;
     83    }
     84  }
     85 
     86  CK_MECHANISM_TYPE encapsMech() {
     87    switch (GetParam()) {
     88      case CKP_NSS_KYBER_768_ROUND3:
     89        return CKM_NSS_KYBER;
     90      case CKP_NSS_ML_KEM_768:
     91        return CKM_NSS_ML_KEM;
     92      case CKP_ML_KEM_768:
     93      case CKP_ML_KEM_1024:
     94        return CKM_ML_KEM;
     95      default:
     96        EXPECT_TRUE(false);
     97        return 0;
     98    }
     99  }
    100 };
    101 
    102 TEST_P(Pkcs11KEMTest, KemConsistencyTest) {
    103  Pkcs11KeyPairGenerator generator(keyGenMech());
    104  ScopedSECKEYPrivateKey priv;
    105  ScopedSECKEYPublicKey pub;
    106  generator.GenerateKey(&priv, &pub, false);
    107 
    108  ASSERT_NE(nullptr, pub);
    109  ASSERT_NE(nullptr, priv);
    110 
    111  // Copy the public key to simulate receiving the key as an octet string
    112  ScopedSECKEYPublicKey pubCopy(SECKEY_CopyPublicKey(pub.get()));
    113  ASSERT_NE(nullptr, pubCopy);
    114 
    115  ScopedPK11SlotInfo slot(PK11_GetBestSlot(encapsMech(), nullptr));
    116  ASSERT_NE(nullptr, slot);
    117  std::string name = PK11_GetSlotName(slot.get());
    118  ASSERT_EQ(name, "NSS Internal Cryptographic Services");
    119 
    120  ASSERT_NE((unsigned int)CK_INVALID_HANDLE,
    121            PK11_ImportPublicKey(slot.get(), pubCopy.get(), PR_FALSE));
    122 
    123  ScopedSECItem ciphertext;
    124  ScopedPK11SymKey sharedSecret(Encapsulate(
    125      pubCopy, CKM_SALSA20_POLY1305, PK11_ATTR_PRIVATE | PK11_ATTR_UNMODIFIABLE,
    126      CKF_ENCRYPT, &ciphertext));
    127 
    128  ASSERT_EQ(CKM_SALSA20_POLY1305, PK11_GetMechanism(sharedSecret.get()));
    129 
    130  CK_BBOOL ckTrue = CK_TRUE;
    131  CK_BBOOL ckFalse = CK_FALSE;
    132  checkSymKeyAttributeValue(sharedSecret, CKA_PRIVATE, &ckTrue);
    133  checkSymKeyAttributeValue(sharedSecret, CKA_MODIFIABLE, &ckFalse);
    134  checkSymKeyAttributeValue(sharedSecret, CKA_ENCRYPT, &ckTrue);
    135 
    136  ScopedPK11SymKey sharedSecret2(
    137      Decapsulate(priv, ciphertext, CKM_SALSA20_POLY1305,
    138                  PK11_ATTR_PRIVATE | PK11_ATTR_UNMODIFIABLE, CKF_ENCRYPT));
    139 
    140  ASSERT_EQ(CKM_SALSA20_POLY1305, PK11_GetMechanism(sharedSecret2.get()));
    141 
    142  checkSymKeyAttributeValue(sharedSecret2, CKA_PRIVATE, &ckTrue);
    143  checkSymKeyAttributeValue(sharedSecret2, CKA_MODIFIABLE, &ckFalse);
    144  checkSymKeyAttributeValue(sharedSecret2, CKA_ENCRYPT, &ckTrue);
    145 
    146  SECItem *item1 = getRawKeyData(sharedSecret);
    147  SECItem *item2 = getRawKeyData(sharedSecret2);
    148  NSS_DECLASSIFY(item1->data, item1->len);
    149  NSS_DECLASSIFY(item2->data, item2->len);
    150  EXPECT_EQ(0, SECITEM_CompareItem(item1, item2));
    151 }
    152 
    153 #ifndef NSS_DISABLE_KYBER
    154 INSTANTIATE_TEST_SUITE_P(Pkcs11KEMTest, Pkcs11KEMTest,
    155                         ::testing::Values(CKP_NSS_KYBER_768_ROUND3,
    156                                           CKP_NSS_ML_KEM_768, CKP_ML_KEM_768));
    157 #else
    158 INSTANTIATE_TEST_SUITE_P(Pkcs11KEMTest, Pkcs11KEMTest,
    159                         ::testing::Values(CKP_NSS_ML_KEM_768, CKP_ML_KEM_768));
    160 #endif
    161 
    162 }  // namespace nss_test