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