tor-browser

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

pk11_aeskeywrappad_unittest.cc (16597B)


      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 "gtest/gtest.h"
      9 #include "nss.h"
     10 #include "nss_scoped_ptrs.h"
     11 #include "pk11pub.h"
     12 
     13 namespace nss_test {
     14 
     15 class Pkcs11AESKeyWrapPadTest : public ::testing::Test {};
     16 
     17 // Encrypt an ephemeral EC key (U2F use case)
     18 TEST_F(Pkcs11AESKeyWrapPadTest, WrapUnwrapECKey) {
     19  const uint32_t kwrappedBufLen = 256;
     20  const uint32_t kPublicKeyLen = 65;
     21  const uint32_t kOidLen = 65;
     22  unsigned char param_buf[kOidLen];
     23  unsigned char unwrap_buf[kPublicKeyLen];
     24 
     25  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
     26  ASSERT_NE(nullptr, slot);
     27 
     28  SECItem ecdsa_params = {siBuffer, param_buf, sizeof(param_buf)};
     29  SECOidData* oid_data = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP256R1);
     30  ASSERT_NE(oid_data, nullptr);
     31  ecdsa_params.data[0] = SEC_ASN1_OBJECT_ID;
     32  ecdsa_params.data[1] = oid_data->oid.len;
     33  memcpy(ecdsa_params.data + 2, oid_data->oid.data, oid_data->oid.len);
     34  ecdsa_params.len = oid_data->oid.len + 2;
     35 
     36  SECKEYPublicKey* pub_tmp;
     37  ScopedSECKEYPublicKey pub_key;
     38  ScopedSECKEYPrivateKey priv_key(
     39      PK11_GenerateKeyPair(slot.get(), CKM_EC_KEY_PAIR_GEN, &ecdsa_params,
     40                           &pub_tmp, PR_FALSE, PR_TRUE, nullptr));
     41  ASSERT_NE(nullptr, priv_key);
     42  ASSERT_NE(nullptr, pub_tmp);
     43  pub_key.reset(pub_tmp);
     44 
     45  // Generate a KEK.
     46  ScopedPK11SymKey kek(
     47      PK11_KeyGen(slot.get(), CKM_AES_CBC, nullptr, 16, nullptr));
     48  ASSERT_NE(nullptr, kek);
     49 
     50  // Wrap the key
     51  ScopedSECItem wrapped(::SECITEM_AllocItem(nullptr, nullptr, kwrappedBufLen));
     52  ScopedSECItem param(PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP_PAD, nullptr));
     53 
     54  SECStatus rv = PK11_WrapPrivKey(slot.get(), kek.get(), priv_key.get(),
     55                                  CKM_NSS_AES_KEY_WRAP_PAD, param.get(),
     56                                  wrapped.get(), nullptr);
     57  ASSERT_EQ(rv, SECSuccess);
     58 
     59  SECItem pubKey = {siBuffer, unwrap_buf, kPublicKeyLen};
     60  CK_ATTRIBUTE_TYPE usages[] = {CKA_SIGN};
     61  int usageCount = 1;
     62 
     63  ScopedSECKEYPrivateKey unwrapped(
     64      PK11_UnwrapPrivKey(slot.get(), kek.get(), CKM_NSS_AES_KEY_WRAP_PAD,
     65                         param.get(), wrapped.get(), nullptr, &pubKey, false,
     66                         true, CKK_EC, usages, usageCount, nullptr));
     67  ASSERT_EQ(0, PORT_GetError());
     68  ASSERT_TRUE(!!unwrapped);
     69 
     70  // Try it with internal params allocation.
     71  SECKEYPrivateKey* tmp = PK11_UnwrapPrivKey(
     72      slot.get(), kek.get(), CKM_NSS_AES_KEY_WRAP_PAD, nullptr, wrapped.get(),
     73      nullptr, &pubKey, false, true, CKK_EC, usages, usageCount, nullptr);
     74  ASSERT_EQ(0, PORT_GetError());
     75  ASSERT_NE(nullptr, tmp);
     76  unwrapped.reset(tmp);
     77 }
     78 
     79 // Encrypt an ephemeral RSA key
     80 TEST_F(Pkcs11AESKeyWrapPadTest, WrapUnwrapRsaKey) {
     81  const uint32_t kwrappedBufLen = 648;
     82  unsigned char unwrap_buf[kwrappedBufLen];
     83 
     84  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
     85  ASSERT_NE(nullptr, slot);
     86 
     87  PK11RSAGenParams rsa_param;
     88  rsa_param.keySizeInBits = 1024;
     89  rsa_param.pe = 65537L;
     90 
     91  SECKEYPublicKey* pub_tmp;
     92  ScopedSECKEYPublicKey pub_key;
     93  ScopedSECKEYPrivateKey priv_key(
     94      PK11_GenerateKeyPair(slot.get(), CKM_RSA_PKCS_KEY_PAIR_GEN, &rsa_param,
     95                           &pub_tmp, PR_FALSE, PR_FALSE, nullptr));
     96  ASSERT_NE(nullptr, priv_key);
     97  ASSERT_NE(nullptr, pub_tmp);
     98  pub_key.reset(pub_tmp);
     99 
    100  // Generate a KEK.
    101  ScopedPK11SymKey kek(
    102      PK11_KeyGen(slot.get(), CKM_AES_CBC, nullptr, 16, nullptr));
    103  ASSERT_NE(nullptr, kek);
    104 
    105  // Wrap the key
    106  ScopedSECItem wrapped(::SECITEM_AllocItem(nullptr, nullptr, kwrappedBufLen));
    107  ScopedSECItem param(PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP_PAD, nullptr));
    108 
    109  SECStatus rv = PK11_WrapPrivKey(slot.get(), kek.get(), priv_key.get(),
    110                                  CKM_NSS_AES_KEY_WRAP_PAD, param.get(),
    111                                  wrapped.get(), nullptr);
    112  ASSERT_EQ(rv, SECSuccess);
    113 
    114  SECItem pubKey = {siBuffer, unwrap_buf, kwrappedBufLen};
    115  CK_ATTRIBUTE_TYPE usages[] = {CKA_SIGN};
    116  int usageCount = 1;
    117 
    118  ScopedSECKEYPrivateKey unwrapped(
    119      PK11_UnwrapPrivKey(slot.get(), kek.get(), CKM_NSS_AES_KEY_WRAP_PAD,
    120                         param.get(), wrapped.get(), nullptr, &pubKey, false,
    121                         false, CKK_EC, usages, usageCount, nullptr));
    122  ASSERT_EQ(0, PORT_GetError());
    123  ASSERT_TRUE(!!unwrapped);
    124 
    125  ScopedSECItem priv_key_data(
    126      PK11_ExportDERPrivateKeyInfo(priv_key.get(), nullptr));
    127  ScopedSECItem unwrapped_data(
    128      PK11_ExportDERPrivateKeyInfo(unwrapped.get(), nullptr));
    129  EXPECT_TRUE(!!priv_key_data);
    130  EXPECT_TRUE(!!unwrapped_data);
    131  ASSERT_EQ(priv_key_data->len, unwrapped_data->len);
    132  ASSERT_EQ(
    133      0, memcmp(priv_key_data->data, unwrapped_data->data, priv_key_data->len));
    134 }
    135 
    136 // Wrap a random that's a multiple of the block size, and compare the unwrap
    137 // result.
    138 TEST_F(Pkcs11AESKeyWrapPadTest, WrapUnwrapRandom_EvenBlock) {
    139  const uint32_t kInputKeyLen = 128;
    140  uint32_t out_len = 0;
    141  std::vector<unsigned char> input_key(kInputKeyLen);
    142  std::vector<unsigned char> wrapped_key(
    143      kInputKeyLen + AES_BLOCK_SIZE);  // One block of padding
    144  std::vector<unsigned char> unwrapped_key(
    145      kInputKeyLen + AES_BLOCK_SIZE);  // One block of padding
    146 
    147  // Generate input key material
    148  SECStatus rv = PK11_GenerateRandom(input_key.data(), input_key.size());
    149  EXPECT_EQ(SECSuccess, rv);
    150 
    151  // Generate a KEK.
    152  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
    153  ASSERT_NE(nullptr, slot);
    154  ScopedPK11SymKey kek(
    155      PK11_KeyGen(slot.get(), CKM_AES_CBC, nullptr, 16, nullptr));
    156  ASSERT_NE(nullptr, kek);
    157 
    158  // Wrap the key
    159  rv = PK11_Encrypt(kek.get(), CKM_NSS_AES_KEY_WRAP_PAD, /* param */ nullptr,
    160                    wrapped_key.data(), &out_len,
    161                    static_cast<unsigned int>(wrapped_key.size()),
    162                    input_key.data(),
    163                    static_cast<unsigned int>(input_key.size()));
    164  ASSERT_EQ(SECSuccess, rv);
    165 
    166  rv = PK11_Decrypt(kek.get(), CKM_NSS_AES_KEY_WRAP_PAD, /* param */ nullptr,
    167                    unwrapped_key.data(), &out_len,
    168                    static_cast<unsigned int>(unwrapped_key.size()),
    169                    wrapped_key.data(), out_len);
    170  ASSERT_EQ(SECSuccess, rv);
    171  ASSERT_EQ(input_key.size(), out_len);
    172  ASSERT_EQ(0, memcmp(input_key.data(), unwrapped_key.data(), out_len));
    173 }
    174 
    175 // Wrap a random that's NOT a multiple of the block size, and compare the unwrap
    176 // result.
    177 TEST_F(Pkcs11AESKeyWrapPadTest, WrapUnwrapRandom_OddBlock1) {
    178  const uint32_t kInputKeyLen = 65;
    179  uint32_t out_len = 0;
    180  std::vector<unsigned char> input_key(kInputKeyLen);
    181  std::vector<unsigned char> wrapped_key(
    182      kInputKeyLen + AES_BLOCK_SIZE);  // One block of padding
    183  std::vector<unsigned char> unwrapped_key(
    184      kInputKeyLen + AES_BLOCK_SIZE);  // One block of padding
    185 
    186  // Generate input key material
    187  SECStatus rv = PK11_GenerateRandom(input_key.data(), input_key.size());
    188  EXPECT_EQ(SECSuccess, rv);
    189 
    190  // Generate a KEK.
    191  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
    192  ASSERT_NE(nullptr, slot);
    193  ScopedPK11SymKey kek(
    194      PK11_KeyGen(slot.get(), CKM_AES_CBC, nullptr, 16, nullptr));
    195  ASSERT_NE(nullptr, kek);
    196 
    197  // Wrap the key
    198  rv = PK11_Encrypt(kek.get(), CKM_NSS_AES_KEY_WRAP_PAD, /* param */ nullptr,
    199                    wrapped_key.data(), &out_len,
    200                    static_cast<unsigned int>(wrapped_key.size()),
    201                    input_key.data(),
    202                    static_cast<unsigned int>(input_key.size()));
    203  ASSERT_EQ(SECSuccess, rv);
    204 
    205  rv = PK11_Decrypt(kek.get(), CKM_NSS_AES_KEY_WRAP_PAD, /* param */ nullptr,
    206                    unwrapped_key.data(), &out_len,
    207                    static_cast<unsigned int>(unwrapped_key.size()),
    208                    wrapped_key.data(), out_len);
    209  ASSERT_EQ(SECSuccess, rv);
    210  ASSERT_EQ(input_key.size(), out_len);
    211  ASSERT_EQ(0, memcmp(input_key.data(), unwrapped_key.data(), out_len));
    212 }
    213 
    214 // Wrap a random that's NOT a multiple of the block size, and compare the unwrap
    215 // result.
    216 TEST_F(Pkcs11AESKeyWrapPadTest, WrapUnwrapRandom_OddBlock2) {
    217  const uint32_t kInputKeyLen = 63;
    218  uint32_t out_len = 0;
    219  std::vector<unsigned char> input_key(kInputKeyLen);
    220  std::vector<unsigned char> wrapped_key(
    221      kInputKeyLen + AES_BLOCK_SIZE);  // One block of padding
    222  std::vector<unsigned char> unwrapped_key(
    223      kInputKeyLen + AES_BLOCK_SIZE);  // One block of padding
    224 
    225  // Generate input key material
    226  SECStatus rv = PK11_GenerateRandom(input_key.data(), input_key.size());
    227  EXPECT_EQ(SECSuccess, rv);
    228 
    229  // Generate a KEK.
    230  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
    231  ASSERT_NE(nullptr, slot);
    232  ScopedPK11SymKey kek(
    233      PK11_KeyGen(slot.get(), CKM_AES_CBC, nullptr, 16, nullptr));
    234  ASSERT_NE(nullptr, kek);
    235 
    236  // Wrap the key
    237  rv = PK11_Encrypt(kek.get(), CKM_NSS_AES_KEY_WRAP_PAD, /* param */ nullptr,
    238                    wrapped_key.data(), &out_len, wrapped_key.size(),
    239                    input_key.data(), input_key.size());
    240  ASSERT_EQ(SECSuccess, rv);
    241 
    242  rv = PK11_Decrypt(kek.get(), CKM_NSS_AES_KEY_WRAP_PAD, /* param */ nullptr,
    243                    unwrapped_key.data(), &out_len,
    244                    static_cast<unsigned int>(unwrapped_key.size()),
    245                    wrapped_key.data(), out_len);
    246  ASSERT_EQ(SECSuccess, rv);
    247  ASSERT_EQ(input_key.size(), out_len);
    248  ASSERT_EQ(0, memcmp(input_key.data(), unwrapped_key.data(), out_len));
    249 }
    250 
    251 // Invalid long padding (over the block size, but otherwise valid)
    252 TEST_F(Pkcs11AESKeyWrapPadTest, WrapUnwrapRandom_PaddingTooLong) {
    253  const uint32_t kInputKeyLen = 32;
    254  uint32_t out_len = 0;
    255 
    256  // Apply our own padding
    257  const unsigned char buf[32] = {
    258      0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
    259      0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
    260      0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
    261  std::vector<unsigned char> wrapped_key(kInputKeyLen + AES_BLOCK_SIZE);
    262  std::vector<unsigned char> unwrapped_key(kInputKeyLen + AES_BLOCK_SIZE);
    263 
    264  // Generate a KEK.
    265  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
    266  ASSERT_NE(nullptr, slot);
    267  ScopedPK11SymKey kek(
    268      PK11_KeyGen(slot.get(), CKM_AES_CBC, nullptr, 16, nullptr));
    269  ASSERT_NE(nullptr, kek);
    270 
    271  // Wrap the key
    272  SECStatus rv =
    273      PK11_Encrypt(kek.get(), CKM_NSS_AES_KEY_WRAP,  // Don't apply more padding
    274                   /* param */ nullptr, wrapped_key.data(), &out_len,
    275                   wrapped_key.size(), buf, sizeof(buf));
    276  ASSERT_EQ(SECSuccess, rv);
    277 
    278  rv = PK11_Decrypt(kek.get(), CKM_NSS_AES_KEY_WRAP_PAD, /* param */ nullptr,
    279                    unwrapped_key.data(), &out_len,
    280                    static_cast<unsigned int>(unwrapped_key.size()),
    281                    wrapped_key.data(), out_len);
    282  ASSERT_EQ(SECFailure, rv);
    283 }
    284 
    285 // Invalid 0-length padding (there should be a full block if the message doesn't
    286 // need to be padded)
    287 TEST_F(Pkcs11AESKeyWrapPadTest, WrapUnwrapRandom_NoPadding) {
    288  const uint32_t kInputKeyLen = 32;
    289  uint32_t out_len = 0;
    290 
    291  // Apply our own padding
    292  const unsigned char buf[32] = {0};
    293  std::vector<unsigned char> wrapped_key(kInputKeyLen + AES_BLOCK_SIZE);
    294  std::vector<unsigned char> unwrapped_key(kInputKeyLen + AES_BLOCK_SIZE);
    295 
    296  // Generate a KEK.
    297  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
    298  ASSERT_NE(nullptr, slot);
    299  ScopedPK11SymKey kek(
    300      PK11_KeyGen(slot.get(), CKM_AES_CBC, nullptr, 16, nullptr));
    301  ASSERT_NE(nullptr, kek);
    302 
    303  // Wrap the key
    304  SECStatus rv =
    305      PK11_Encrypt(kek.get(), CKM_NSS_AES_KEY_WRAP,  // Don't apply more padding
    306                   /* param */ nullptr, wrapped_key.data(), &out_len,
    307                   wrapped_key.size(), buf, sizeof(buf));
    308  ASSERT_EQ(SECSuccess, rv);
    309 
    310  rv = PK11_Decrypt(kek.get(), CKM_NSS_AES_KEY_WRAP_PAD, /* param */ nullptr,
    311                    unwrapped_key.data(), &out_len,
    312                    static_cast<unsigned int>(unwrapped_key.size()),
    313                    wrapped_key.data(), out_len);
    314  ASSERT_EQ(SECFailure, rv);
    315 }
    316 
    317 // Invalid padding
    318 TEST_F(Pkcs11AESKeyWrapPadTest, WrapUnwrapRandom_BadPadding1) {
    319  const uint32_t kInputKeyLen = 32;
    320  uint32_t out_len = 0;
    321 
    322  // Apply our own padding
    323  const unsigned char buf[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    324                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    325                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    326                                 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08,
    327                                 0x08, 0x08, 0x08, 0x08};  // Check all 8 bytes
    328  std::vector<unsigned char> wrapped_key(kInputKeyLen + AES_BLOCK_SIZE);
    329  std::vector<unsigned char> unwrapped_key(kInputKeyLen + AES_BLOCK_SIZE);
    330 
    331  // Generate a KEK.
    332  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
    333  ASSERT_NE(nullptr, slot);
    334  ScopedPK11SymKey kek(
    335      PK11_KeyGen(slot.get(), CKM_AES_CBC, nullptr, 16, nullptr));
    336  ASSERT_NE(nullptr, kek);
    337 
    338  // Wrap the key
    339  SECStatus rv =
    340      PK11_Encrypt(kek.get(), CKM_NSS_AES_KEY_WRAP,  // Don't apply more padding
    341                   /* param */ nullptr, wrapped_key.data(), &out_len,
    342                   wrapped_key.size(), buf, sizeof(buf));
    343  ASSERT_EQ(SECSuccess, rv);
    344 
    345  rv = PK11_Decrypt(kek.get(), CKM_NSS_AES_KEY_WRAP_PAD, /* param */ nullptr,
    346                    unwrapped_key.data(), &out_len,
    347                    static_cast<unsigned int>(unwrapped_key.size()),
    348                    wrapped_key.data(), out_len);
    349  ASSERT_EQ(SECFailure, rv);
    350 }
    351 
    352 // Invalid padding
    353 TEST_F(Pkcs11AESKeyWrapPadTest, WrapUnwrapRandom_BadPadding2) {
    354  const uint32_t kInputKeyLen = 32;
    355  uint32_t out_len = 0;
    356 
    357  // Apply our own padding
    358  const unsigned char
    359      buf[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    360                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    361                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    362                 0x00, 0x00, 0x00, 0x01, 0x02};  // Check first loop repeat
    363  std::vector<unsigned char> wrapped_key(kInputKeyLen + AES_BLOCK_SIZE);
    364  std::vector<unsigned char> unwrapped_key(kInputKeyLen + AES_BLOCK_SIZE);
    365 
    366  // Generate a KEK.
    367  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
    368  ASSERT_NE(nullptr, slot);
    369  ScopedPK11SymKey kek(
    370      PK11_KeyGen(slot.get(), CKM_AES_CBC, nullptr, 16, nullptr));
    371  ASSERT_NE(nullptr, kek);
    372 
    373  // Wrap the key
    374  SECStatus rv =
    375      PK11_Encrypt(kek.get(), CKM_NSS_AES_KEY_WRAP,  // Don't apply more padding
    376                   /* param */ nullptr, wrapped_key.data(), &out_len,
    377                   wrapped_key.size(), buf, sizeof(buf));
    378  ASSERT_EQ(SECSuccess, rv);
    379 
    380  rv = PK11_Decrypt(kek.get(), CKM_NSS_AES_KEY_WRAP_PAD, /* param */ nullptr,
    381                    unwrapped_key.data(), &out_len,
    382                    static_cast<unsigned int>(unwrapped_key.size()),
    383                    wrapped_key.data(), out_len);
    384  ASSERT_EQ(SECFailure, rv);
    385 }
    386 
    387 // Minimum valid padding
    388 TEST_F(Pkcs11AESKeyWrapPadTest, WrapUnwrapRandom_ShortValidPadding) {
    389  const uint32_t kInputKeyLen = 32;
    390  uint32_t out_len = 0;
    391 
    392  // Apply our own padding
    393  const unsigned char buf[kInputKeyLen] = {
    394      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    395      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    396      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};  // Minimum
    397  std::vector<unsigned char> wrapped_key(kInputKeyLen + AES_BLOCK_SIZE);
    398  std::vector<unsigned char> unwrapped_key(kInputKeyLen + AES_BLOCK_SIZE);
    399 
    400  // Generate a KEK.
    401  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
    402  ASSERT_NE(nullptr, slot);
    403  ScopedPK11SymKey kek(
    404      PK11_KeyGen(slot.get(), CKM_AES_CBC, nullptr, 16, nullptr));
    405  ASSERT_NE(nullptr, kek);
    406 
    407  // Wrap the key
    408  SECStatus rv =
    409      PK11_Encrypt(kek.get(), CKM_NSS_AES_KEY_WRAP,  // Don't apply more padding
    410                   /* param */ nullptr, wrapped_key.data(), &out_len,
    411                   wrapped_key.size(), buf, sizeof(buf));
    412  ASSERT_EQ(SECSuccess, rv);
    413 
    414  rv = PK11_Decrypt(kek.get(), CKM_NSS_AES_KEY_WRAP_PAD, /* param */ nullptr,
    415                    unwrapped_key.data(), &out_len,
    416                    static_cast<unsigned int>(unwrapped_key.size()),
    417                    wrapped_key.data(), out_len);
    418  ASSERT_EQ(SECSuccess, rv);
    419  ASSERT_EQ(kInputKeyLen - 1, out_len);
    420  ASSERT_EQ(0, memcmp(buf, unwrapped_key.data(), out_len));
    421 }
    422 
    423 }  // namespace nss_test