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