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