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