tor-browser

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

pk11_cipherop_unittest.cc (4177B)


      1 // This Source Code Form is subject to the terms of the Mozilla Public
      2 // License, v. 2.0. If a copy of the MPL was not distributed with this file,
      3 // You can obtain one at http://mozilla.org/MPL/2.0/.
      4 
      5 #include "gtest/gtest.h"
      6 #include "nss_scoped_ptrs.h"
      7 
      8 #include <assert.h>
      9 #include <limits.h>
     10 #include <prinit.h>
     11 #include <nss.h>
     12 #include <pk11pub.h>
     13 
     14 static const size_t kKeyLen = 128 / 8;
     15 
     16 namespace nss_test {
     17 
     18 //
     19 // The ciper tests using the bltest command cover a great deal of testing.
     20 // However, Bug 1489691 revealed a corner case which is covered here.
     21 // This test will make multiple calls to PK11_CipherOp using the same
     22 // cipher context with data that is not cipher block aligned.
     23 //
     24 
     25 static SECStatus GetBytes(const ScopedPK11Context& ctx, size_t len) {
     26  std::vector<uint8_t> in(len, 0);
     27 
     28  uint8_t outbuf[128];
     29  PORT_Assert(len <= sizeof(outbuf));
     30  int outlen;
     31  SECStatus rv = PK11_CipherOp(ctx.get(), outbuf, &outlen, len, in.data(), len);
     32  if (static_cast<size_t>(outlen) != len) {
     33    EXPECT_EQ(rv, SECFailure);
     34  }
     35  return rv;
     36 }
     37 
     38 TEST(Pkcs11CipherOp, SingleCtxMultipleUnalignedCipherOps) {
     39  ScopedNSSInitContext globalctx(
     40      NSS_InitContext("", "", "", "", NULL,
     41                      NSS_INIT_READONLY | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB |
     42                          NSS_INIT_FORCEOPEN | NSS_INIT_NOROOTINIT));
     43  ASSERT_TRUE(globalctx);
     44 
     45  const CK_MECHANISM_TYPE cipher = CKM_AES_CTR;
     46 
     47  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
     48  ASSERT_TRUE(slot);
     49 
     50  // Use arbitrary bytes for the AES key
     51  uint8_t key_bytes[kKeyLen];
     52  for (size_t i = 0; i < kKeyLen; i++) {
     53    key_bytes[i] = i;
     54  }
     55 
     56  SECItem keyItem = {siBuffer, key_bytes, kKeyLen};
     57 
     58  // The IV can be all zeros since we only encrypt once with
     59  // each AES key.
     60  CK_AES_CTR_PARAMS param = {128, {}};
     61  SECItem paramItem = {siBuffer, reinterpret_cast<unsigned char*>(&param),
     62                       sizeof(CK_AES_CTR_PARAMS)};
     63 
     64  ScopedPK11SymKey key(PK11_ImportSymKey(slot.get(), cipher, PK11_OriginUnwrap,
     65                                         CKA_ENCRYPT, &keyItem, NULL));
     66  ASSERT_TRUE(key);
     67  ScopedPK11Context ctx(
     68      PK11_CreateContextBySymKey(cipher, CKA_ENCRYPT, key.get(), &paramItem));
     69  ASSERT_TRUE(ctx);
     70 
     71  ASSERT_EQ(GetBytes(ctx, 7), SECSuccess);
     72  ASSERT_EQ(GetBytes(ctx, 17), SECSuccess);
     73 }
     74 
     75 // A context can't be used for Chacha20 as the underlying
     76 // PK11_CipherOp operation is calling the C_EncryptUpdate function for
     77 // which multi-part is disabled for ChaCha20 in counter mode.
     78 void ChachaMulti(CK_MECHANISM_TYPE cipher, SECItem* param) {
     79  ScopedNSSInitContext globalctx(
     80      NSS_InitContext("", "", "", "", NULL,
     81                      NSS_INIT_READONLY | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB |
     82                          NSS_INIT_FORCEOPEN | NSS_INIT_NOROOTINIT));
     83  ASSERT_TRUE(globalctx);
     84 
     85  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
     86  ASSERT_TRUE(slot);
     87 
     88  // Use arbitrary bytes for the ChaCha20 key and IV
     89  uint8_t key_bytes[32];
     90  for (size_t i = 0; i < 32; i++) {
     91    key_bytes[i] = i;
     92  }
     93  SECItem keyItem = {siBuffer, key_bytes, sizeof(key_bytes)};
     94 
     95  ScopedPK11SymKey key(PK11_ImportSymKey(slot.get(), cipher, PK11_OriginUnwrap,
     96                                         CKA_ENCRYPT, &keyItem, NULL));
     97  ASSERT_TRUE(key);
     98  ScopedSECItem param_item(PK11_ParamFromIV(cipher, param));
     99  ASSERT_TRUE(param_item);
    100  ScopedPK11Context ctx(PK11_CreateContextBySymKey(
    101      cipher, CKA_ENCRYPT, key.get(), param_item.get()));
    102  ASSERT_TRUE(ctx);
    103 
    104  ASSERT_EQ(GetBytes(ctx, 7), SECFailure);
    105 }
    106 
    107 TEST(Pkcs11CipherOp, ChachaMultiLegacy) {
    108  uint8_t iv_bytes[16];
    109  for (size_t i = 0; i < 16; i++) {
    110    iv_bytes[i] = i;
    111  }
    112  SECItem param_item = {siBuffer, iv_bytes, sizeof(iv_bytes)};
    113 
    114  ChachaMulti(CKM_NSS_CHACHA20_CTR, &param_item);
    115 }
    116 
    117 TEST(Pkcs11CipherOp, ChachaMulti) {
    118  uint8_t iv_bytes[16];
    119  for (size_t i = 0; i < 16; i++) {
    120    iv_bytes[i] = i;
    121  }
    122  CK_CHACHA20_PARAMS chacha_params = {iv_bytes, 32, iv_bytes + 4, 96};
    123  SECItem param_item = {siBuffer, reinterpret_cast<uint8_t*>(&chacha_params),
    124                        sizeof(chacha_params)};
    125 
    126  ChachaMulti(CKM_CHACHA20, &param_item);
    127 }
    128 
    129 }  // namespace nss_test