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