Home | History | Annotate | Download | only in crypto
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <string>
      6 
      7 #include "crypto/hmac.h"
      8 #include "testing/gtest/include/gtest/gtest.h"
      9 
     10 static const int kSHA1DigestSize = 20;
     11 static const int kSHA256DigestSize = 32;
     12 
     13 TEST(HMACTest, HmacSafeBrowsingResponseTest) {
     14   const int kKeySize = 16;
     15 
     16   // Client key.
     17   const unsigned char kClientKey[kKeySize] =
     18       { 0xbf, 0xf6, 0x83, 0x4b, 0x3e, 0xa3, 0x23, 0xdd,
     19         0x96, 0x78, 0x70, 0x8e, 0xa1, 0x9d, 0x3b, 0x40 };
     20 
     21   // Expected HMAC result using kMessage and kClientKey.
     22   const unsigned char kReceivedHmac[kSHA1DigestSize] =
     23       { 0xb9, 0x3c, 0xd6, 0xf0, 0x49, 0x47, 0xe2, 0x52,
     24         0x59, 0x7a, 0xbd, 0x1f, 0x2b, 0x4c, 0x83, 0xad,
     25         0x86, 0xd2, 0x48, 0x85 };
     26 
     27   const char kMessage[] =
     28 "n:1896\ni:goog-malware-shavar\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shav"
     29 "ar_s_445-450\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_439-444\nu:s"
     30 ".ytimg.com/safebrowsing/rd/goog-malware-shavar_s_437\nu:s.ytimg.com/safebrowsi"
     31 "ng/rd/goog-malware-shavar_s_436\nu:s.ytimg.com/safebrowsing/rd/goog-malware-sh"
     32 "avar_s_433-435\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_431\nu:s.y"
     33 "timg.com/safebrowsing/rd/goog-malware-shavar_s_430\nu:s.ytimg.com/safebrowsing"
     34 "/rd/goog-malware-shavar_s_429\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shav"
     35 "ar_s_428\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_426\nu:s.ytimg.c"
     36 "om/safebrowsing/rd/goog-malware-shavar_s_424\nu:s.ytimg.com/safebrowsing/rd/go"
     37 "og-malware-shavar_s_423\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_4"
     38 "22\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_420\nu:s.ytimg.com/saf"
     39 "ebrowsing/rd/goog-malware-shavar_s_419\nu:s.ytimg.com/safebrowsing/rd/goog-mal"
     40 "ware-shavar_s_414\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_409-411"
     41 "\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_405\nu:s.ytimg.com/safeb"
     42 "rowsing/rd/goog-malware-shavar_s_404\nu:s.ytimg.com/safebrowsing/rd/goog-malwa"
     43 "re-shavar_s_402\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_401\nu:s."
     44 "ytimg.com/safebrowsing/rd/goog-malware-shavar_a_973-978\nu:s.ytimg.com/safebro"
     45 "wsing/rd/goog-malware-shavar_a_937-972\nu:s.ytimg.com/safebrowsing/rd/goog-mal"
     46 "ware-shavar_a_931-936\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_a_925"
     47 "-930\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_a_919-924\ni:goog-phis"
     48 "h-shavar\nu:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_2633\nu:s.ytimg.co"
     49 "m/safebrowsing/rd/goog-phish-shavar_a_2632\nu:s.ytimg.com/safebrowsing/rd/goog"
     50 "-phish-shavar_a_2629-2631\nu:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_2"
     51 "626-2628\nu:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_2625\n";
     52 
     53   std::string message_data(kMessage);
     54 
     55   crypto::HMAC hmac(crypto::HMAC::SHA1);
     56   ASSERT_TRUE(hmac.Init(kClientKey, kKeySize));
     57   unsigned char calculated_hmac[kSHA1DigestSize];
     58 
     59   EXPECT_TRUE(hmac.Sign(message_data, calculated_hmac, kSHA1DigestSize));
     60   EXPECT_EQ(0, memcmp(kReceivedHmac, calculated_hmac, kSHA1DigestSize));
     61 }
     62 
     63 // Test cases from RFC 2202 section 3
     64 TEST(HMACTest, RFC2202TestCases) {
     65   const struct {
     66     const char *key;
     67     const int key_len;
     68     const char *data;
     69     const int data_len;
     70     const char *digest;
     71   } cases[] = {
     72     { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
     73           "\x0B\x0B\x0B\x0B", 20,
     74       "Hi There", 8,
     75       "\xB6\x17\x31\x86\x55\x05\x72\x64\xE2\x8B\xC0\xB6\xFB\x37\x8C\x8E"
     76           "\xF1\x46\xBE\x00" },
     77     { "Jefe", 4,
     78       "what do ya want for nothing?", 28,
     79       "\xEF\xFC\xDF\x6A\xE5\xEB\x2F\xA2\xD2\x74\x16\xD5\xF1\x84\xDF\x9C"
     80           "\x25\x9A\x7C\x79" },
     81     { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
     82           "\xAA\xAA\xAA\xAA", 20,
     83       "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
     84           "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
     85           "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
     86           "\xDD\xDD", 50,
     87       "\x12\x5D\x73\x42\xB9\xAC\x11\xCD\x91\xA3\x9A\xF4\x8A\xA1\x7B\x4F"
     88           "\x63\xF1\x75\xD3" },
     89     { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
     90           "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
     91       "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
     92           "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
     93           "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
     94           "\xCD\xCD", 50,
     95       "\x4C\x90\x07\xF4\x02\x62\x50\xC6\xBC\x84\x14\xF9\xBF\x50\xC8\x6C"
     96           "\x2D\x72\x35\xDA" },
     97     { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
     98           "\x0C\x0C\x0C\x0C", 20,
     99       "Test With Truncation", 20,
    100       "\x4C\x1A\x03\x42\x4B\x55\xE0\x7F\xE7\xF2\x7B\xE1\xD5\x8B\xB9\x32"
    101           "\x4A\x9A\x5A\x04" },
    102     { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    103           "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    104           "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    105           "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    106           "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
    107       80,
    108       "Test Using Larger Than Block-Size Key - Hash Key First", 54,
    109       "\xAA\x4A\xE5\xE1\x52\x72\xD0\x0E\x95\x70\x56\x37\xCE\x8A\x3B\x55"
    110           "\xED\x40\x21\x12" },
    111     { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    112           "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    113           "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    114           "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    115           "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
    116       80,
    117       "Test Using Larger Than Block-Size Key and Larger "
    118           "Than One Block-Size Data", 73,
    119       "\xE8\xE9\x9D\x0F\x45\x23\x7D\x78\x6D\x6B\xBA\xA7\x96\x5C\x78\x08"
    120           "\xBB\xFF\x1A\x91" }
    121   };
    122 
    123   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
    124     crypto::HMAC hmac(crypto::HMAC::SHA1);
    125     ASSERT_TRUE(hmac.Init(reinterpret_cast<const unsigned char*>(cases[i].key),
    126                           cases[i].key_len));
    127     std::string data_string(cases[i].data, cases[i].data_len);
    128     unsigned char digest[kSHA1DigestSize];
    129     EXPECT_TRUE(hmac.Sign(data_string, digest, kSHA1DigestSize));
    130     EXPECT_EQ(0, memcmp(cases[i].digest, digest, kSHA1DigestSize));
    131   }
    132 }
    133 
    134 // TODO(wtc): add other test vectors from RFC 4231.
    135 TEST(HMACTest, RFC4231TestCase6) {
    136   unsigned char key[131];
    137   for (size_t i = 0; i < sizeof(key); ++i)
    138     key[i] = 0xaa;
    139 
    140   std::string data = "Test Using Larger Than Block-Size Key - Hash Key First";
    141   ASSERT_EQ(54U, data.size());
    142 
    143   static unsigned char kKnownHMACSHA256[] = {
    144     0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f,
    145     0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f,
    146     0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14,
    147     0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54
    148   };
    149 
    150   crypto::HMAC hmac(crypto::HMAC::SHA256);
    151   ASSERT_TRUE(hmac.Init(key, sizeof(key)));
    152   unsigned char calculated_hmac[kSHA256DigestSize];
    153 
    154   EXPECT_TRUE(hmac.Sign(data, calculated_hmac, kSHA256DigestSize));
    155   EXPECT_EQ(0, memcmp(kKnownHMACSHA256, calculated_hmac, kSHA256DigestSize));
    156 }
    157 
    158 // Based on NSS's FIPS HMAC power-up self-test.
    159 TEST(HMACTest, NSSFIPSPowerUpSelfTest) {
    160   static const char kKnownMessage[] =
    161       "The test message for the MD2, MD5, and SHA-1 hashing algorithms.";
    162 
    163   static const unsigned char kKnownSecretKey[] = {
    164     0x46, 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, 0x20,
    165     0x61, 0x6e, 0x64, 0x20, 0x54, 0x68, 0x75, 0x6e,
    166     0x64, 0x65, 0x72, 0x42, 0x69, 0x72, 0x64, 0x20,
    167     0x61, 0x72, 0x65, 0x20, 0x61, 0x77, 0x65, 0x73,
    168     0x6f, 0x6d, 0x65, 0x21, 0x00
    169   };
    170 
    171   static const size_t kKnownSecretKeySize = sizeof(kKnownSecretKey);
    172 
    173   // HMAC-SHA-1 known answer (20 bytes).
    174   static const unsigned char kKnownHMACSHA1[] = {
    175     0xd5, 0x85, 0xf6, 0x5b, 0x39, 0xfa, 0xb9, 0x05,
    176     0x3b, 0x57, 0x1d, 0x61, 0xe7, 0xb8, 0x84, 0x1e,
    177     0x5d, 0x0e, 0x1e, 0x11
    178   };
    179 
    180   // HMAC-SHA-256 known answer (32 bytes).
    181   static const unsigned char kKnownHMACSHA256[] = {
    182     0x05, 0x75, 0x9a, 0x9e, 0x70, 0x5e, 0xe7, 0x44,
    183     0xe2, 0x46, 0x4b, 0x92, 0x22, 0x14, 0x22, 0xe0,
    184     0x1b, 0x92, 0x8a, 0x0c, 0xfe, 0xf5, 0x49, 0xe9,
    185     0xa7, 0x1b, 0x56, 0x7d, 0x1d, 0x29, 0x40, 0x48
    186   };
    187 
    188   std::string message_data(kKnownMessage);
    189 
    190   crypto::HMAC hmac(crypto::HMAC::SHA1);
    191   ASSERT_TRUE(hmac.Init(kKnownSecretKey, kKnownSecretKeySize));
    192   unsigned char calculated_hmac[kSHA1DigestSize];
    193 
    194   EXPECT_TRUE(hmac.Sign(message_data, calculated_hmac, kSHA1DigestSize));
    195   EXPECT_EQ(0, memcmp(kKnownHMACSHA1, calculated_hmac, kSHA1DigestSize));
    196 
    197   crypto::HMAC hmac2(crypto::HMAC::SHA256);
    198   ASSERT_TRUE(hmac2.Init(kKnownSecretKey, kKnownSecretKeySize));
    199   unsigned char calculated_hmac2[kSHA256DigestSize];
    200 
    201   EXPECT_TRUE(hmac2.Sign(message_data, calculated_hmac2, kSHA256DigestSize));
    202   EXPECT_EQ(0, memcmp(kKnownHMACSHA256, calculated_hmac2, kSHA256DigestSize));
    203 }
    204 
    205 TEST(HMACTest, HMACObjectReuse) {
    206   const char *key =
    207       "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    208       "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    209       "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    210       "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
    211       "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA";
    212   const int key_len = 80;
    213 
    214   const struct {
    215     const char *data;
    216     const int data_len;
    217     const char *digest;
    218   } cases[] = {
    219     { "Test Using Larger Than Block-Size Key - Hash Key First", 54,
    220       "\xAA\x4A\xE5\xE1\x52\x72\xD0\x0E\x95\x70\x56\x37\xCE\x8A\x3B\x55"
    221           "\xED\x40\x21\x12" },
    222     { "Test Using Larger Than Block-Size Key and Larger "
    223           "Than One Block-Size Data", 73,
    224       "\xE8\xE9\x9D\x0F\x45\x23\x7D\x78\x6D\x6B\xBA\xA7\x96\x5C\x78\x08"
    225           "\xBB\xFF\x1A\x91" }
    226   };
    227 
    228   crypto::HMAC hmac(crypto::HMAC::SHA1);
    229   ASSERT_TRUE(hmac.Init(reinterpret_cast<const unsigned char*>(key), key_len));
    230   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
    231     std::string data_string(cases[i].data, cases[i].data_len);
    232     unsigned char digest[kSHA1DigestSize];
    233     EXPECT_TRUE(hmac.Sign(data_string, digest, kSHA1DigestSize));
    234     EXPECT_EQ(0, memcmp(cases[i].digest, digest, kSHA1DigestSize));
    235   }
    236 }
    237