1 /*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "AdbPairingAuthTest"
18
19 #include <gtest/gtest.h>
20
21 #include <adb/pairing/pairing_auth.h>
22 #include <android-base/endian.h>
23
24 namespace adb {
25 namespace pairing {
26
PairingAuthDeleter(PairingAuthCtx * p)27 static void PairingAuthDeleter(PairingAuthCtx* p) {
28 pairing_auth_destroy(p);
29 }
30
31 class AdbPairingAuthTest : public testing::Test {
32 protected:
SetUp()33 virtual void SetUp() override {}
34
TearDown()35 virtual void TearDown() override {}
36
37 using PairingAuthUniquePtr = std::unique_ptr<PairingAuthCtx, decltype(&PairingAuthDeleter)>;
38
makeClient(std::vector<uint8_t> pswd)39 PairingAuthUniquePtr makeClient(std::vector<uint8_t> pswd) {
40 return PairingAuthUniquePtr(pairing_auth_client_new(pswd.data(), pswd.size()),
41 PairingAuthDeleter);
42 }
43
makeServer(std::vector<uint8_t> pswd)44 PairingAuthUniquePtr makeServer(std::vector<uint8_t> pswd) {
45 return PairingAuthUniquePtr(pairing_auth_server_new(pswd.data(), pswd.size()),
46 PairingAuthDeleter);
47 }
48 };
49
TEST_F(AdbPairingAuthTest,EmptyPassword)50 TEST_F(AdbPairingAuthTest, EmptyPassword) {
51 // Context creation should fail if password is empty
52 PairingAuthUniquePtr client(nullptr, PairingAuthDeleter);
53 ASSERT_DEATH(
54 {
55 client = PairingAuthUniquePtr(pairing_auth_client_new(nullptr, 0),
56 PairingAuthDeleter);
57 },
58 "");
59 ASSERT_DEATH(
60 {
61 client = PairingAuthUniquePtr(pairing_auth_client_new(nullptr, 2),
62 PairingAuthDeleter);
63 },
64 "");
65 ASSERT_DEATH(
66 {
67 uint8_t p;
68 client = PairingAuthUniquePtr(pairing_auth_client_new(&p, 0), PairingAuthDeleter);
69 },
70 "");
71 }
72
TEST_F(AdbPairingAuthTest,ValidPassword)73 TEST_F(AdbPairingAuthTest, ValidPassword) {
74 const char* kPswd = "password";
75 std::vector<uint8_t> pswd(kPswd, kPswd + sizeof(kPswd));
76 auto client = makeClient(pswd);
77 auto server = makeServer(pswd);
78
79 ASSERT_NE(nullptr, client);
80 ASSERT_NE(nullptr, server);
81
82 // msg should not be empty.
83 {
84 size_t msg_size = pairing_auth_msg_size(client.get());
85 std::vector<uint8_t> buf(msg_size);
86 ASSERT_GT(msg_size, 0);
87 pairing_auth_get_spake2_msg(client.get(), buf.data());
88 }
89 {
90 size_t msg_size = pairing_auth_msg_size(server.get());
91 std::vector<uint8_t> buf(msg_size);
92 ASSERT_GT(msg_size, 0);
93 pairing_auth_get_spake2_msg(server.get(), buf.data());
94 }
95 }
96
TEST_F(AdbPairingAuthTest,NoInitCipher)97 TEST_F(AdbPairingAuthTest, NoInitCipher) {
98 // Register a non-empty password, but not the peer's msg.
99 // You should not be able to encrypt/decrypt messages.
100 const char* kPswd = "password";
101 std::vector<uint8_t> pswd(kPswd, kPswd + sizeof(kPswd));
102 std::vector<uint8_t> data{0x01, 0x02, 0x03};
103 uint8_t outbuf[256];
104 size_t outsize;
105
106 // All other functions should crash if cipher hasn't been initialized.
107 ASSERT_DEATH(
108 {
109 auto server = makeServer(pswd);
110 pairing_auth_init_cipher(server.get(), nullptr, 0);
111 },
112 "");
113 ASSERT_DEATH(
114 {
115 auto server = makeServer(pswd);
116 pairing_auth_encrypt(server.get(), data.data(), data.size(), outbuf, &outsize);
117 },
118 "");
119 ASSERT_DEATH(
120 {
121 auto server = makeServer(pswd);
122 pairing_auth_decrypt(server.get(), data.data(), data.size(), outbuf, &outsize);
123 },
124 "");
125 ASSERT_DEATH(
126 {
127 auto server = makeServer(pswd);
128 pairing_auth_safe_decrypted_size(server.get(), data.data(), data.size());
129 },
130 "");
131 ASSERT_DEATH(
132 {
133 auto server = makeServer(pswd);
134 pairing_auth_safe_encrypted_size(server.get(), data.size());
135 },
136 "");
137 }
138
TEST_F(AdbPairingAuthTest,DifferentPasswords)139 TEST_F(AdbPairingAuthTest, DifferentPasswords) {
140 // Register different passwords and then exchange the msgs. The
141 // encryption should succeed, but the decryption should fail, since the
142 // ciphers have been initialized with different keys.
143 auto client = makeClient({0x01, 0x02, 0x03});
144 std::vector<uint8_t> client_msg(pairing_auth_msg_size(client.get()));
145 ASSERT_FALSE(client_msg.empty());
146 pairing_auth_get_spake2_msg(client.get(), client_msg.data());
147
148 auto server = makeServer({0x01, 0x02, 0x04});
149 std::vector<uint8_t> server_msg(pairing_auth_msg_size(server.get()));
150 ASSERT_FALSE(server_msg.empty());
151 pairing_auth_get_spake2_msg(server.get(), server_msg.data());
152
153 EXPECT_TRUE(pairing_auth_init_cipher(client.get(), server_msg.data(), server_msg.size()));
154 EXPECT_TRUE(pairing_auth_init_cipher(server.get(), client_msg.data(), client_msg.size()));
155
156 // We shouldn't be able to decrypt.
157 std::vector<uint8_t> msg{0x2a, 0x2b, 0x2c};
158 // Client encrypts, server can't decrypt
159 size_t out_size;
160 client_msg.resize(pairing_auth_safe_encrypted_size(client.get(), msg.size()));
161 ASSERT_GT(client_msg.size(), 0);
162 ASSERT_TRUE(pairing_auth_encrypt(client.get(), msg.data(), msg.size(), client_msg.data(),
163 &out_size));
164 ASSERT_GT(out_size, 0);
165 client_msg.resize(out_size);
166
167 server_msg.resize(
168 pairing_auth_safe_decrypted_size(server.get(), client_msg.data(), client_msg.size()));
169 ASSERT_GT(server_msg.size(), 0);
170 ASSERT_FALSE(pairing_auth_decrypt(server.get(), client_msg.data(), client_msg.size(),
171 server_msg.data(), &out_size));
172
173 // Server encrypts, client can't decrypt
174 server_msg.resize(pairing_auth_safe_encrypted_size(server.get(), msg.size()));
175 ASSERT_GT(server_msg.size(), 0);
176 ASSERT_TRUE(pairing_auth_encrypt(server.get(), msg.data(), msg.size(), server_msg.data(),
177 &out_size));
178 ASSERT_GT(out_size, 0);
179 server_msg.resize(out_size);
180
181 client_msg.resize(
182 pairing_auth_safe_decrypted_size(client.get(), server_msg.data(), server_msg.size()));
183 ASSERT_GT(client_msg.size(), 0);
184 ASSERT_FALSE(pairing_auth_decrypt(client.get(), server_msg.data(), server_msg.size(),
185 client_msg.data(), &out_size));
186 }
187
TEST_F(AdbPairingAuthTest,SamePasswords)188 TEST_F(AdbPairingAuthTest, SamePasswords) {
189 // Register same password and then exchange the msgs. The
190 // encryption and decryption should succeed and have the same, unencrypted
191 // values.
192 std::vector<uint8_t> pswd{0x4f, 0x5a, 0x01, 0x46};
193 auto client = makeClient(pswd);
194 std::vector<uint8_t> client_msg(pairing_auth_msg_size(client.get()));
195 ASSERT_FALSE(client_msg.empty());
196 pairing_auth_get_spake2_msg(client.get(), client_msg.data());
197
198 auto server = makeServer(pswd);
199 std::vector<uint8_t> server_msg(pairing_auth_msg_size(server.get()));
200 ASSERT_FALSE(server_msg.empty());
201 pairing_auth_get_spake2_msg(server.get(), server_msg.data());
202
203 EXPECT_TRUE(pairing_auth_init_cipher(client.get(), server_msg.data(), server_msg.size()));
204 EXPECT_TRUE(pairing_auth_init_cipher(server.get(), client_msg.data(), client_msg.size()));
205
206 // We should be able to decrypt.
207 std::vector<uint8_t> msg{0x2a, 0x2b, 0x2c, 0xff, 0x45, 0x12, 0x33};
208 // Client encrypts, server decrypts
209 size_t out_size;
210 client_msg.resize(pairing_auth_safe_encrypted_size(client.get(), msg.size()));
211 ASSERT_GT(client_msg.size(), 0);
212 ASSERT_TRUE(pairing_auth_encrypt(client.get(), msg.data(), msg.size(), client_msg.data(),
213 &out_size));
214 ASSERT_GT(out_size, 0);
215 client_msg.resize(out_size);
216
217 server_msg.resize(
218 pairing_auth_safe_decrypted_size(server.get(), client_msg.data(), client_msg.size()));
219 ASSERT_GT(server_msg.size(), 0);
220 ASSERT_TRUE(pairing_auth_decrypt(server.get(), client_msg.data(), client_msg.size(),
221 server_msg.data(), &out_size));
222 ASSERT_EQ(out_size, msg.size());
223 EXPECT_EQ(memcmp(msg.data(), server_msg.data(), out_size), 0);
224
225 // Server encrypts, client decrypt
226 server_msg.resize(pairing_auth_safe_encrypted_size(server.get(), msg.size()));
227 ASSERT_GT(server_msg.size(), 0);
228 ASSERT_TRUE(pairing_auth_encrypt(server.get(), msg.data(), msg.size(), server_msg.data(),
229 &out_size));
230 ASSERT_GT(out_size, 0);
231 server_msg.resize(out_size);
232
233 client_msg.resize(
234 pairing_auth_safe_decrypted_size(client.get(), server_msg.data(), server_msg.size()));
235 ASSERT_GT(client_msg.size(), 0);
236 ASSERT_TRUE(pairing_auth_decrypt(client.get(), server_msg.data(), server_msg.size(),
237 client_msg.data(), &out_size));
238 ASSERT_EQ(out_size, msg.size());
239 EXPECT_EQ(memcmp(msg.data(), client_msg.data(), out_size), 0);
240 }
241
TEST_F(AdbPairingAuthTest,CorruptedPayload)242 TEST_F(AdbPairingAuthTest, CorruptedPayload) {
243 // Do a matching password for both server/client, but let's fudge with the
244 // header payload field. The decryption should fail.
245 std::vector<uint8_t> pswd{0x4f, 0x5a, 0x01, 0x46};
246 auto client = makeClient(pswd);
247 std::vector<uint8_t> client_msg(pairing_auth_msg_size(client.get()));
248 ASSERT_FALSE(client_msg.empty());
249 pairing_auth_get_spake2_msg(client.get(), client_msg.data());
250
251 auto server = makeServer(pswd);
252 std::vector<uint8_t> server_msg(pairing_auth_msg_size(server.get()));
253 ASSERT_FALSE(server_msg.empty());
254 pairing_auth_get_spake2_msg(server.get(), server_msg.data());
255
256 EXPECT_TRUE(pairing_auth_init_cipher(client.get(), server_msg.data(), server_msg.size()));
257 EXPECT_TRUE(pairing_auth_init_cipher(server.get(), client_msg.data(), client_msg.size()));
258
259 std::vector<uint8_t> msg{0x2a, 0x2b, 0x2c, 0xff, 0x45, 0x12,
260 0x33, 0x45, 0x12, 0xea, 0xf2, 0xdb};
261 {
262 // Client encrypts whole msg, server decrypts msg. Should be fine.
263 size_t out_size;
264 client_msg.resize(pairing_auth_safe_encrypted_size(client.get(), msg.size()));
265 ASSERT_GT(client_msg.size(), 0);
266 ASSERT_TRUE(pairing_auth_encrypt(client.get(), msg.data(), msg.size(), client_msg.data(),
267 &out_size));
268 ASSERT_GT(out_size, 0);
269 client_msg.resize(out_size);
270
271 server_msg.resize(pairing_auth_safe_decrypted_size(server.get(), client_msg.data(),
272 client_msg.size()));
273 ASSERT_GT(server_msg.size(), 0);
274 ASSERT_TRUE(pairing_auth_decrypt(server.get(), client_msg.data(), client_msg.size(),
275 server_msg.data(), &out_size));
276 ASSERT_EQ(out_size, msg.size());
277 EXPECT_EQ(memcmp(msg.data(), server_msg.data(), out_size), 0);
278 }
279 {
280 // 1) Client encrypts msg
281 // 2) append some data to the encrypted msg
282 // 3) change the payload field
283 // 4) server tries to decrypt. It should fail.
284 size_t out_size;
285 client_msg.resize(pairing_auth_safe_encrypted_size(client.get(), msg.size()));
286 ASSERT_GT(client_msg.size(), 0);
287 ASSERT_TRUE(pairing_auth_encrypt(client.get(), msg.data(), msg.size(), client_msg.data(),
288 &out_size));
289 ASSERT_GT(out_size, 0);
290 client_msg.resize(out_size);
291 client_msg.push_back(0xaa);
292 // This requires knowledge of the layout of the data. payload is the
293 // first four bytes of the client_msg.
294 uint32_t* payload = reinterpret_cast<uint32_t*>(client_msg.data());
295 *payload = ntohl(*payload);
296 *payload = htonl(*payload + 1);
297
298 server_msg.resize(pairing_auth_safe_decrypted_size(server.get(), client_msg.data(),
299 client_msg.size()));
300 ASSERT_GT(server_msg.size(), 0);
301 ASSERT_FALSE(pairing_auth_decrypt(server.get(), client_msg.data(), client_msg.size(),
302 server_msg.data(), &out_size));
303 }
304 {
305 // 1) Client encrypts msg
306 // 3) decrement the payload field
307 // 4) server tries to decrypt. It should fail.
308 size_t out_size;
309 client_msg.resize(pairing_auth_safe_encrypted_size(client.get(), msg.size()));
310 ASSERT_GT(client_msg.size(), 0);
311 ASSERT_TRUE(pairing_auth_encrypt(client.get(), msg.data(), msg.size(), client_msg.data(),
312 &out_size));
313 ASSERT_GT(out_size, 0);
314 client_msg.resize(out_size);
315 // This requires knowledge of the layout of the data. payload is the
316 // first four bytes of the client_msg.
317 uint32_t* payload = reinterpret_cast<uint32_t*>(client_msg.data());
318 *payload = ntohl(*payload);
319 *payload = htonl(*payload - 1);
320
321 server_msg.resize(pairing_auth_safe_decrypted_size(server.get(), client_msg.data(),
322 client_msg.size()));
323 ASSERT_GT(server_msg.size(), 0);
324 ASSERT_FALSE(pairing_auth_decrypt(server.get(), client_msg.data(), client_msg.size(),
325 server_msg.data(), &out_size));
326 }
327 }
328
329 } // namespace pairing
330 } // namespace adb
331