1 // Copyright 2010-2018, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 #include <memory>
31 
32 #include "base/encryptor.h"
33 #include "base/password_manager.h"
34 #include "base/system_util.h"
35 #include "base/util.h"
36 #include "testing/base/public/googletest.h"
37 #include "testing/base/public/gunit.h"
38 
39 namespace mozc {
40 
41 namespace {
42 struct TestData {
43   const char *password;
44   size_t password_size;
45   const char *salt;
46   size_t salt_size;
47   const char *iv;
48   const char *input;
49   size_t input_size;
50   const char *encrypted;
51   size_t encrypted_size;
52 };
53 
54 const TestData kTestData[] = {
55   {
56     "foohoge", 7,
57     "salt", 4,
58     "1111111111111111",
59     "foo", 3,
60     "\x27\x32\x66\x88\x82\x33\x78\x80\x58\x29\xBF\xDD\x46\x9A\xCC\x87", 16
61   },
62   {
63     "password", 8,
64     "salt", 4,
65     "1111111111111111",
66     "a", 1,
67     "\x2A\xA1\x73\xB0\x91\x1C\x22\x40\x55\xDB\xAB\xC0\x77\x39\xE6\x57", 16
68   },
69   {
70     "password", 8,
71     "salt", 4,
72     "1111111111111111",
73     "test", 4,
74     "\x13\x16\x0A\xA4\x2B\xA3\x02\xC4\xEF\x47\x98\x6D\x9F\xC9\xAD\x43", 16
75   },
76   {
77     "password", 8,
78     "salt", 4,
79     "0123456789abcdef",
80     "dhoifasoifaoishd"
81     "oifahsoifdhaoish"
82     "fioashdoifahisod"
83     "fhaioshdfioa", 60,
84     "\x27\x92\xD1\x4F\xCE\x71\xFF\xA0\x9E\x52\xAB\x96\xB4\x5D\x1A\x2F"
85     "\xE0\xC7\xB3\x92\xD7\xB8\x29\xB0\xEF\xD3\x51\x9F\xBD\x87\xE0\xB4"
86     "\x0A\x06\xE0\x9A\x03\x72\x48\xB3\x8F\x9A\x5E\xAC\xCD\x5D\xB8\x0B"
87     "\x01\x1D\x2C\xD7\xAA\x55\x05\x0F\x4E\xD5\x73\xC0\xCB\xE2\x10\x69", 64
88   }
89 };
90 }  // namespace
91 
TEST(EncryptorTest,VerificationTest)92 TEST(EncryptorTest, VerificationTest) {
93   {
94     const string password(kTestData[0].password, kTestData[0].password_size);
95     const string salt(kTestData[0].salt, kTestData[0].salt_size);
96     Encryptor::Key key1, key2;
97     EXPECT_TRUE(key1.DeriveFromPassword(
98                     password, salt,
99                     reinterpret_cast<const uint8 *>(kTestData[0].iv)));
100     EXPECT_TRUE(key1.IsAvailable());
101     EXPECT_TRUE(key2.DeriveFromPassword(
102                     password, salt,
103                     reinterpret_cast<const uint8 *>(kTestData[0].iv)));
104     EXPECT_TRUE(key2.IsAvailable());
105     string input(kTestData[0].input, kTestData[0].input_size);
106     const string encrypted(kTestData[0].encrypted, kTestData[0].encrypted_size);
107     const string decrypted(input.data(), input.size());
108 
109     EXPECT_TRUE(Encryptor::EncryptString(key1, &input));
110     EXPECT_EQ(encrypted, input);
111     EXPECT_TRUE(Encryptor::DecryptString(key2, &input));
112     EXPECT_EQ(decrypted, input);
113   }
114   {
115     const string password(kTestData[1].password, kTestData[1].password_size);
116     const string salt(kTestData[1].salt, kTestData[1].salt_size);
117     Encryptor::Key key1, key2;
118     EXPECT_TRUE(key1.DeriveFromPassword(
119                     password, salt,
120                     reinterpret_cast<const uint8 *>(kTestData[1].iv)));
121     EXPECT_TRUE(key1.IsAvailable());
122     EXPECT_TRUE(key2.DeriveFromPassword(
123                     password, salt,
124                     reinterpret_cast<const uint8 *>(kTestData[1].iv)));
125     EXPECT_TRUE(key2.IsAvailable());
126     string input(kTestData[1].input, kTestData[1].input_size);
127     const string encrypted(kTestData[1].encrypted, kTestData[1].encrypted_size);
128     const string decrypted(input.data(), input.size());
129 
130     EXPECT_TRUE(Encryptor::EncryptString(key1, &input));
131     EXPECT_EQ(encrypted, input);
132     EXPECT_TRUE(Encryptor::DecryptString(key2, &input));
133     EXPECT_EQ(decrypted, input);
134   }
135   {
136     const string password(kTestData[2].password, kTestData[2].password_size);
137     const string salt(kTestData[2].salt, kTestData[2].salt_size);
138     Encryptor::Key key1, key2;
139     EXPECT_TRUE(key1.DeriveFromPassword(
140                     password, salt,
141                     reinterpret_cast<const uint8 *>(kTestData[2].iv)));
142     EXPECT_TRUE(key1.IsAvailable());
143     EXPECT_TRUE(key2.DeriveFromPassword(
144                     password, salt,
145                     reinterpret_cast<const uint8 *>(kTestData[2].iv)));
146     EXPECT_TRUE(key2.IsAvailable());
147     string input(kTestData[2].input, kTestData[2].input_size);
148     const string encrypted(kTestData[2].encrypted, kTestData[2].encrypted_size);
149     const string decrypted(input.data(), input.size());
150 
151     EXPECT_TRUE(Encryptor::EncryptString(key1, &input));
152     EXPECT_EQ(encrypted, input);
153     EXPECT_TRUE(Encryptor::DecryptString(key2, &input));
154     EXPECT_EQ(decrypted, input);
155   }
156   {
157     const string password(kTestData[3].password, kTestData[3].password_size);
158     const string salt(kTestData[3].salt, kTestData[3].salt_size);
159     Encryptor::Key key1, key2;
160     EXPECT_TRUE(key1.DeriveFromPassword(
161                     password, salt,
162                     reinterpret_cast<const uint8 *>(kTestData[3].iv)));
163     EXPECT_TRUE(key1.IsAvailable());
164     EXPECT_TRUE(key2.DeriveFromPassword(
165                     password, salt,
166                     reinterpret_cast<const uint8 *>(kTestData[3].iv)));
167     EXPECT_TRUE(key2.IsAvailable());
168     string input(kTestData[3].input, kTestData[3].input_size);
169     const string encrypted(kTestData[3].encrypted, kTestData[3].encrypted_size);
170     const string decrypted(input.data(), input.size());
171 
172     EXPECT_TRUE(Encryptor::EncryptString(key1, &input));
173     EXPECT_EQ(encrypted, input);
174     EXPECT_TRUE(Encryptor::DecryptString(key2, &input));
175     EXPECT_EQ(decrypted, input);
176   }
177 }
178 
TEST(EncryptorTest,BasicTest)179 TEST(EncryptorTest, BasicTest) {
180   Encryptor::Key key;
181   EXPECT_FALSE(key.DeriveFromPassword(""));
182   EXPECT_FALSE(key.IsAvailable());
183   EXPECT_TRUE(key.DeriveFromPassword("test"));
184   EXPECT_TRUE(key.IsAvailable());
185   EXPECT_EQ(16, key.block_size());
186   EXPECT_EQ(256, key.key_size());
187   EXPECT_EQ(16, key.iv_size());
188 }
189 
TEST(EncryptorTest,EncryptBatch)190 TEST(EncryptorTest, EncryptBatch) {
191   const size_t kSizeTable[] = { 1, 10, 16, 32, 100, 1000, 1600,
192                                 10000, 16000, 100000 };
193 
194   for (size_t i = 0; i < arraysize(kSizeTable); ++i) {
195     std::unique_ptr<char[]> buf(new char[kSizeTable[i]]);
196     Util::GetRandomSequence(buf.get(), kSizeTable[i]);
197 
198     Encryptor::Key key1, key2, key3, key4;
199 
200     EXPECT_TRUE(key1.DeriveFromPassword("test", "salt"));
201     EXPECT_TRUE(key2.DeriveFromPassword("test", "salt"));
202 
203     EXPECT_TRUE(key3.DeriveFromPassword("test", "salt2"));  // wrong salt
204     EXPECT_TRUE(key4.DeriveFromPassword("test2", "salt"));  // wrong key
205 
206     EXPECT_TRUE(key1.IsAvailable());
207     EXPECT_TRUE(key2.IsAvailable());
208     EXPECT_TRUE(key3.IsAvailable());
209     EXPECT_TRUE(key4.IsAvailable());
210 
211     string original(buf.get(), kSizeTable[i]);
212 
213     // enfoce to copy. disable reference counting
214     string encrypted(original.data(), original.size());
215 
216     EXPECT_TRUE(Encryptor::EncryptString(key1, &encrypted));
217     EXPECT_EQ(0, encrypted.size() % key1.block_size());
218     EXPECT_NE(encrypted, original);
219 
220     string encrypted3(encrypted.data(), encrypted.size());
221     string encrypted4(encrypted.data(), encrypted.size());
222 
223     EXPECT_TRUE(Encryptor::DecryptString(key2, &encrypted));
224     EXPECT_EQ(original.size(), encrypted.size());
225     EXPECT_EQ(original, encrypted);
226 
227     // wrong key
228     Encryptor::DecryptString(key3, &encrypted3);
229     Encryptor::DecryptString(key4, &encrypted4);
230     EXPECT_NE(original, encrypted3);
231     EXPECT_NE(original, encrypted4);
232 
233     // invalid values
234     EXPECT_FALSE(Encryptor::EncryptString(key1, NULL));
235     EXPECT_FALSE(Encryptor::DecryptString(key1, NULL));
236 
237     // empty string
238     string empty_string;
239     EXPECT_FALSE(Encryptor::EncryptString(key1, &empty_string));
240     EXPECT_FALSE(Encryptor::DecryptString(key1, &empty_string));
241   }
242 }
243 
TEST(EncryptorTest,ProtectData)244 TEST(EncryptorTest, ProtectData) {
245   SystemUtil::SetUserProfileDirectory(FLAGS_test_tmpdir);
246   const size_t kSizeTable[] = { 1, 10, 100, 1000, 10000, 100000 };
247 
248   for (size_t i = 0; i < arraysize(kSizeTable); ++i) {
249     std::unique_ptr<char[]> buf(new char[kSizeTable[i]]);
250     Util::GetRandomSequence(buf.get(), kSizeTable[i]);
251     string input(buf.get(), kSizeTable[i]);
252     string output;
253     EXPECT_TRUE(Encryptor::ProtectData(input, &output));
254     EXPECT_NE(input, output);
255     string result;
256     EXPECT_TRUE(Encryptor::UnprotectData(output, &result));
257     EXPECT_EQ(result, input);
258   }
259 }
260 
261 }  // namespace mozc
262