tor-browser

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

pk11_aeskeywrap_unittest.cc (4699B)


      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 
     15 namespace nss_test {
     16 
     17 class Pkcs11AESKeyWrapTest : public ::testing::TestWithParam<keywrap_vector> {
     18 protected:
     19  CK_MECHANISM_TYPE mechanism = CKM_NSS_AES_KEY_WRAP;
     20 
     21  void WrapUnwrap(unsigned char* kek_data, unsigned int kek_len,
     22                  unsigned char* key_data, unsigned int key_data_len,
     23                  unsigned char* expected_ciphertext,
     24                  unsigned int expected_ciphertext_len,
     25                  std::map<Action, Result> tests, uint32_t test_id) {
     26    std::vector<unsigned char> wrapped_key(PR_MAX(1U, expected_ciphertext_len));
     27    std::vector<unsigned char> unwrapped_key(PR_MAX(1U, key_data_len));
     28    std::vector<unsigned char> zeros(PR_MAX(1U, expected_ciphertext_len));
     29    std::fill(zeros.begin(), zeros.end(), 0);
     30    unsigned int wrapped_key_len = 0;
     31    unsigned int unwrapped_key_len = 0;
     32    SECStatus rv;
     33 
     34    std::stringstream s;
     35    s << "Test with original ID #" << test_id << " failed." << std::endl;
     36    std::string msg = s.str();
     37 
     38    ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
     39    ASSERT_NE(nullptr, slot) << msg;
     40 
     41    // Import encryption key.
     42    SECItem kek_item = {siBuffer, kek_data, kek_len};
     43    ScopedPK11SymKey kek(PK11_ImportSymKey(slot.get(), CKM_NSS_AES_KEY_WRAP,
     44                                           PK11_OriginUnwrap, CKA_ENCRYPT,
     45                                           &kek_item, nullptr));
     46    EXPECT_TRUE(!!kek) << msg;
     47 
     48    // Wrap key
     49    Action test = WRAP;
     50    if (tests.count(test)) {
     51      rv = PK11_Encrypt(kek.get(), mechanism, nullptr /* param */,
     52                        wrapped_key.data(), &wrapped_key_len,
     53                        wrapped_key.size(), key_data, key_data_len);
     54      ASSERT_EQ(rv, tests[test].expect_rv) << msg;
     55 
     56      // If we failed, check that output was not produced.
     57      if (rv == SECFailure) {
     58        EXPECT_TRUE(wrapped_key_len == 0);
     59        EXPECT_TRUE(!memcmp(wrapped_key.data(), zeros.data(), wrapped_key_len));
     60      }
     61 
     62      if (tests[test].output_match) {
     63        EXPECT_EQ(expected_ciphertext_len, wrapped_key_len) << msg;
     64        EXPECT_TRUE(!memcmp(expected_ciphertext, wrapped_key.data(),
     65                            expected_ciphertext_len))
     66            << msg;
     67      } else {
     68        // If we produced output, verify that it doesn't match the vector
     69        if (wrapped_key_len) {
     70          EXPECT_FALSE(wrapped_key_len == expected_ciphertext_len &&
     71                       !memcmp(wrapped_key.data(), expected_ciphertext,
     72                               expected_ciphertext_len))
     73              << msg;
     74        }
     75      }
     76    }
     77 
     78    // Unwrap key
     79    test = UNWRAP;
     80    if (tests.count(test)) {
     81      rv = PK11_Decrypt(kek.get(), mechanism, nullptr /* param */,
     82                        unwrapped_key.data(), &unwrapped_key_len,
     83                        unwrapped_key.size(), expected_ciphertext,
     84                        expected_ciphertext_len);
     85      ASSERT_EQ(rv, tests[test].expect_rv) << msg;
     86 
     87      // If we failed, check that output was not produced.
     88      if (rv == SECFailure) {
     89        EXPECT_TRUE(unwrapped_key_len == 0);
     90        EXPECT_TRUE(
     91            !memcmp(unwrapped_key.data(), zeros.data(), unwrapped_key_len));
     92      }
     93 
     94      if (tests[test].output_match) {
     95        EXPECT_EQ(unwrapped_key_len, key_data_len) << msg;
     96        EXPECT_TRUE(!memcmp(key_data, unwrapped_key.data(), key_data_len))
     97            << msg;
     98      } else {
     99        // If we produced output, verify that it doesn't match the vector
    100        if (unwrapped_key_len) {
    101          EXPECT_FALSE(
    102              unwrapped_key_len == expected_ciphertext_len &&
    103              !memcmp(unwrapped_key.data(), key_data, unwrapped_key_len))
    104              << msg;
    105        }
    106      }
    107    }
    108  }
    109 
    110  void WrapUnwrap(keywrap_vector testvector) {
    111    WrapUnwrap(testvector.key.data(), testvector.key.size(),
    112               testvector.msg.data(), testvector.msg.size(),
    113               testvector.ct.data(), testvector.ct.size(), testvector.tests,
    114               testvector.test_id);
    115  }
    116 };
    117 
    118 TEST_P(Pkcs11AESKeyWrapTest, TestVectors) { WrapUnwrap(GetParam()); }
    119 
    120 INSTANTIATE_TEST_SUITE_P(Pkcs11WycheproofAESKWTest, Pkcs11AESKeyWrapTest,
    121                         ::testing::ValuesIn(kWycheproofAesKWVectors));
    122 }  // namespace nss_test