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