From e374a4a0a6a14609f9cd6f485b002178134febd6 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Mon, 16 Sep 2019 16:09:27 +0800 Subject: [PATCH] Wifi: WAPI constants and methods This change includes two parts: * Define WAPI proto, key management, and cipher constants. * Expose WAPI HAL API for setting the certificate suite. Bug: 139257562 Test: atest VtsHalWifiSupplicantV1_3TargetTest Change-Id: Id7a58b242776d641a091b9ede3f147b7d42003d1 --- current.txt | 4 +- wifi/supplicant/1.3/ISupplicantStaIface.hal | 14 ++ wifi/supplicant/1.3/ISupplicantStaNetwork.hal | 163 ++++++++++++++++ .../supplicant_sta_iface_hidl_test.cpp | 19 ++ .../supplicant_sta_network_hidl_test.cpp | 184 +++++++++++++++++- 5 files changed, 381 insertions(+), 3 deletions(-) diff --git a/current.txt b/current.txt index 6d1e6c645e..70c413ee66 100644 --- a/current.txt +++ b/current.txt @@ -613,9 +613,9 @@ a3eddd9bbdc87e8c22764070037dd1154f1cf006e6fba93364c4f85d4c134a19 android.hardwar cf1d55e8c68300090747ab90b94c22e4c859b29c84ced68a317c595bb115eab2 android.hardware.neuralnetworks@1.3::types 3e01d4446cd69fd1c48f8572efd97487bc179564b32bd795800b97bbe10be37b android.hardware.wifi@1.4::IWifi a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardware.wifi.supplicant@1.3::ISupplicant -44445b8a03d7b9e68b2fbd954672c18a8fce9e32851b0692f4f4ab3407f86ecb android.hardware.wifi.supplicant@1.3::ISupplicantStaIface +213457930af81ff3ea344fbc9d4a0d0a2bb70527f96b7b6a32ee3b5e4c17057e android.hardware.wifi.supplicant@1.3::ISupplicantStaIface 619fc9839ec6e369cfa9b28e3e9412e6885720ff8f9b5750c1b6ffb905120391 android.hardware.wifi.supplicant@1.3::ISupplicantStaIfaceCallback -c9273429fcf98d797d3bb07fdba6f1be95bf960f9255cde169fd1ca4db85f856 android.hardware.wifi.supplicant@1.3::ISupplicantStaNetwork +a6163000e2804472924733bcf8b4269db776460cc4df64f9c4dc8350d7aeafc5 android.hardware.wifi.supplicant@1.3::ISupplicantStaNetwork 9b0a3ab6f4f74b971ed094426d8a443e29b512ff03e1ab50c07156396cdb2483 android.hardware.wifi.supplicant@1.3::types 35cd6586225912718c599421606d69260707e43732d874f2064e28de45c87fac android.hardware.radio@1.5::types 3f1e2410d9bed4e7d41c6a589fe3a7943bc904b0066e40e0199a7c58427ac4e9 android.hardware.radio@1.5::IRadio diff --git a/wifi/supplicant/1.3/ISupplicantStaIface.hal b/wifi/supplicant/1.3/ISupplicantStaIface.hal index bfd8946251..fa88b91c6c 100644 --- a/wifi/supplicant/1.3/ISupplicantStaIface.hal +++ b/wifi/supplicant/1.3/ISupplicantStaIface.hal @@ -18,6 +18,7 @@ package android.hardware.wifi.supplicant@1.3; import @1.0::SupplicantStatus; import @1.2::ISupplicantStaIface; +import @1.3::ISupplicantStaNetwork; import ISupplicantStaIfaceCallback; /** @@ -76,4 +77,17 @@ interface ISupplicantStaIface extends @1.2::ISupplicantStaIface { * |SupplicantStatusCode.FAILURE_UNKNOWN| */ setMboCellularDataStatus(bool available) generates (SupplicantStatus status); + + /** + * Get Key management capabilities of the device + * + * @return status Status of the operation, and a bitmap of key management mask. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN| + */ + getKeyMgmtCapabilities_1_3() + generates (SupplicantStatus status, bitfield keyMgmtMask); }; diff --git a/wifi/supplicant/1.3/ISupplicantStaNetwork.hal b/wifi/supplicant/1.3/ISupplicantStaNetwork.hal index ab08cff9c5..1bcf7bcde2 100644 --- a/wifi/supplicant/1.3/ISupplicantStaNetwork.hal +++ b/wifi/supplicant/1.3/ISupplicantStaNetwork.hal @@ -16,6 +16,7 @@ package android.hardware.wifi.supplicant@1.3; +import @1.0::ISupplicantStaNetwork; import @1.0::SupplicantStatus; import @1.2::ISupplicantStaNetwork; @@ -24,6 +25,32 @@ import @1.2::ISupplicantStaNetwork; * configuration it controls. */ interface ISupplicantStaNetwork extends @1.2::ISupplicantStaNetwork { + /** Possble mask of values for Proto param. */ + enum ProtoMask : @1.0::ISupplicantStaNetwork.ProtoMask { + WAPI = 1 << 2, + }; + + /** Possble mask of values for KeyMgmt param. */ + enum KeyMgmtMask : @1.2::ISupplicantStaNetwork.KeyMgmtMask { + /* WAPI Psk */ + WAPI_PSK = 1 << 12, + + /** WAPI Cert */ + WAPI_CERT = 1 << 13, + }; + + /** Possble mask of values for PairwiseCipher param. */ + enum PairwiseCipherMask : @1.2::ISupplicantStaNetwork.PairwiseCipherMask { + /** SMS4 Pairwise Cipher */ + SMS4 = 1 << 7, + }; + + /** Possble mask of values for GroupCipher param. */ + enum GroupCipherMask : @1.2::ISupplicantStaNetwork.GroupCipherMask { + /** SMS4 Group Cipher */ + SMS4 = 1 << 7, + }; + /** * Set OCSP (Online Certificate Status Protocol) type for this network. * @@ -48,6 +75,142 @@ interface ISupplicantStaNetwork extends @1.2::ISupplicantStaNetwork { */ getOcsp() generates (SupplicantStatus status, OcspType ocspType); + /** + * Set key management mask for the network. + * + * @param keyMgmtMask value to set. + * Combination of |KeyMgmtMask| values. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN| + */ + setKeyMgmt_1_3(bitfield keyMgmtMask) generates (SupplicantStatus status); + + /** + * Get the key mgmt mask set for the network. + * + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN| + * @return keyMgmtMask Combination of |KeyMgmtMask| values. + */ + getKeyMgmt_1_3() + generates (SupplicantStatus status, bitfield keyMgmtMask); + + /** + * Set proto mask for the network. + * + * @param protoMask value to set. + * Combination of |ProtoMask| values. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN| + */ + setProto_1_3(bitfield protoMask) generates (SupplicantStatus status); + + /** + * Get the proto mask set for the network. + * + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN| + * @return protoMask Combination of |ProtoMask| values. + */ + getProto_1_3() generates (SupplicantStatus status, bitfield protoMask); + + /** + * Set group cipher mask for the network. + * + * @param groupCipherMask value to set. + * Combination of |ProtoMask| values. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN| + */ + setGroupCipher_1_3(bitfield groupCipherMask) + generates (SupplicantStatus status); + + /** + * Get the pairwise cipher mask set for the network. + * + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN| + * @return pairwiseCipherMask Combination of |PairwiseCipherMask| values. + */ + getPairwiseCipher_1_3() + generates (SupplicantStatus status, + bitfield pairwiseCipherMask); + + /** + * Set pairwise cipher mask for the network. + * + * @param pairwiseCipherMask value to set. + * Combination of |ProtoMask| values. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN| + */ + setPairwiseCipher_1_3(bitfield pairwiseCipherMask) + generates (SupplicantStatus status); + + /** + * Get the group cipher mask set for the network. + * + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN| + * @return groupCipherMask Combination of |GroupCipherMask| values. + */ + getGroupCipher_1_3() + generates (SupplicantStatus status, + bitfield groupCipherMask); + + /** + * Set WAPI certificate suite for this network. + * + * @param suite value to set. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN| + */ + setWapiCertSuite(string suite) generates (SupplicantStatus status); + + /** + * Get WAPI certificate suite set for this network. + * + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN| + * @return suite The name of a suite. + */ + getWapiCertSuite() generates (SupplicantStatus status, string suite); + /** * Add a PMK into supplicant PMK cache. * diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp index 2cf58813ad..ca3265e960 100644 --- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -227,3 +227,22 @@ TEST_F(SupplicantStaIfaceHidlTest, SetMboCellularDataStatus) { EXPECT_EQ(expectedStatusCode, status.code); }); } + +/* + * GetKeyMgmtCapabilities_1_3 + */ +TEST_F(SupplicantStaIfaceHidlTest, GetKeyMgmtCapabilities_1_3) { + sta_iface_->getKeyMgmtCapabilities_1_3([&](const SupplicantStatus& status, + uint32_t keyMgmtMask) { + if (SupplicantStatusCode::SUCCESS != status.code) { + // for unsupport case + EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + } else { + // Even though capabilities vary, these two are always set in HAL + // v1.3 + EXPECT_TRUE(keyMgmtMask & ISupplicantStaNetwork::KeyMgmtMask::NONE); + EXPECT_TRUE(keyMgmtMask & + ISupplicantStaNetwork::KeyMgmtMask::IEEE8021X); + } + }); +} diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp index 07bc9d8103..d6f55f54fc 100644 --- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp +++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp @@ -17,15 +17,18 @@ #include #include +#include #include #include "supplicant_hidl_test_utils.h" #include "supplicant_hidl_test_utils_1_3.h" using ::android::sp; +using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus; using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; +using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface; using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaNetwork; using ::android::hardware::wifi::supplicant::V1_3::OcspType; namespace { @@ -39,15 +42,37 @@ class SupplicantStaNetworkHidlTest virtual void SetUp() override { startSupplicantAndWaitForHidlService(); EXPECT_TRUE(turnOnExcessiveLogging()); + sta_iface_ = getSupplicantStaIface_1_3(); + ASSERT_NE(nullptr, sta_iface_.get()); sta_network_ = createSupplicantStaNetwork_1_3(); - ASSERT_NE(sta_network_.get(), nullptr); + ASSERT_NE(nullptr, sta_network_.get()); } virtual void TearDown() override { stopSupplicant(); } protected: + sp sta_iface_; // ISupplicantStaNetwork object used for all tests in this fixture. sp sta_network_; + + bool isWapiSupported() { + uint32_t keyMgmtMask = 0; + + // We need to first get the key management capabilities from the device. + // If WAPI is not supported, we just pass the test. + sta_iface_->getKeyMgmtCapabilities_1_3( + [&](const SupplicantStatus &status, uint32_t keyMgmtMaskInternal) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + keyMgmtMask = keyMgmtMaskInternal; + }); + + if (!(keyMgmtMask & ISupplicantStaNetwork::KeyMgmtMask::WAPI_PSK)) { + // WAPI not supported + return false; + } + + return true; + } }; /* @@ -84,3 +109,160 @@ TEST_F(SupplicantStaNetworkHidlTest, SetPmkCache) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); } + +/* + * SetGetKeyMgmt_1_3, check new WAPI proto support + */ +TEST_F(SupplicantStaNetworkHidlTest, SetGetKeyMgmt_1_3) { + uint32_t keyMgmt = (uint32_t)ISupplicantStaNetwork::KeyMgmtMask::WAPI_PSK; + + sta_network_->setKeyMgmt_1_3(keyMgmt, [](const SupplicantStatus &status) { + if (SupplicantStatusCode::SUCCESS != status.code) { + // for unsupport case + EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + } + }); + + sta_network_->getKeyMgmt_1_3( + [&keyMgmt](const SupplicantStatus &status, uint32_t keyMgmtOut) { + if (SupplicantStatusCode::SUCCESS != status.code) { + // for unsupport case + EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + } else { + EXPECT_EQ(keyMgmtOut, keyMgmt); + } + }); + + keyMgmt = (uint32_t)ISupplicantStaNetwork::KeyMgmtMask::WAPI_CERT; + sta_network_->setKeyMgmt_1_3(keyMgmt, [](const SupplicantStatus &status) { + if (SupplicantStatusCode::SUCCESS != status.code) { + // for unsupport case + EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + } + }); + + sta_network_->getKeyMgmt_1_3( + [&keyMgmt](const SupplicantStatus &status, uint32_t keyMgmtOut) { + if (SupplicantStatusCode::SUCCESS != status.code) { + // for unsupport case + EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + } else { + EXPECT_EQ(keyMgmtOut, keyMgmt); + } + }); +} + +/* + * SetGetProto_1_3, check new WAPI proto support + */ +TEST_F(SupplicantStaNetworkHidlTest, SetGetProto_1_3) { + uint32_t wapiProto = (uint32_t)ISupplicantStaNetwork::ProtoMask::WAPI; + sta_network_->setProto(wapiProto, [](const SupplicantStatus &status) { + if (SupplicantStatusCode::SUCCESS != status.code) { + // for unsupport case + EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + } + }); + sta_network_->getProto([&](const SupplicantStatus &status, uint32_t proto) { + if (SupplicantStatusCode::SUCCESS != status.code) { + // for unsupport case + EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + } else { + EXPECT_EQ(proto, wapiProto); + } + }); +} + +/* + * SetGetGroupCipher_1_3, check new WAPI support + */ +TEST_F(SupplicantStaNetworkHidlTest, SetGetGroupCipher_1_3) { + uint32_t groupCipher = + (uint32_t)ISupplicantStaNetwork::GroupCipherMask::SMS4; + + sta_network_->setGroupCipher_1_3( + groupCipher, [](const SupplicantStatus &status) { + if (SupplicantStatusCode::SUCCESS != status.code) { + // for unsupport case + EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + } + }); + + sta_network_->getGroupCipher_1_3( + [&groupCipher](const SupplicantStatus &status, + uint32_t groupCipherOut) { + if (SupplicantStatusCode::SUCCESS != status.code) { + // for unsupport case + EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + } else { + EXPECT_EQ(groupCipherOut, groupCipher); + } + }); +} + +/* + * SetGetPairwiseCipher_1_3, check new WAPI support + */ +TEST_F(SupplicantStaNetworkHidlTest, SetGetPairwiseCipher_1_3) { + uint32_t pairwiseCipher = + (uint32_t)ISupplicantStaNetwork::PairwiseCipherMask::SMS4; + + sta_network_->setPairwiseCipher_1_3( + pairwiseCipher, [](const SupplicantStatus &status) { + if (SupplicantStatusCode::SUCCESS != status.code) { + // for unsupport case + EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + } + }); + + sta_network_->getPairwiseCipher_1_3( + [&pairwiseCipher](const SupplicantStatus &status, + uint32_t pairwiseCipherOut) { + if (SupplicantStatusCode::SUCCESS != status.code) { + // for unsupport case + EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + } else { + EXPECT_EQ(pairwiseCipherOut, pairwiseCipher); + } + }); +} + +/* + * SetGetWapiCertSuite + */ +TEST_F(SupplicantStaNetworkHidlTest, SetGetWapiCertSuite) { + hidl_string testWapiCertSuite = "suite"; + + if (isWapiSupported()) { + sta_network_->setWapiCertSuite( + testWapiCertSuite, [](const SupplicantStatus &status) { + if (SupplicantStatusCode::SUCCESS != status.code) { + // for unsupport case + EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, + status.code); + } + }); + + sta_network_->getWapiCertSuite([testWapiCertSuite]( + const SupplicantStatus &status, + const hidl_string &wapiCertSuite) { + if (SupplicantStatusCode::SUCCESS != status.code) { + // for unsupport case + EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + } else { + EXPECT_EQ(testWapiCertSuite, wapiCertSuite); + } + }); + } else { + sta_network_->setWapiCertSuite( + testWapiCertSuite, [](const SupplicantStatus &status) { + EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + }); + + sta_network_->getWapiCertSuite( + [testWapiCertSuite](const SupplicantStatus &status, + const hidl_string &wapiCertSuite __unused) { + EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + }); + } +}