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