Home | History | Annotate | Download | only in base
      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 "base/md5.h"
      6 
      7 #include <string.h>
      8 
      9 #include <memory>
     10 #include <string>
     11 
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 namespace base {
     15 
     16 TEST(MD5, DigestToBase16) {
     17   MD5Digest digest;
     18 
     19   int data[] = {
     20     0xd4, 0x1d, 0x8c, 0xd9,
     21     0x8f, 0x00, 0xb2, 0x04,
     22     0xe9, 0x80, 0x09, 0x98,
     23     0xec, 0xf8, 0x42, 0x7e
     24   };
     25 
     26   for (int i = 0; i < 16; ++i)
     27     digest.a[i] = data[i] & 0xff;
     28 
     29   std::string actual = MD5DigestToBase16(digest);
     30   std::string expected = "d41d8cd98f00b204e9800998ecf8427e";
     31 
     32   EXPECT_EQ(expected, actual);
     33 }
     34 
     35 TEST(MD5, MD5SumEmtpyData) {
     36   MD5Digest digest;
     37   const char data[] = "";
     38 
     39   MD5Sum(data, strlen(data), &digest);
     40 
     41   int expected[] = {
     42     0xd4, 0x1d, 0x8c, 0xd9,
     43     0x8f, 0x00, 0xb2, 0x04,
     44     0xe9, 0x80, 0x09, 0x98,
     45     0xec, 0xf8, 0x42, 0x7e
     46   };
     47 
     48   for (int i = 0; i < 16; ++i)
     49     EXPECT_EQ(expected[i], digest.a[i] & 0xFF);
     50 }
     51 
     52 TEST(MD5, MD5SumOneByteData) {
     53   MD5Digest digest;
     54   const char data[] = "a";
     55 
     56   MD5Sum(data, strlen(data), &digest);
     57 
     58   int expected[] = {
     59     0x0c, 0xc1, 0x75, 0xb9,
     60     0xc0, 0xf1, 0xb6, 0xa8,
     61     0x31, 0xc3, 0x99, 0xe2,
     62     0x69, 0x77, 0x26, 0x61
     63   };
     64 
     65   for (int i = 0; i < 16; ++i)
     66     EXPECT_EQ(expected[i], digest.a[i] & 0xFF);
     67 }
     68 
     69 TEST(MD5, MD5SumLongData) {
     70   const int length = 10 * 1024 * 1024 + 1;
     71   std::unique_ptr<char[]> data(new char[length]);
     72 
     73   for (int i = 0; i < length; ++i)
     74     data[i] = i & 0xFF;
     75 
     76   MD5Digest digest;
     77   MD5Sum(data.get(), length, &digest);
     78 
     79   int expected[] = {
     80     0x90, 0xbd, 0x6a, 0xd9,
     81     0x0a, 0xce, 0xf5, 0xad,
     82     0xaa, 0x92, 0x20, 0x3e,
     83     0x21, 0xc7, 0xa1, 0x3e
     84   };
     85 
     86   for (int i = 0; i < 16; ++i)
     87     EXPECT_EQ(expected[i], digest.a[i] & 0xFF);
     88 }
     89 
     90 TEST(MD5, ContextWithEmptyData) {
     91   MD5Context ctx;
     92   MD5Init(&ctx);
     93 
     94   MD5Digest digest;
     95   MD5Final(&digest, &ctx);
     96 
     97   int expected[] = {
     98     0xd4, 0x1d, 0x8c, 0xd9,
     99     0x8f, 0x00, 0xb2, 0x04,
    100     0xe9, 0x80, 0x09, 0x98,
    101     0xec, 0xf8, 0x42, 0x7e
    102   };
    103 
    104   for (int i = 0; i < 16; ++i)
    105     EXPECT_EQ(expected[i], digest.a[i] & 0xFF);
    106 }
    107 
    108 TEST(MD5, ContextWithLongData) {
    109   MD5Context ctx;
    110   MD5Init(&ctx);
    111 
    112   const int length = 10 * 1024 * 1024 + 1;
    113   std::unique_ptr<char[]> data(new char[length]);
    114 
    115   for (int i = 0; i < length; ++i)
    116     data[i] = i & 0xFF;
    117 
    118   int total = 0;
    119   while (total < length) {
    120     int len = 4097;  // intentionally not 2^k.
    121     if (len > length - total)
    122       len = length - total;
    123 
    124     MD5Update(&ctx,
    125               StringPiece(reinterpret_cast<char*>(data.get() + total), len));
    126     total += len;
    127   }
    128 
    129   EXPECT_EQ(length, total);
    130 
    131   MD5Digest digest;
    132   MD5Final(&digest, &ctx);
    133 
    134   int expected[] = {
    135     0x90, 0xbd, 0x6a, 0xd9,
    136     0x0a, 0xce, 0xf5, 0xad,
    137     0xaa, 0x92, 0x20, 0x3e,
    138     0x21, 0xc7, 0xa1, 0x3e
    139   };
    140 
    141   for (int i = 0; i < 16; ++i)
    142     EXPECT_EQ(expected[i], digest.a[i] & 0xFF);
    143 }
    144 
    145 // Example data from http://www.ietf.org/rfc/rfc1321.txt A.5 Test Suite
    146 TEST(MD5, MD5StringTestSuite1) {
    147   std::string actual = MD5String("");
    148   std::string expected = "d41d8cd98f00b204e9800998ecf8427e";
    149   EXPECT_EQ(expected, actual);
    150 }
    151 
    152 TEST(MD5, MD5StringTestSuite2) {
    153   std::string actual = MD5String("a");
    154   std::string expected = "0cc175b9c0f1b6a831c399e269772661";
    155   EXPECT_EQ(expected, actual);
    156 }
    157 
    158 TEST(MD5, MD5StringTestSuite3) {
    159   std::string actual = MD5String("abc");
    160   std::string expected = "900150983cd24fb0d6963f7d28e17f72";
    161   EXPECT_EQ(expected, actual);
    162 }
    163 
    164 TEST(MD5, MD5StringTestSuite4) {
    165   std::string actual = MD5String("message digest");
    166   std::string expected = "f96b697d7cb7938d525a2f31aaf161d0";
    167   EXPECT_EQ(expected, actual);
    168 }
    169 
    170 TEST(MD5, MD5StringTestSuite5) {
    171   std::string actual = MD5String("abcdefghijklmnopqrstuvwxyz");
    172   std::string expected = "c3fcd3d76192e4007dfb496cca67e13b";
    173   EXPECT_EQ(expected, actual);
    174 }
    175 
    176 TEST(MD5, MD5StringTestSuite6) {
    177   std::string actual = MD5String("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    178                                  "abcdefghijklmnopqrstuvwxyz"
    179                                  "0123456789");
    180   std::string expected = "d174ab98d277d9f5a5611c2c9f419d9f";
    181   EXPECT_EQ(expected, actual);
    182 }
    183 
    184 TEST(MD5, MD5StringTestSuite7) {
    185   std::string actual = MD5String("12345678901234567890"
    186                                  "12345678901234567890"
    187                                  "12345678901234567890"
    188                                  "12345678901234567890");
    189   std::string expected = "57edf4a22be3c955ac49da2e2107b67a";
    190   EXPECT_EQ(expected, actual);
    191 }
    192 
    193 TEST(MD5, ContextWithStringData) {
    194   MD5Context ctx;
    195   MD5Init(&ctx);
    196 
    197   MD5Update(&ctx, "abc");
    198 
    199   MD5Digest digest;
    200   MD5Final(&digest, &ctx);
    201 
    202   std::string actual = MD5DigestToBase16(digest);
    203   std::string expected = "900150983cd24fb0d6963f7d28e17f72";
    204 
    205   EXPECT_EQ(expected, actual);
    206 }
    207 
    208 // Test that a digest generated by MD5IntermediateFinal() gives the same results
    209 // as an independently-calculated digest, and also does not modify the context.
    210 TEST(MD5, IntermediateFinal) {
    211   // Independent context over the header.
    212   MD5Context check_header_context;
    213   MD5Init(&check_header_context);
    214 
    215   // Independent context over entire input.
    216   MD5Context check_full_context;
    217   MD5Init(&check_full_context);
    218 
    219   // Context intermediate digest will be calculated from.
    220   MD5Context context;
    221   MD5Init(&context);
    222 
    223   static const char kHeader[] = "header data";
    224   static const char kBody[] = "payload data";
    225 
    226   MD5Update(&context, kHeader);
    227   MD5Update(&check_header_context, kHeader);
    228   MD5Update(&check_full_context, kHeader);
    229 
    230   MD5Digest check_header_digest;
    231   MD5Final(&check_header_digest, &check_header_context);
    232 
    233   MD5Digest header_digest;
    234   MD5IntermediateFinal(&header_digest, &context);
    235 
    236   MD5Update(&context, kBody);
    237   MD5Update(&check_full_context, kBody);
    238 
    239   MD5Digest check_full_digest;
    240   MD5Final(&check_full_digest, &check_full_context);
    241 
    242   MD5Digest digest;
    243   MD5Final(&digest, &context);
    244 
    245   // The header and full digest pairs are the same, and they aren't the same as
    246   // each other.
    247   EXPECT_TRUE(!memcmp(&header_digest, &check_header_digest,
    248                       sizeof(header_digest)));
    249   EXPECT_TRUE(!memcmp(&digest, &check_full_digest, sizeof(digest)));
    250   EXPECT_TRUE(memcmp(&digest, &header_digest, sizeof(digest)));
    251 }
    252 
    253 }  // namespace base
    254