tor-browser

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

blake2b_unittest.cc (9831B)


      1 /*
      2 * blake2b_unittest.cc - unittests for blake2b hash function
      3 *
      4 * This Source Code Form is subject to the terms of the Mozilla Public
      5 * License, v. 2.0. If a copy of the MPL was not distributed with this
      6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      7 
      8 #include "blapi.h"
      9 #include "nspr.h"
     10 #include "nss.h"
     11 #include "secerr.h"
     12 
     13 #include <cstdlib>
     14 #include <iostream>
     15 #include <memory>
     16 
     17 #define GTEST_HAS_RTTI 0
     18 #include "gtest/gtest.h"
     19 
     20 #include "kat/blake2b_kat.h"
     21 
     22 template <class T>
     23 struct ScopedDelete {
     24  void operator()(T* ptr) {
     25    if (ptr) {
     26      BLAKE2B_DestroyContext(ptr, PR_TRUE);
     27    }
     28  }
     29 };
     30 
     31 typedef std::unique_ptr<BLAKE2BContext, ScopedDelete<BLAKE2BContext>>
     32    ScopedBLAKE2BContext;
     33 
     34 class Blake2BTests : public ::testing::Test {};
     35 
     36 class Blake2BKAT
     37    : public ::testing::TestWithParam<std::pair<int, std::vector<uint8_t>>> {};
     38 
     39 class Blake2BKATUnkeyed : public Blake2BKAT {};
     40 class Blake2BKATKeyed : public Blake2BKAT {};
     41 
     42 TEST_P(Blake2BKATUnkeyed, Unkeyed) {
     43  std::vector<uint8_t> values(BLAKE2B512_LENGTH);
     44  SECStatus rv =
     45      BLAKE2B_HashBuf(values.data(), kat_data.data(), std::get<0>(GetParam()));
     46  ASSERT_EQ(SECSuccess, rv);
     47  EXPECT_EQ(values, std::get<1>(GetParam()));
     48 }
     49 
     50 TEST_P(Blake2BKATKeyed, Keyed) {
     51  std::vector<uint8_t> values(BLAKE2B512_LENGTH);
     52  SECStatus rv = BLAKE2B_MAC_HashBuf(values.data(), kat_data.data(),
     53                                     std::get<0>(GetParam()), kat_key.data(),
     54                                     BLAKE2B_KEY_SIZE);
     55  ASSERT_EQ(SECSuccess, rv);
     56  EXPECT_EQ(values, std::get<1>(GetParam()));
     57 }
     58 
     59 INSTANTIATE_TEST_SUITE_P(UnkeyedKAT, Blake2BKATUnkeyed,
     60                         ::testing::ValuesIn(TestcasesUnkeyed));
     61 INSTANTIATE_TEST_SUITE_P(KeyedKAT, Blake2BKATKeyed,
     62                         ::testing::ValuesIn(TestcasesKeyed));
     63 
     64 TEST_F(Blake2BTests, ContextTest) {
     65  ScopedBLAKE2BContext ctx(BLAKE2B_NewContext());
     66  ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!";
     67 
     68  SECStatus rv = BLAKE2B_Begin(ctx.get());
     69  ASSERT_EQ(SECSuccess, rv);
     70 
     71  size_t src_length = 252;
     72  const size_t quarter = 63;
     73 
     74  for (int i = 0; i < 4 && src_length > 0; i++) {
     75    rv = BLAKE2B_Update(ctx.get(), kat_data.data() + i * quarter,
     76                        PR_MIN(quarter, src_length));
     77    ASSERT_EQ(SECSuccess, rv);
     78 
     79    size_t len = BLAKE2B_FlattenSize(ctx.get());
     80    std::vector<unsigned char> ctxbytes(len);
     81    rv = BLAKE2B_Flatten(ctx.get(), ctxbytes.data());
     82    ASSERT_EQ(SECSuccess, rv);
     83    ScopedBLAKE2BContext ctx_cpy(BLAKE2B_Resurrect(ctxbytes.data(), NULL));
     84    ASSERT_TRUE(ctx_cpy) << "BLAKE2B_Resurrect failed!";
     85    ASSERT_EQ(SECSuccess, PORT_Memcmp(ctx.get(), ctx_cpy.get(), len));
     86    src_length -= quarter;
     87  }
     88  ASSERT_EQ(0U, src_length);
     89 
     90  std::vector<uint8_t> digest(BLAKE2B512_LENGTH);
     91  rv = BLAKE2B_End(ctx.get(), digest.data(), nullptr, BLAKE2B512_LENGTH);
     92  ASSERT_EQ(SECSuccess, rv);
     93  ASSERT_EQ(std::get<1>(TestcasesUnkeyed[252]), digest)
     94      << "BLAKE2B_End failed!";
     95 }
     96 
     97 TEST_F(Blake2BTests, ContextTest2) {
     98  ScopedBLAKE2BContext ctx(BLAKE2B_NewContext());
     99  ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!";
    100 
    101  SECStatus rv = BLAKE2B_Begin(ctx.get());
    102  ASSERT_EQ(SECSuccess, rv);
    103 
    104  rv = BLAKE2B_Update(ctx.get(), kat_data.data(), 128);
    105  ASSERT_EQ(SECSuccess, rv);
    106  rv = BLAKE2B_Update(ctx.get(), kat_data.data() + 128, 127);
    107  ASSERT_EQ(SECSuccess, rv);
    108 
    109  std::vector<uint8_t> digest(BLAKE2B512_LENGTH);
    110  rv = BLAKE2B_End(ctx.get(), digest.data(), nullptr, BLAKE2B512_LENGTH);
    111  ASSERT_EQ(SECSuccess, rv);
    112  ASSERT_EQ(std::get<1>(TestcasesUnkeyed[255]), digest)
    113      << "BLAKE2B_End failed!";
    114 }
    115 
    116 TEST_F(Blake2BTests, NullContextTest) {
    117  SECStatus rv = BLAKE2B_Begin(nullptr);
    118  ASSERT_EQ(SECFailure, rv);
    119 
    120  rv = BLAKE2B_Update(nullptr, kat_data.data(), 128);
    121  ASSERT_EQ(SECFailure, rv);
    122 
    123  std::vector<uint8_t> digest(BLAKE2B512_LENGTH);
    124  rv = BLAKE2B_End(nullptr, digest.data(), nullptr, BLAKE2B512_LENGTH);
    125  ASSERT_EQ(SECFailure, rv);
    126 }
    127 
    128 TEST_F(Blake2BTests, CloneTest) {
    129  ScopedBLAKE2BContext ctx(BLAKE2B_NewContext());
    130  ScopedBLAKE2BContext cloned_ctx(BLAKE2B_NewContext());
    131  ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!";
    132  ASSERT_TRUE(cloned_ctx) << "BLAKE2B_NewContext failed!";
    133 
    134  SECStatus rv = BLAKE2B_Begin(ctx.get());
    135  ASSERT_EQ(SECSuccess, rv);
    136  rv = BLAKE2B_Update(ctx.get(), kat_data.data(), 255);
    137  ASSERT_EQ(SECSuccess, rv);
    138  BLAKE2B_Clone(cloned_ctx.get(), ctx.get());
    139 
    140  std::vector<uint8_t> digest(BLAKE2B512_LENGTH);
    141  rv = BLAKE2B_End(cloned_ctx.get(), digest.data(), nullptr, BLAKE2B512_LENGTH);
    142  ASSERT_EQ(SECSuccess, rv);
    143  ASSERT_EQ(std::get<1>(TestcasesUnkeyed[255]), digest)
    144      << "BLAKE2B_End failed!";
    145 }
    146 
    147 TEST_F(Blake2BTests, NullTest) {
    148  std::vector<uint8_t> digest(BLAKE2B512_LENGTH);
    149  SECStatus rv = BLAKE2B_HashBuf(digest.data(), nullptr, 0);
    150  ASSERT_EQ(SECSuccess, rv);
    151  EXPECT_EQ(std::get<1>(TestcasesUnkeyed[0]), digest);
    152 
    153  digest = std::vector<uint8_t>(BLAKE2B512_LENGTH);
    154  rv = BLAKE2B_MAC_HashBuf(digest.data(), nullptr, 0, kat_key.data(),
    155                           BLAKE2B_KEY_SIZE);
    156  ASSERT_EQ(SECSuccess, rv);
    157  EXPECT_EQ(std::get<1>(TestcasesKeyed[0]), digest);
    158 }
    159 
    160 TEST_F(Blake2BTests, HashTest) {
    161  ScopedBLAKE2BContext ctx(BLAKE2B_NewContext());
    162  ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!";
    163 
    164  std::vector<uint8_t> digest(BLAKE2B512_LENGTH);
    165  SECStatus rv = BLAKE2B_Hash(digest.data(), "abc");
    166  std::vector<uint8_t> expected = {
    167      0xba, 0x80, 0xa5, 0x3f, 0x98, 0x1c, 0x4d, 0x0d, 0x6a, 0x27, 0x97,
    168      0xb6, 0x9f, 0x12, 0xf6, 0xe9, 0x4c, 0x21, 0x2f, 0x14, 0x68, 0x5a,
    169      0xc4, 0xb7, 0x4b, 0x12, 0xbb, 0x6f, 0xdb, 0xff, 0xa2, 0xd1, 0x7d,
    170      0x87, 0xc5, 0x39, 0x2a, 0xab, 0x79, 0x2d, 0xc2, 0x52, 0xd5, 0xde,
    171      0x45, 0x33, 0xcc, 0x95, 0x18, 0xd3, 0x8a, 0xa8, 0xdb, 0xf1, 0x92,
    172      0x5a, 0xb9, 0x23, 0x86, 0xed, 0xd4, 0x00, 0x99, 0x23};
    173  ASSERT_EQ(SECSuccess, rv);
    174  EXPECT_EQ(expected, digest);
    175 }
    176 
    177 TEST_F(Blake2BTests, LongHashTest) {
    178  ScopedBLAKE2BContext ctx(BLAKE2B_NewContext());
    179  ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!";
    180 
    181  std::vector<uint8_t> digest(BLAKE2B512_LENGTH);
    182  SECStatus rv = BLAKE2B_Hash(
    183      digest.data(),
    184      "qwertzuiopasdfghjklyxcvbnm123456789qwertzuiopasdfghjklyxcvbnm123456789qw"
    185      "ertzuiopasdfghjklyxcvbnm123456789qwertzuiopasdfghjklyxcvbnm123456789qwer"
    186      "tzuiopasdfghjklyxcvbnm123456789qwertzuiopasdfghjklyxcvbnm123456789qwertz"
    187      "uiopasdfghjklyxcvbnm123456789qwertzuiopasdfghjklyxcvbnm123456789");
    188  std::vector<uint8_t> expected = {
    189      0x1f, 0x9e, 0xe6, 0x5a, 0xa0, 0x36, 0x05, 0xfc, 0x41, 0x0e, 0x2f,
    190      0x55, 0x96, 0xfd, 0xb5, 0x9d, 0x85, 0x95, 0x5e, 0x24, 0x37, 0xe7,
    191      0x0d, 0xe4, 0xa0, 0x22, 0x4a, 0xe1, 0x59, 0x1f, 0x97, 0x03, 0x57,
    192      0x54, 0xf0, 0xca, 0x92, 0x75, 0x2f, 0x9e, 0x86, 0xeb, 0x82, 0x4f,
    193      0x9c, 0xf4, 0x02, 0x17, 0x7f, 0x76, 0x56, 0x26, 0x46, 0xf4, 0x07,
    194      0xfd, 0x1f, 0x78, 0xdb, 0x7b, 0x0d, 0x24, 0x43, 0xf0};
    195  ASSERT_EQ(SECSuccess, rv);
    196  EXPECT_EQ(expected, digest);
    197 }
    198 
    199 TEST_F(Blake2BTests, TruncatedHashTest) {
    200  ScopedBLAKE2BContext ctx(BLAKE2B_NewContext());
    201  ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!";
    202 
    203  SECStatus rv = BLAKE2B_Begin(ctx.get());
    204  ASSERT_EQ(SECSuccess, rv);
    205 
    206  rv = BLAKE2B_Update(ctx.get(), kat_data.data(), 128);
    207  ASSERT_EQ(SECSuccess, rv);
    208  rv = BLAKE2B_Update(ctx.get(), kat_data.data() + 128, 127);
    209  ASSERT_EQ(SECSuccess, rv);
    210 
    211  size_t max_digest_len = BLAKE2B512_LENGTH - 5;
    212  std::vector<uint8_t> digest(max_digest_len);
    213  unsigned int digest_len;
    214  rv = BLAKE2B_End(ctx.get(), digest.data(), &digest_len, max_digest_len);
    215  ASSERT_EQ(SECSuccess, rv);
    216  ASSERT_EQ(digest.size(), digest_len);
    217  ASSERT_EQ(0, memcmp(std::get<1>(TestcasesUnkeyed[255]).data(), digest.data(),
    218                      max_digest_len))
    219      << "BLAKE2B_End failed!";
    220 }
    221 
    222 TEST_F(Blake2BTests, TruncatedHashTest2) {
    223  ScopedBLAKE2BContext ctx(BLAKE2B_NewContext());
    224  ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!";
    225 
    226  SECStatus rv = BLAKE2B_Begin(ctx.get());
    227  ASSERT_EQ(SECSuccess, rv);
    228 
    229  rv = BLAKE2B_Update(ctx.get(), kat_data.data(), 128);
    230  ASSERT_EQ(SECSuccess, rv);
    231  rv = BLAKE2B_Update(ctx.get(), kat_data.data() + 128, 127);
    232  ASSERT_EQ(SECSuccess, rv);
    233 
    234  size_t max_digest_len = BLAKE2B512_LENGTH - 60;
    235  std::vector<uint8_t> digest(max_digest_len);
    236  unsigned int digest_len;
    237  rv = BLAKE2B_End(ctx.get(), digest.data(), &digest_len, max_digest_len);
    238  ASSERT_EQ(SECSuccess, rv);
    239  ASSERT_EQ(digest.size(), digest_len);
    240 }
    241 
    242 TEST_F(Blake2BTests, OverlongKeyTest) {
    243  ScopedBLAKE2BContext ctx(BLAKE2B_NewContext());
    244  ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!";
    245 
    246  std::vector<uint8_t> key = {
    247      0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
    248      0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32,
    249      0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
    250      0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34,
    251      0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
    252      0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35};
    253  std::vector<uint8_t> data = {0x61, 0x62, 0x63};
    254 
    255  std::vector<uint8_t> digest(BLAKE2B512_LENGTH);
    256  SECStatus rv =
    257      BLAKE2B_MAC_HashBuf(digest.data(), data.data(), 3, key.data(), 65);
    258  EXPECT_EQ(SECFailure, rv);
    259  EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError());
    260 }
    261 
    262 TEST_F(Blake2BTests, EmptyKeyTest) {
    263  ScopedBLAKE2BContext ctx(BLAKE2B_NewContext());
    264  ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!";
    265 
    266  uint8_t key[1];  // A vector.data() would give us a nullptr.
    267  std::vector<uint8_t> data = {0x61, 0x62, 0x63};
    268 
    269  std::vector<uint8_t> digest(BLAKE2B512_LENGTH);
    270  SECStatus rv = BLAKE2B_MAC_HashBuf(digest.data(), data.data(), 3, key, 0);
    271  EXPECT_EQ(SECFailure, rv);
    272  EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError());
    273 }