1 /*
2 * Copyright (C) 2017 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 #include <android-base/logging.h>
18
19 #include <android/security/keystore/IKeystoreService.h>
20 #include <android/system/wifi/keystore/1.0/IKeystore.h>
21 #include <binder/IServiceManager.h>
22 #include <binder/ProcessState.h>
23 #include <cutils/properties.h>
24 #include <gtest/gtest.h>
25 #include <hidl/GtestPrinter.h>
26 #include <hidl/ServiceManagement.h>
27 #include <keymasterV4_0/authorization_set.h>
28 #include <keystore/keystore_promises.h>
29 #include <private/android_filesystem_config.h>
30 #include <utils/String16.h>
31
32 using namespace std;
33 using namespace ::testing;
34 using namespace android;
35 using namespace android::binder;
36 using namespace android::security::keystore;
37 using namespace android::security::keymaster;
38 using android::security::keystore::IKeystoreService;
39 using android::system::wifi::keystore::V1_0::IKeystore;
40
main(int argc,char ** argv)41 int main(int argc, char** argv) {
42 // Start thread pool for Binder
43 android::ProcessState::self()->startThreadPool();
44
45 InitGoogleTest(&argc, argv);
46 int status = RUN_ALL_TESTS();
47 return status;
48 }
49
50 namespace {
51
52 enum KeyPurpose {
53 ENCRYPTION,
54 SIGNING,
55 };
56
57 // The fixture for testing the Wifi Keystore HAL
58 class WifiKeystoreHalTest : public TestWithParam<std::string> {
59 protected:
SetUp()60 void SetUp() override {
61 keystore = IKeystore::getService(GetParam());
62 ASSERT_TRUE(keystore);
63
64 sp<android::IServiceManager> service_manager = android::defaultServiceManager();
65 sp<android::IBinder> keystore_binder =
66 service_manager->getService(String16(kKeystoreServiceName));
67 service = interface_cast<IKeystoreService>(keystore_binder);
68
69 ASSERT_TRUE(service);
70
71 resetState();
72 }
73
TearDown()74 void TearDown() override { resetState(); }
75
isDebuggableBuild()76 bool isDebuggableBuild() {
77 char value[PROPERTY_VALUE_MAX] = {0};
78 property_get("ro.system.build.type", value, "");
79 if (strcmp(value, "userdebug") == 0) {
80 return true;
81 }
82 if (strcmp(value, "eng") == 0) {
83 return true;
84 }
85 return false;
86 }
87
88 /**
89 * Resets the relevant state of the system between tests
90 */
resetState()91 void resetState() {
92 for (uid_t uid : {UID_SELF, AID_WIFI}) {
93 deleteKey(kTestKeyName, uid);
94 }
95 }
96
97 /**
98 * Delete a key if it exists.
99 *
100 * @param keyName: name of the key to delete
101 * @param uid: the uid to delete the key on behalf of. Use
102 * UID_SELF to use the process' uid.
103 *
104 * @return true iff the key existed and is now deleted, false otherwise.
105 */
deleteKey(std::string keyName,uid_t uid)106 bool deleteKey(std::string keyName, uid_t uid) {
107 String16 keyName16(keyName.data(), keyName.size());
108 int32_t result;
109 auto binder_result = service->del(keyName16, uid, &result);
110 if (!binder_result.isOk()) {
111 cout << "deleteKey: failed binder call" << endl;
112 return false;
113 }
114
115 keystore::KeyStoreNativeReturnCode wrappedResult(result);
116 return wrappedResult.isOk();
117 }
118
119 /**
120 * Generate a key for a specific purpose.
121 *
122 * This generates a key which can be used either for signing
123 * or encryption. The signing key is setup to be used in
124 * the Wifi Keystore HAL's sign() call. The data
125 * about the key returning from its generation is discarded.
126 * If this returns 'true' the key generation has completed
127 * and the key is ready for use.
128 *
129 * @param keyName: name of the key to generate
130 * @param purpose: the purpose the generated key will support
131 * @param uid: the uid to generate the key on behalf of. Use
132 * UID_SELF to use the process' uid.
133 *
134 * @return true iff the key was successfully generated and is
135 * ready for use, false otherwise.
136 */
generateKey(std::string keyName,KeyPurpose purpose,uid_t uid)137 bool generateKey(std::string keyName, KeyPurpose purpose, uid_t uid) {
138 constexpr uint32_t kAESKeySize = 256;
139
140 int32_t aidl_return;
141 vector<uint8_t> entropy;
142 keystore::AuthorizationSetBuilder key_parameters;
143 if (purpose == KeyPurpose::SIGNING) {
144 key_parameters.EcdsaSigningKey(kAESKeySize);
145 }
146
147 if (purpose == KeyPurpose::ENCRYPTION) {
148 key_parameters.AesEncryptionKey(kAESKeySize);
149 }
150
151 key_parameters.NoDigestOrPadding()
152 .Authorization(keystore::keymaster::TAG_BLOCK_MODE, keystore::keymaster::BlockMode::CBC)
153 .Authorization(keystore::keymaster::TAG_NO_AUTH_REQUIRED);
154
155 sp<keystore::KeyCharacteristicsPromise> promise(new keystore::KeyCharacteristicsPromise);
156 auto future = promise->get_future();
157
158 String16 keyName16(keyName.data(), keyName.size());
159
160 fflush(stdout);
161 auto binder_result = service->generateKey(
162 promise, keyName16, KeymasterArguments(key_parameters.hidl_data()), entropy,
163 uid, // create key for process' uid
164 0, // empty flags; pick default key provider
165 &aidl_return);
166
167 if (!binder_result.isOk()) {
168 cout << "generateKey: Failed binder call" << endl;
169 return false;
170 }
171
172 keystore::KeyStoreNativeReturnCode rc(aidl_return);
173 if (!rc.isOk()) {
174 cout << "generateKey: Failed to generate key" << endl;
175 return false;
176 }
177
178 auto [km_response, characteristics] = future.get();
179
180 return true;
181 }
182
183 /**
184 * Creates a TYPE_GENERIC key blob. This cannot be used for signing.
185 *
186 * @param keyName: name of the key to generate.
187 * @param uid: the uid to insert the key on behalf of. Use
188 * UID_SELF to use the process' uid.
189 *
190 * @returns true iff the key was successfully created, false otherwise.
191 */
insert(std::string keyName,uid_t uid)192 bool insert(std::string keyName, uid_t uid) {
193 int32_t aidl_return;
194 vector<uint8_t> item;
195
196 String16 keyName16(keyName.data(), keyName.size());
197 auto binder_result = service->insert(keyName16, item,
198 uid, // Use process' uid
199 0, // empty flags; pick default key provider
200 &aidl_return);
201
202 if (!binder_result.isOk()) {
203 cout << "insert: Failed binder call" << endl;
204 return false;
205 }
206
207 keystore::KeyStoreNativeReturnCode rc(aidl_return);
208 if (!rc.isOk()) {
209 cout << "insert: Failed to generate key" << endl;
210 return false;
211 }
212
213 return true;
214 }
215
216 constexpr static const char kKeystoreServiceName[] = "android.security.keystore";
217 constexpr static const char kTestKeyName[] = "TestKeyName";
218 constexpr static const int32_t UID_SELF = -1;
219
220 sp<IKeystore> keystore;
221 sp<IKeystoreService> service;
222 };
223
TEST_P(WifiKeystoreHalTest,Sign_nullptr_key_name)224 TEST_P(WifiKeystoreHalTest, Sign_nullptr_key_name) {
225 IKeystore::KeystoreStatusCode statusCode;
226
227 auto callback = [&statusCode](IKeystore::KeystoreStatusCode status,
228 const ::android::hardware::hidl_vec<uint8_t>& /*value*/) {
229 statusCode = status;
230 return;
231 };
232
233 ::android::hardware::hidl_vec<uint8_t> dataToSign;
234 dataToSign.resize(100);
235 keystore->sign(nullptr, dataToSign, callback);
236 EXPECT_EQ(IKeystore::KeystoreStatusCode::ERROR_UNKNOWN, statusCode);
237 }
238
TEST_P(WifiKeystoreHalTest,Sign_empty_key_name)239 TEST_P(WifiKeystoreHalTest, Sign_empty_key_name) {
240 IKeystore::KeystoreStatusCode statusCode;
241
242 auto callback = [&statusCode](IKeystore::KeystoreStatusCode status,
243 const ::android::hardware::hidl_vec<uint8_t>& /*value*/) {
244 statusCode = status;
245 return;
246 };
247
248 ::android::hardware::hidl_vec<uint8_t> dataToSign;
249 dataToSign.resize(100);
250 keystore->sign("", dataToSign, callback);
251 EXPECT_EQ(IKeystore::KeystoreStatusCode::ERROR_UNKNOWN, statusCode);
252 }
253
TEST_P(WifiKeystoreHalTest,Sign_empty_data)254 TEST_P(WifiKeystoreHalTest, Sign_empty_data) {
255 if (!isDebuggableBuild()) {
256 GTEST_SKIP() << "Device not running a debuggable build, cannot make test keys";
257 }
258
259 bool callbackInvoked = false;
260
261 auto callback = [&callbackInvoked](IKeystore::KeystoreStatusCode /*status*/,
262 const ::android::hardware::hidl_vec<uint8_t>& /*value*/) {
263 // The result is ignored; this callback is a no-op.
264 callbackInvoked = true;
265 return;
266 };
267
268 bool result = generateKey(kTestKeyName, KeyPurpose::SIGNING, AID_WIFI);
269 EXPECT_EQ(result, true);
270
271 // The data to sign is empty. The return code is not important, and the attempt could be
272 // interpreted as valid or an error case. The goal is to determine that the callback
273 // was invokved.
274 ::android::hardware::hidl_vec<uint8_t> dataToSign;
275 keystore->sign(kTestKeyName, dataToSign, callback);
276 EXPECT_EQ(true, callbackInvoked);
277 }
278
TEST_P(WifiKeystoreHalTest,Sign_wrong_key_purpose)279 TEST_P(WifiKeystoreHalTest, Sign_wrong_key_purpose) {
280 if (!isDebuggableBuild()) {
281 GTEST_SKIP() << "Device not running a debuggable build, cannot make test keys";
282 }
283
284 IKeystore::KeystoreStatusCode statusCode;
285
286 auto callback = [&statusCode](IKeystore::KeystoreStatusCode status,
287 const ::android::hardware::hidl_vec<uint8_t>& /*value*/) {
288 statusCode = status;
289 return;
290 };
291
292 // Create a key which cannot sign; any signing attempt should fail.
293 bool result = generateKey(kTestKeyName, KeyPurpose::ENCRYPTION, AID_WIFI);
294 EXPECT_EQ(result, true);
295
296 ::android::hardware::hidl_vec<uint8_t> dataToSign;
297 dataToSign.resize(100);
298 keystore->sign(kTestKeyName, dataToSign, callback);
299 EXPECT_EQ(IKeystore::KeystoreStatusCode::ERROR_UNKNOWN, statusCode);
300 }
301
TEST_P(WifiKeystoreHalTest,Sign_wrong_key_type)302 TEST_P(WifiKeystoreHalTest, Sign_wrong_key_type) {
303 if (!isDebuggableBuild()) {
304 GTEST_SKIP() << "Device not running a debuggable build, cannot make test keys";
305 }
306
307 IKeystore::KeystoreStatusCode statusCode;
308
309 auto callback = [&statusCode](IKeystore::KeystoreStatusCode status,
310 const ::android::hardware::hidl_vec<uint8_t>& /*value*/) {
311 statusCode = status;
312 return;
313 };
314
315 ::android::hardware::hidl_vec<uint8_t> dataToSign;
316
317 // Generate a TYPE_GENERIC key instead of a TYPE_KEYMASTER_10 key.
318 // This also cannot be used to sign.
319
320 bool result = insert(kTestKeyName, AID_WIFI);
321 EXPECT_EQ(result, true);
322
323 keystore->sign(kTestKeyName, dataToSign, callback);
324 EXPECT_EQ(IKeystore::KeystoreStatusCode::ERROR_UNKNOWN, statusCode);
325 }
326
TEST_P(WifiKeystoreHalTest,Sign_success)327 TEST_P(WifiKeystoreHalTest, Sign_success) {
328 if (!isDebuggableBuild()) {
329 GTEST_SKIP() << "Device not running a debuggable build, cannot make test keys";
330 }
331
332 IKeystore::KeystoreStatusCode statusCode;
333
334 auto callback = [&statusCode](IKeystore::KeystoreStatusCode status,
335 const ::android::hardware::hidl_vec<uint8_t>& /*value*/) {
336 statusCode = status;
337 return;
338 };
339
340 ::android::hardware::hidl_vec<uint8_t> dataToSign;
341
342 bool result = generateKey(kTestKeyName, KeyPurpose::SIGNING, AID_WIFI);
343 EXPECT_EQ(result, true);
344
345 // With data the signing attempt should succeed
346
347 dataToSign.resize(100);
348 keystore->sign(kTestKeyName, dataToSign, callback);
349 EXPECT_EQ(IKeystore::KeystoreStatusCode::SUCCESS, statusCode);
350
351 result = deleteKey(kTestKeyName, AID_WIFI);
352 EXPECT_EQ(result, true);
353 }
354
TEST_P(WifiKeystoreHalTest,GetBlob_null_key_name)355 TEST_P(WifiKeystoreHalTest, GetBlob_null_key_name) {
356 IKeystore::KeystoreStatusCode statusCode;
357
358 auto callback = [&statusCode](IKeystore::KeystoreStatusCode status,
359 const ::android::hardware::hidl_vec<uint8_t>& /*value*/) {
360 statusCode = status;
361 return;
362 };
363
364 // Attempting to get a blob on a non-existent key should fail.
365 statusCode = IKeystore::KeystoreStatusCode::SUCCESS;
366 keystore->getBlob(nullptr, callback);
367 EXPECT_EQ(IKeystore::KeystoreStatusCode::ERROR_UNKNOWN, statusCode);
368 }
369
TEST_P(WifiKeystoreHalTest,GetBlob_empty_key_name)370 TEST_P(WifiKeystoreHalTest, GetBlob_empty_key_name) {
371 IKeystore::KeystoreStatusCode statusCode;
372
373 auto callback = [&statusCode](IKeystore::KeystoreStatusCode status,
374 const ::android::hardware::hidl_vec<uint8_t>& /*value*/) {
375 statusCode = status;
376 return;
377 };
378
379 // Attempting to get a blob on a non-existent key should fail.
380 statusCode = IKeystore::KeystoreStatusCode::SUCCESS;
381 keystore->getBlob("", callback);
382 EXPECT_EQ(IKeystore::KeystoreStatusCode::ERROR_UNKNOWN, statusCode);
383 }
384
TEST_P(WifiKeystoreHalTest,GetBlob_missing_key)385 TEST_P(WifiKeystoreHalTest, GetBlob_missing_key) {
386 IKeystore::KeystoreStatusCode statusCode;
387
388 auto callback = [&statusCode](IKeystore::KeystoreStatusCode status,
389 const ::android::hardware::hidl_vec<uint8_t>& /*value*/) {
390 statusCode = status;
391 return;
392 };
393
394 // Attempting to get a blob on a non-existent key should fail.
395 statusCode = IKeystore::KeystoreStatusCode::SUCCESS;
396 keystore->getBlob(kTestKeyName, callback);
397 EXPECT_EQ(IKeystore::KeystoreStatusCode::ERROR_UNKNOWN, statusCode);
398 }
399
TEST_P(WifiKeystoreHalTest,GetBlob_wrong_user)400 TEST_P(WifiKeystoreHalTest, GetBlob_wrong_user) {
401 if (!isDebuggableBuild()) {
402 GTEST_SKIP() << "Device not running a debuggable build, cannot make test keys";
403 }
404
405 IKeystore::KeystoreStatusCode statusCode;
406
407 auto callback = [&statusCode](IKeystore::KeystoreStatusCode status,
408 const ::android::hardware::hidl_vec<uint8_t>& /*value*/) {
409 statusCode = status;
410 return;
411 };
412
413 // The HAL is expecting the key to belong to the wifi user.
414 // If the key belongs to another user's space it should fail.
415
416 bool result = insert(kTestKeyName, UID_SELF);
417 EXPECT_EQ(result, true);
418
419 keystore->getBlob(kTestKeyName, callback);
420 EXPECT_EQ(IKeystore::KeystoreStatusCode::ERROR_UNKNOWN, statusCode);
421 }
422
TEST_P(WifiKeystoreHalTest,GetBlob_success)423 TEST_P(WifiKeystoreHalTest, GetBlob_success) {
424 if (!isDebuggableBuild()) {
425 GTEST_SKIP() << "Device not running a debuggable build, cannot make test keys";
426 }
427
428 IKeystore::KeystoreStatusCode statusCode;
429
430 auto callback = [&statusCode](IKeystore::KeystoreStatusCode status,
431 const ::android::hardware::hidl_vec<uint8_t>& /*value*/) {
432 statusCode = status;
433 return;
434 };
435
436 // Accessing the key belonging to the wifi user should succeed.
437
438 bool result = insert(kTestKeyName, AID_WIFI);
439 EXPECT_EQ(result, true);
440
441 keystore->getBlob(kTestKeyName, callback);
442 EXPECT_EQ(IKeystore::KeystoreStatusCode::SUCCESS, statusCode);
443
444 result = deleteKey(kTestKeyName, AID_WIFI);
445 EXPECT_EQ(result, true);
446 }
447
TEST_P(WifiKeystoreHalTest,GetPublicKey_nullptr_key_name)448 TEST_P(WifiKeystoreHalTest, GetPublicKey_nullptr_key_name) {
449 IKeystore::KeystoreStatusCode statusCode;
450
451 auto callback = [&statusCode](IKeystore::KeystoreStatusCode status,
452 const ::android::hardware::hidl_vec<uint8_t>& /*value*/) {
453 statusCode = status;
454 return;
455 };
456
457 // Attempting to export a non-existent key should fail.
458 statusCode = IKeystore::KeystoreStatusCode::SUCCESS;
459 keystore->getPublicKey(nullptr, callback);
460 EXPECT_EQ(IKeystore::KeystoreStatusCode::ERROR_UNKNOWN, statusCode);
461 }
462
TEST_P(WifiKeystoreHalTest,GetPublicKey_empty_key_name)463 TEST_P(WifiKeystoreHalTest, GetPublicKey_empty_key_name) {
464 IKeystore::KeystoreStatusCode statusCode;
465
466 auto callback = [&statusCode](IKeystore::KeystoreStatusCode status,
467 const ::android::hardware::hidl_vec<uint8_t>& /*value*/) {
468 statusCode = status;
469 return;
470 };
471
472 // Attempting to export a non-existent key should fail.
473 statusCode = IKeystore::KeystoreStatusCode::SUCCESS;
474 keystore->getPublicKey("", callback);
475 EXPECT_EQ(IKeystore::KeystoreStatusCode::ERROR_UNKNOWN, statusCode);
476 }
477
TEST_P(WifiKeystoreHalTest,GetPublicKey_wrong_key_name)478 TEST_P(WifiKeystoreHalTest, GetPublicKey_wrong_key_name) {
479 IKeystore::KeystoreStatusCode statusCode;
480
481 auto callback = [&statusCode](IKeystore::KeystoreStatusCode status,
482 const ::android::hardware::hidl_vec<uint8_t>& /*value*/) {
483 statusCode = status;
484 return;
485 };
486
487 // Attempting to export a non-existent key should fail.
488 statusCode = IKeystore::KeystoreStatusCode::SUCCESS;
489 keystore->getPublicKey(kTestKeyName, callback);
490 EXPECT_EQ(IKeystore::KeystoreStatusCode::ERROR_UNKNOWN, statusCode);
491 }
492
TEST_P(WifiKeystoreHalTest,GetPublicKey_wrong_user)493 TEST_P(WifiKeystoreHalTest, GetPublicKey_wrong_user) {
494 if (!isDebuggableBuild()) {
495 GTEST_SKIP() << "Device not running a debuggable build, cannot make test keys";
496 }
497
498 IKeystore::KeystoreStatusCode statusCode;
499
500 auto callback = [&statusCode](IKeystore::KeystoreStatusCode status,
501 const ::android::hardware::hidl_vec<uint8_t>& /*value*/) {
502 statusCode = status;
503 return;
504 };
505
506 // The HAL is expecting the key to belong to the wifi user.
507 // If the key belongs to another user's space (e.g. root) it should
508 // not be accessible and should fail.
509
510 bool result = generateKey(kTestKeyName, KeyPurpose::SIGNING, UID_SELF);
511 EXPECT_EQ(result, true);
512
513 keystore->getPublicKey(kTestKeyName, callback);
514 EXPECT_EQ(IKeystore::KeystoreStatusCode::ERROR_UNKNOWN, statusCode);
515
516 result = deleteKey(kTestKeyName, UID_SELF);
517 EXPECT_EQ(result, true);
518 }
519
TEST_P(WifiKeystoreHalTest,GetPublicKey_wrong_key_type)520 TEST_P(WifiKeystoreHalTest, GetPublicKey_wrong_key_type) {
521 if (!isDebuggableBuild()) {
522 GTEST_SKIP() << "Device not running a debuggable build, cannot make test keys";
523 }
524
525 IKeystore::KeystoreStatusCode statusCode;
526
527 auto callback = [&statusCode](IKeystore::KeystoreStatusCode status,
528 const ::android::hardware::hidl_vec<uint8_t>& /*value*/) {
529 statusCode = status;
530 return;
531 };
532
533 // A TYPE_GENERIC key (instead of a TYPE_KEYMASTER_10 key)
534 // should also fail.
535
536 bool result = insert(kTestKeyName, AID_WIFI);
537 EXPECT_EQ(result, true);
538
539 keystore->getPublicKey(kTestKeyName, callback);
540 EXPECT_EQ(IKeystore::KeystoreStatusCode::ERROR_UNKNOWN, statusCode);
541
542 result = deleteKey(kTestKeyName, AID_WIFI);
543 EXPECT_EQ(result, true);
544 }
545
TEST_P(WifiKeystoreHalTest,GetPublicKey_success)546 TEST_P(WifiKeystoreHalTest, GetPublicKey_success) {
547 if (!isDebuggableBuild()) {
548 GTEST_SKIP() << "Device not running a debuggable build, cannot make test keys";
549 }
550
551 IKeystore::KeystoreStatusCode statusCode;
552
553 auto callback = [&statusCode](IKeystore::KeystoreStatusCode status,
554 const ::android::hardware::hidl_vec<uint8_t>& /*value*/) {
555 statusCode = status;
556 return;
557 };
558
559 // Accessing the key belonging to the wifi uid should succeed.
560
561 bool result = generateKey(kTestKeyName, KeyPurpose::SIGNING, AID_WIFI);
562 EXPECT_EQ(result, true);
563
564 keystore->getPublicKey(kTestKeyName, callback);
565 EXPECT_EQ(IKeystore::KeystoreStatusCode::SUCCESS, statusCode);
566
567 result = deleteKey(kTestKeyName, AID_WIFI);
568 EXPECT_EQ(result, true);
569 }
570
571 INSTANTIATE_TEST_SUITE_P(
572 PerInstance, WifiKeystoreHalTest,
573 testing::ValuesIn(android::hardware::getAllHalInstanceNames(IKeystore::descriptor)),
574 android::hardware::PrintInstanceNameToString);
575
576 } // namespace
577