tor-browser

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

pk11_aeskeywrapkwp_unittest.cc (5854B)


      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 "pk11pub.h"
     10 
     11 #include "testvectors/kw-vectors.h"
     12 #include "gtest/gtest.h"
     13 #include "nss_scoped_ptrs.h"
     14 #include "json_reader.h"
     15 
     16 extern std::string g_source_dir;
     17 
     18 namespace nss_test {
     19 
     20 class Pkcs11AESKeyWrapKwpTest
     21    : public ::testing::TestWithParam<keywrap_vector> {
     22 protected:
     23  CK_MECHANISM_TYPE mechanism = CKM_AES_KEY_WRAP_KWP;
     24 
     25  void WrapUnwrap(unsigned char* kek_data, unsigned int kek_len,
     26                  unsigned char* key_data, unsigned int key_data_len,
     27                  unsigned char* expected_ciphertext,
     28                  unsigned int expected_ciphertext_len,
     29                  std::map<Action, Result> tests, uint32_t test_id) {
     30    std::vector<unsigned char> wrapped_key(PR_MAX(1U, expected_ciphertext_len));
     31    std::vector<unsigned char> unwrapped_key(PR_MAX(1U, key_data_len));
     32    std::vector<unsigned char> zeros(PR_MAX(1U, expected_ciphertext_len), 0);
     33    unsigned int wrapped_key_len = 0;
     34    unsigned int unwrapped_key_len = 0;
     35    SECStatus rv;
     36 
     37    std::stringstream s;
     38    s << "Test with original ID #" << test_id << " failed." << std::endl;
     39    std::string msg = s.str();
     40 
     41    ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
     42    ASSERT_NE(nullptr, slot) << msg;
     43 
     44    // Import encryption key.
     45    SECItem kek_item = {siBuffer, kek_data, kek_len};
     46    ScopedPK11SymKey kek(PK11_ImportSymKeyWithFlags(
     47        slot.get(), mechanism, PK11_OriginUnwrap, CKA_ENCRYPT, &kek_item,
     48        CKF_DECRYPT, PR_FALSE, nullptr));
     49    EXPECT_TRUE(!!kek) << msg;
     50 
     51    // Wrap key
     52    Action test = WRAP;
     53    if (tests.count(test)) {
     54      rv = PK11_Encrypt(kek.get(), mechanism, nullptr /* param */,
     55                        wrapped_key.data(), &wrapped_key_len,
     56                        wrapped_key.size(), key_data, key_data_len);
     57      ASSERT_EQ(rv, tests[test].expect_rv) << msg;
     58 
     59      // If we failed, check that output was not produced.
     60      if (rv == SECFailure) {
     61        EXPECT_TRUE(wrapped_key_len == 0);
     62        EXPECT_TRUE(!memcmp(wrapped_key.data(), zeros.data(), wrapped_key_len));
     63      }
     64 
     65      if (tests[test].output_match) {
     66        EXPECT_EQ(expected_ciphertext_len, wrapped_key_len) << msg;
     67        EXPECT_TRUE(!memcmp(expected_ciphertext, wrapped_key.data(),
     68                            expected_ciphertext_len))
     69            << msg;
     70      } else {
     71        // If we produced output, verify that it doesn't match the vector
     72        if (wrapped_key_len) {
     73          EXPECT_FALSE(wrapped_key_len == expected_ciphertext_len &&
     74                       !memcmp(wrapped_key.data(), expected_ciphertext,
     75                               expected_ciphertext_len))
     76              << msg;
     77        }
     78      }
     79    }
     80 
     81    // Unwrap key
     82    test = UNWRAP;
     83    if (tests.count(test)) {
     84      rv = PK11_Decrypt(kek.get(), mechanism, nullptr /* param */,
     85                        unwrapped_key.data(), &unwrapped_key_len,
     86                        unwrapped_key.size(), expected_ciphertext,
     87                        expected_ciphertext_len);
     88      ASSERT_EQ(rv, tests[test].expect_rv) << msg;
     89 
     90      // If we failed, check that output was not produced.
     91      if (rv == SECFailure) {
     92        EXPECT_TRUE(unwrapped_key_len == 0);
     93        EXPECT_TRUE(
     94            !memcmp(unwrapped_key.data(), zeros.data(), unwrapped_key_len));
     95      }
     96 
     97      if (tests[test].output_match) {
     98        EXPECT_EQ(unwrapped_key_len, key_data_len) << msg;
     99        EXPECT_TRUE(!memcmp(key_data, unwrapped_key.data(), key_data_len))
    100            << msg;
    101      } else {
    102        // If we produced output, verify that it doesn't match the vector
    103        if (unwrapped_key_len) {
    104          EXPECT_FALSE(
    105              unwrapped_key_len == expected_ciphertext_len &&
    106              !memcmp(unwrapped_key.data(), key_data, unwrapped_key_len))
    107              << msg;
    108        }
    109      }
    110    }
    111  }
    112 };
    113 
    114 TEST_F(Pkcs11AESKeyWrapKwpTest, TestVectors) {
    115  std::string testvectors =
    116      ::g_source_dir + "/../common/testvectors/kwp-vectors.json";
    117  JsonReader r(testvectors);
    118 
    119  r.NextItem();
    120  ASSERT_EQ("numberOfTests", r.ReadLabel());
    121  uint64_t expected_count = r.ReadInt();
    122  uint64_t count = 0;
    123 
    124  r.NextItem();
    125  ASSERT_EQ("tests", r.ReadLabel());
    126 
    127  while (r.NextItemArray()) {
    128    count++;
    129    keywrap_vector testvector;
    130 
    131    uint8_t seen = 0;
    132    while (r.NextItem()) {
    133      std::string n = r.ReadLabel();
    134      if (n == "tcId") {
    135        seen |= 1;
    136        testvector.test_id = r.ReadInt();
    137      } else if (n == "key") {
    138        seen |= 2;
    139        testvector.key = r.ReadHex();
    140      } else if (n == "msg") {
    141        seen |= 4;
    142        testvector.msg = r.ReadHex();
    143      } else if (n == "ct") {
    144        seen |= 8;
    145        testvector.ct = r.ReadHex();
    146      } else if (n == "wrapRv") {
    147        seen |= 16;
    148        testvector.tests[Action::WRAP].expect_rv = r.ReadSECStatus();
    149      } else if (n == "wrapMatch") {
    150        seen |= 32;
    151        testvector.tests[Action::WRAP].output_match = r.ReadBool();
    152      } else if (n == "unwrapRv") {
    153        seen |= 64;
    154        testvector.tests[Action::UNWRAP].expect_rv = r.ReadSECStatus();
    155      } else if (n == "unwrapMatch") {
    156        seen |= 128;
    157        testvector.tests[Action::UNWRAP].output_match = r.ReadBool();
    158      }
    159    }
    160    EXPECT_EQ(seen, 255);
    161    WrapUnwrap(testvector.key.data(), testvector.key.size(),
    162               testvector.msg.data(), testvector.msg.size(),
    163               testvector.ct.data(), testvector.ct.size(), testvector.tests,
    164               testvector.test_id);
    165  }
    166  EXPECT_EQ(count, expected_count);
    167 }
    168 
    169 }  // namespace nss_test