tor-browser

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

selfencrypt_unittest.cc (9423B)


      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 <functional>
      8 #include <memory>
      9 #include "nss.h"
     10 #include "pk11pub.h"
     11 #include "prerror.h"
     12 #include "secerr.h"
     13 #include "ssl.h"
     14 #include "sslerr.h"
     15 extern "C" {
     16 #include "sslimpl.h"
     17 #include "selfencrypt.h"
     18 }
     19 
     20 #include "databuffer.h"
     21 #include "gtest_utils.h"
     22 #include "nss_scoped_ptrs.h"
     23 
     24 namespace nss_test {
     25 
     26 static const uint8_t kAesKey1Buf[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
     27                                      0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
     28                                      0x0c, 0x0d, 0x0e, 0x0f};
     29 static const DataBuffer kAesKey1(kAesKey1Buf, sizeof(kAesKey1Buf));
     30 
     31 static const uint8_t kAesKey2Buf[] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
     32                                      0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
     33                                      0x1c, 0x1d, 0x1e, 0x1f};
     34 static const DataBuffer kAesKey2(kAesKey2Buf, sizeof(kAesKey2Buf));
     35 
     36 static const uint8_t kHmacKey1Buf[] = {
     37    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
     38    0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
     39    0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
     40 static const DataBuffer kHmacKey1(kHmacKey1Buf, sizeof(kHmacKey1Buf));
     41 
     42 static const uint8_t kHmacKey2Buf[] = {
     43    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
     44    0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
     45    0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f};
     46 static const DataBuffer kHmacKey2(kHmacKey2Buf, sizeof(kHmacKey2Buf));
     47 
     48 static const uint8_t* kKeyName1 =
     49    reinterpret_cast<const unsigned char*>("KEY1KEY1KEY1KEY1");
     50 static const uint8_t* kKeyName2 =
     51    reinterpret_cast<const uint8_t*>("KEY2KEY2KEY2KEY2");
     52 
     53 static void ImportKey(const DataBuffer& key, PK11SlotInfo* slot,
     54                      CK_MECHANISM_TYPE mech, CK_ATTRIBUTE_TYPE cka,
     55                      ScopedPK11SymKey* to) {
     56  SECItem key_item = {siBuffer, const_cast<uint8_t*>(key.data()),
     57                      static_cast<unsigned int>(key.len())};
     58 
     59  PK11SymKey* inner =
     60      PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, cka, &key_item, nullptr);
     61  ASSERT_NE(nullptr, inner);
     62  to->reset(inner);
     63 }
     64 
     65 extern "C" {
     66 extern char ssl_trace;
     67 extern FILE* ssl_trace_iob;
     68 }
     69 
     70 class SelfEncryptTestBase : public ::testing::Test {
     71 public:
     72  SelfEncryptTestBase(size_t message_size)
     73      : aes1_(),
     74        aes2_(),
     75        hmac1_(),
     76        hmac2_(),
     77        message_(),
     78        slot_(PK11_GetInternalSlot()) {
     79    EXPECT_NE(nullptr, slot_);
     80    char* ev = getenv("SSLTRACE");
     81    if (ev && ev[0]) {
     82      ssl_trace = atoi(ev);
     83      ssl_trace_iob = stderr;
     84    }
     85    message_.Allocate(message_size);
     86    for (size_t i = 0; i < message_.len(); ++i) {
     87      message_.data()[i] = i;
     88    }
     89  }
     90 
     91  void SetUp() {
     92    message_.Allocate(100);
     93    for (size_t i = 0; i < 100; ++i) {
     94      message_.data()[i] = i;
     95    }
     96    ImportKey(kAesKey1, slot_.get(), CKM_AES_CBC, CKA_ENCRYPT, &aes1_);
     97    ImportKey(kAesKey2, slot_.get(), CKM_AES_CBC, CKA_ENCRYPT, &aes2_);
     98    ImportKey(kHmacKey1, slot_.get(), CKM_SHA256_HMAC, CKA_SIGN, &hmac1_);
     99    ImportKey(kHmacKey2, slot_.get(), CKM_SHA256_HMAC, CKA_SIGN, &hmac2_);
    100  }
    101 
    102  void SelfTest(
    103      const uint8_t* writeKeyName, const ScopedPK11SymKey& writeAes,
    104      const ScopedPK11SymKey& writeHmac, const uint8_t* readKeyName,
    105      const ScopedPK11SymKey& readAes, const ScopedPK11SymKey& readHmac,
    106      PRErrorCode protect_error_code = 0, PRErrorCode unprotect_error_code = 0,
    107      std::function<void(uint8_t* ciphertext, unsigned int* ciphertext_len)>
    108          mutate = nullptr) {
    109    uint8_t ciphertext[1000];
    110    unsigned int ciphertext_len;
    111    uint8_t plaintext[1000];
    112    unsigned int plaintext_len;
    113 
    114    SECStatus rv = ssl_SelfEncryptProtectInt(
    115        writeAes.get(), writeHmac.get(), writeKeyName, message_.data(),
    116        message_.len(), ciphertext, &ciphertext_len, sizeof(ciphertext));
    117    if (rv != SECSuccess) {
    118      std::cerr << "Error: " << PORT_ErrorToName(PORT_GetError()) << std::endl;
    119    }
    120    if (protect_error_code) {
    121      ASSERT_EQ(protect_error_code, PORT_GetError());
    122      return;
    123    }
    124    ASSERT_EQ(SECSuccess, rv);
    125 
    126    if (mutate) {
    127      mutate(ciphertext, &ciphertext_len);
    128    }
    129    rv = ssl_SelfEncryptUnprotectInt(readAes.get(), readHmac.get(), readKeyName,
    130                                     ciphertext, ciphertext_len, plaintext,
    131                                     &plaintext_len, sizeof(plaintext));
    132    if (rv != SECSuccess) {
    133      std::cerr << "Error: " << PORT_ErrorToName(PORT_GetError()) << std::endl;
    134    }
    135    if (!unprotect_error_code) {
    136      ASSERT_EQ(SECSuccess, rv);
    137      EXPECT_EQ(message_.len(), plaintext_len);
    138      EXPECT_EQ(0, memcmp(message_.data(), plaintext, message_.len()));
    139    } else {
    140      ASSERT_EQ(SECFailure, rv);
    141      EXPECT_EQ(unprotect_error_code, PORT_GetError());
    142    }
    143  }
    144 
    145 protected:
    146  ScopedPK11SymKey aes1_;
    147  ScopedPK11SymKey aes2_;
    148  ScopedPK11SymKey hmac1_;
    149  ScopedPK11SymKey hmac2_;
    150  DataBuffer message_;
    151 
    152 private:
    153  ScopedPK11SlotInfo slot_;
    154 };
    155 
    156 class SelfEncryptTestVariable : public SelfEncryptTestBase,
    157                                public ::testing::WithParamInterface<size_t> {
    158 public:
    159  SelfEncryptTestVariable() : SelfEncryptTestBase(GetParam()) {}
    160 };
    161 
    162 class SelfEncryptTest128 : public SelfEncryptTestBase {
    163 public:
    164  SelfEncryptTest128() : SelfEncryptTestBase(128) {}
    165 };
    166 
    167 TEST_P(SelfEncryptTestVariable, SuccessCase) {
    168  SelfTest(kKeyName1, aes1_, hmac1_, kKeyName1, aes1_, hmac1_);
    169 }
    170 
    171 TEST_P(SelfEncryptTestVariable, WrongMacKey) {
    172  SelfTest(kKeyName1, aes1_, hmac1_, kKeyName1, aes1_, hmac2_, 0,
    173           SEC_ERROR_BAD_DATA);
    174 }
    175 
    176 TEST_P(SelfEncryptTestVariable, WrongKeyName) {
    177  SelfTest(kKeyName1, aes1_, hmac1_, kKeyName2, aes1_, hmac1_, 0,
    178           SEC_ERROR_NOT_A_RECIPIENT);
    179 }
    180 
    181 TEST_P(SelfEncryptTestVariable, AddAByte) {
    182  SelfTest(kKeyName1, aes1_, hmac1_, kKeyName1, aes1_, hmac1_, 0,
    183           SEC_ERROR_BAD_DATA,
    184           [](uint8_t* ciphertext, unsigned int* ciphertext_len) {
    185             (*ciphertext_len)++;
    186           });
    187 }
    188 
    189 TEST_P(SelfEncryptTestVariable, SubtractAByte) {
    190  SelfTest(kKeyName1, aes1_, hmac1_, kKeyName1, aes1_, hmac1_, 0,
    191           SEC_ERROR_BAD_DATA,
    192           [](uint8_t* ciphertext, unsigned int* ciphertext_len) {
    193             (*ciphertext_len)--;
    194           });
    195 }
    196 
    197 TEST_P(SelfEncryptTestVariable, BogusIv) {
    198  SelfTest(kKeyName1, aes1_, hmac1_, kKeyName1, aes1_, hmac1_, 0,
    199           SEC_ERROR_BAD_DATA,
    200           [](uint8_t* ciphertext, unsigned int* ciphertext_len) {
    201             ciphertext[16]++;
    202           });
    203 }
    204 
    205 TEST_P(SelfEncryptTestVariable, BogusCiphertext) {
    206  SelfTest(kKeyName1, aes1_, hmac1_, kKeyName1, aes1_, hmac1_, 0,
    207           SEC_ERROR_BAD_DATA,
    208           [](uint8_t* ciphertext, unsigned int* ciphertext_len) {
    209             ciphertext[32]++;
    210           });
    211 }
    212 
    213 TEST_P(SelfEncryptTestVariable, BadMac) {
    214  SelfTest(kKeyName1, aes1_, hmac1_, kKeyName1, aes1_, hmac1_, 0,
    215           SEC_ERROR_BAD_DATA,
    216           [](uint8_t* ciphertext, unsigned int* ciphertext_len) {
    217             ciphertext[*ciphertext_len - 1]++;
    218           });
    219 }
    220 
    221 TEST_F(SelfEncryptTest128, DISABLED_BadPadding) {
    222  SelfTest(kKeyName1, aes1_, hmac1_, kKeyName1, aes2_, hmac1_, 0,
    223           SEC_ERROR_BAD_DATA);
    224 }
    225 
    226 TEST_F(SelfEncryptTest128, ShortKeyName) {
    227  SelfTest(kKeyName1, aes1_, hmac1_, kKeyName1, aes1_, hmac1_, 0,
    228           SEC_ERROR_BAD_DATA,
    229           [](uint8_t* ciphertext, unsigned int* ciphertext_len) {
    230             *ciphertext_len = 15;
    231           });
    232 }
    233 
    234 TEST_F(SelfEncryptTest128, ShortIv) {
    235  SelfTest(kKeyName1, aes1_, hmac1_, kKeyName1, aes1_, hmac1_, 0,
    236           SEC_ERROR_BAD_DATA,
    237           [](uint8_t* ciphertext, unsigned int* ciphertext_len) {
    238             *ciphertext_len = 31;
    239           });
    240 }
    241 
    242 TEST_F(SelfEncryptTest128, ShortCiphertextLen) {
    243  SelfTest(kKeyName1, aes1_, hmac1_, kKeyName1, aes1_, hmac1_, 0,
    244           SEC_ERROR_BAD_DATA,
    245           [](uint8_t* ciphertext, unsigned int* ciphertext_len) {
    246             *ciphertext_len = 32;
    247           });
    248 }
    249 
    250 TEST_F(SelfEncryptTest128, ShortCiphertext) {
    251  SelfTest(kKeyName1, aes1_, hmac1_, kKeyName1, aes1_, hmac1_, 0,
    252           SEC_ERROR_BAD_DATA,
    253           [](uint8_t* ciphertext, unsigned int* ciphertext_len) {
    254             *ciphertext_len -= 17;
    255           });
    256 }
    257 
    258 TEST_F(SelfEncryptTest128, MacWithAESKeyEncrypt) {
    259  SelfTest(kKeyName1, aes1_, aes1_, kKeyName1, aes1_, hmac1_,
    260           SEC_ERROR_LIBRARY_FAILURE);
    261 }
    262 
    263 TEST_F(SelfEncryptTest128, AESWithMacKeyEncrypt) {
    264  SelfTest(kKeyName1, hmac1_, hmac1_, kKeyName1, aes1_, hmac1_,
    265           SEC_ERROR_INVALID_KEY);
    266 }
    267 
    268 TEST_F(SelfEncryptTest128, MacWithAESKeyDecrypt) {
    269  SelfTest(kKeyName1, aes1_, hmac1_, kKeyName1, aes1_, aes1_, 0,
    270           SEC_ERROR_LIBRARY_FAILURE);
    271 }
    272 
    273 TEST_F(SelfEncryptTest128, AESWithMacKeyDecrypt) {
    274  SelfTest(kKeyName1, aes1_, hmac1_, kKeyName1, hmac1_, hmac1_, 0,
    275           SEC_ERROR_INVALID_KEY);
    276 }
    277 
    278 INSTANTIATE_TEST_SUITE_P(VariousSizes, SelfEncryptTestVariable,
    279                         ::testing::Values(0, 15, 16, 31, 255, 256, 257));
    280 
    281 }  // namespace nss_test