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