1/*
2 * hidl interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
4 * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
5 *
6 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
8 */
9
10#include "hidl_manager.h"
11#include "hidl_return_util.h"
12#include "misc_utils.h"
13#include "sta_network.h"
14
15extern "C" {
16#include "wps_supplicant.h"
17}
18
19namespace {
20using android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
21using android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
22
23constexpr uint8_t kZeroBssid[6] = {0, 0, 0, 0, 0, 0};
24
25constexpr uint32_t kAllowedKeyMgmtMask =
26    (static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::NONE) |
27     static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::WPA_PSK) |
28     static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::WPA_EAP) |
29     static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::IEEE8021X) |
30     static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::FT_EAP) |
31     static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::FT_PSK) |
32     static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::OSEN));
33constexpr uint32_t kAllowedProtoMask =
34    (static_cast<uint32_t>(ISupplicantStaNetwork::ProtoMask::WPA) |
35     static_cast<uint32_t>(ISupplicantStaNetwork::ProtoMask::RSN) |
36     static_cast<uint32_t>(ISupplicantStaNetwork::ProtoMask::OSEN));
37constexpr uint32_t kAllowedAuthAlgMask =
38    (static_cast<uint32_t>(ISupplicantStaNetwork::AuthAlgMask::OPEN) |
39     static_cast<uint32_t>(ISupplicantStaNetwork::AuthAlgMask::SHARED) |
40     static_cast<uint32_t>(ISupplicantStaNetwork::AuthAlgMask::LEAP));
41constexpr uint32_t kAllowedGroupCipherMask =
42    (static_cast<uint32_t>(ISupplicantStaNetwork::GroupCipherMask::WEP40) |
43     static_cast<uint32_t>(ISupplicantStaNetwork::GroupCipherMask::WEP104) |
44     static_cast<uint32_t>(ISupplicantStaNetwork::GroupCipherMask::TKIP) |
45     static_cast<uint32_t>(ISupplicantStaNetwork::GroupCipherMask::CCMP) |
46     static_cast<uint32_t>(
47	 ISupplicantStaNetwork::GroupCipherMask::GTK_NOT_USED));
48constexpr uint32_t kAllowedPairwisewCipherMask =
49    (static_cast<uint32_t>(ISupplicantStaNetwork::PairwiseCipherMask::NONE) |
50     static_cast<uint32_t>(ISupplicantStaNetwork::PairwiseCipherMask::TKIP) |
51     static_cast<uint32_t>(ISupplicantStaNetwork::PairwiseCipherMask::CCMP));
52
53constexpr uint32_t kEapMethodMax =
54    static_cast<uint32_t>(ISupplicantStaNetwork::EapMethod::WFA_UNAUTH_TLS) + 1;
55constexpr char const *kEapMethodStrings[kEapMethodMax] = {
56    "PEAP", "TLS", "TTLS", "PWD", "SIM", "AKA", "AKA'", "WFA-UNAUTH-TLS"};
57constexpr uint32_t kEapPhase2MethodMax =
58    static_cast<uint32_t>(ISupplicantStaNetwork::EapPhase2Method::AKA_PRIME) +
59    1;
60constexpr char const *kEapPhase2MethodStrings[kEapPhase2MethodMax] = {
61    "", "PAP", "MSCHAP", "MSCHAPV2", "GTC", "SIM", "AKA", "AKA'"};
62constexpr char kEapPhase2AuthPrefix[] = "auth=";
63constexpr char kEapPhase2AuthEapPrefix[] = "autheap=";
64constexpr char kNetworkEapSimGsmAuthResponse[] = "GSM-AUTH";
65constexpr char kNetworkEapSimUmtsAuthResponse[] = "UMTS-AUTH";
66constexpr char kNetworkEapSimUmtsAutsResponse[] = "UMTS-AUTS";
67constexpr char kNetworkEapSimGsmAuthFailure[] = "GSM-FAIL";
68constexpr char kNetworkEapSimUmtsAuthFailure[] = "UMTS-FAIL";
69}  // namespace
70
71namespace android {
72namespace hardware {
73namespace wifi {
74namespace supplicant {
75namespace V1_0 {
76namespace implementation {
77using hidl_return_util::validateAndCall;
78
79StaNetwork::StaNetwork(
80    struct wpa_global *wpa_global, const char ifname[], int network_id)
81    : wpa_global_(wpa_global),
82      ifname_(ifname),
83      network_id_(network_id),
84      is_valid_(true)
85{
86}
87
88void StaNetwork::invalidate() { is_valid_ = false; }
89bool StaNetwork::isValid()
90{
91	return (is_valid_ && (retrieveNetworkPtr() != nullptr));
92}
93
94Return<void> StaNetwork::getId(getId_cb _hidl_cb)
95{
96	return validateAndCall(
97	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
98	    &StaNetwork::getIdInternal, _hidl_cb);
99}
100
101Return<void> StaNetwork::getInterfaceName(getInterfaceName_cb _hidl_cb)
102{
103	return validateAndCall(
104	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
105	    &StaNetwork::getInterfaceNameInternal, _hidl_cb);
106}
107
108Return<void> StaNetwork::getType(getType_cb _hidl_cb)
109{
110	return validateAndCall(
111	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
112	    &StaNetwork::getTypeInternal, _hidl_cb);
113}
114
115Return<void> StaNetwork::registerCallback(
116    const sp<ISupplicantStaNetworkCallback> &callback,
117    registerCallback_cb _hidl_cb)
118{
119	return validateAndCall(
120	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
121	    &StaNetwork::registerCallbackInternal, _hidl_cb, callback);
122}
123
124Return<void> StaNetwork::setSsid(
125    const hidl_vec<uint8_t> &ssid, setSsid_cb _hidl_cb)
126{
127	return validateAndCall(
128	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
129	    &StaNetwork::setSsidInternal, _hidl_cb, ssid);
130}
131
132Return<void> StaNetwork::setBssid(
133    const hidl_array<uint8_t, 6> &bssid, setBssid_cb _hidl_cb)
134{
135	return validateAndCall(
136	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
137	    &StaNetwork::setBssidInternal, _hidl_cb, bssid);
138}
139
140Return<void> StaNetwork::setScanSsid(bool enable, setScanSsid_cb _hidl_cb)
141{
142	return validateAndCall(
143	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
144	    &StaNetwork::setScanSsidInternal, _hidl_cb, enable);
145}
146
147Return<void> StaNetwork::setKeyMgmt(
148    uint32_t key_mgmt_mask, setKeyMgmt_cb _hidl_cb)
149{
150	return validateAndCall(
151	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
152	    &StaNetwork::setKeyMgmtInternal, _hidl_cb, key_mgmt_mask);
153}
154
155Return<void> StaNetwork::setProto(uint32_t proto_mask, setProto_cb _hidl_cb)
156{
157	return validateAndCall(
158	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
159	    &StaNetwork::setProtoInternal, _hidl_cb, proto_mask);
160}
161
162Return<void> StaNetwork::setAuthAlg(
163    uint32_t auth_alg_mask,
164    std::function<void(const SupplicantStatus &status)> _hidl_cb)
165{
166	return validateAndCall(
167	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
168	    &StaNetwork::setAuthAlgInternal, _hidl_cb, auth_alg_mask);
169}
170
171Return<void> StaNetwork::setGroupCipher(
172    uint32_t group_cipher_mask, setGroupCipher_cb _hidl_cb)
173{
174	return validateAndCall(
175	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
176	    &StaNetwork::setGroupCipherInternal, _hidl_cb, group_cipher_mask);
177}
178
179Return<void> StaNetwork::setPairwiseCipher(
180    uint32_t pairwise_cipher_mask, setPairwiseCipher_cb _hidl_cb)
181{
182	return validateAndCall(
183	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
184	    &StaNetwork::setPairwiseCipherInternal, _hidl_cb,
185	    pairwise_cipher_mask);
186}
187
188Return<void> StaNetwork::setPskPassphrase(
189    const hidl_string &psk, setPskPassphrase_cb _hidl_cb)
190{
191	return validateAndCall(
192	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
193	    &StaNetwork::setPskPassphraseInternal, _hidl_cb, psk);
194}
195
196Return<void> StaNetwork::setPsk(
197    const hidl_array<uint8_t, 32> &psk, setPsk_cb _hidl_cb)
198{
199	return validateAndCall(
200	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
201	    &StaNetwork::setPskInternal, _hidl_cb, psk);
202}
203
204Return<void> StaNetwork::setWepKey(
205    uint32_t key_idx, const hidl_vec<uint8_t> &wep_key, setWepKey_cb _hidl_cb)
206{
207	return validateAndCall(
208	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
209	    &StaNetwork::setWepKeyInternal, _hidl_cb, key_idx, wep_key);
210}
211
212Return<void> StaNetwork::setWepTxKeyIdx(
213    uint32_t key_idx, setWepTxKeyIdx_cb _hidl_cb)
214{
215	return validateAndCall(
216	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
217	    &StaNetwork::setWepTxKeyIdxInternal, _hidl_cb, key_idx);
218}
219
220Return<void> StaNetwork::setRequirePmf(bool enable, setRequirePmf_cb _hidl_cb)
221{
222	return validateAndCall(
223	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
224	    &StaNetwork::setRequirePmfInternal, _hidl_cb, enable);
225}
226
227Return<void> StaNetwork::setEapMethod(
228    ISupplicantStaNetwork::EapMethod method, setEapMethod_cb _hidl_cb)
229{
230	return validateAndCall(
231	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
232	    &StaNetwork::setEapMethodInternal, _hidl_cb, method);
233}
234
235Return<void> StaNetwork::setEapPhase2Method(
236    ISupplicantStaNetwork::EapPhase2Method method,
237    setEapPhase2Method_cb _hidl_cb)
238{
239	return validateAndCall(
240	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
241	    &StaNetwork::setEapPhase2MethodInternal, _hidl_cb, method);
242}
243
244Return<void> StaNetwork::setEapIdentity(
245    const hidl_vec<uint8_t> &identity, setEapIdentity_cb _hidl_cb)
246{
247	return validateAndCall(
248	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
249	    &StaNetwork::setEapIdentityInternal, _hidl_cb, identity);
250}
251
252Return<void> StaNetwork::setEapAnonymousIdentity(
253    const hidl_vec<uint8_t> &identity, setEapAnonymousIdentity_cb _hidl_cb)
254{
255	return validateAndCall(
256	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
257	    &StaNetwork::setEapAnonymousIdentityInternal, _hidl_cb, identity);
258}
259
260Return<void> StaNetwork::setEapPassword(
261    const hidl_vec<uint8_t> &password, setEapPassword_cb _hidl_cb)
262{
263	return validateAndCall(
264	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
265	    &StaNetwork::setEapPasswordInternal, _hidl_cb, password);
266}
267
268Return<void> StaNetwork::setEapCACert(
269    const hidl_string &path, setEapCACert_cb _hidl_cb)
270{
271	return validateAndCall(
272	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
273	    &StaNetwork::setEapCACertInternal, _hidl_cb, path);
274}
275
276Return<void> StaNetwork::setEapCAPath(
277    const hidl_string &path, setEapCAPath_cb _hidl_cb)
278{
279	return validateAndCall(
280	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
281	    &StaNetwork::setEapCAPathInternal, _hidl_cb, path);
282}
283
284Return<void> StaNetwork::setEapClientCert(
285    const hidl_string &path, setEapClientCert_cb _hidl_cb)
286{
287	return validateAndCall(
288	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
289	    &StaNetwork::setEapClientCertInternal, _hidl_cb, path);
290}
291
292Return<void> StaNetwork::setEapPrivateKeyId(
293    const hidl_string &id, setEapPrivateKeyId_cb _hidl_cb)
294{
295	return validateAndCall(
296	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
297	    &StaNetwork::setEapPrivateKeyIdInternal, _hidl_cb, id);
298}
299
300Return<void> StaNetwork::setEapSubjectMatch(
301    const hidl_string &match, setEapSubjectMatch_cb _hidl_cb)
302{
303	return validateAndCall(
304	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
305	    &StaNetwork::setEapSubjectMatchInternal, _hidl_cb, match);
306}
307
308Return<void> StaNetwork::setEapAltSubjectMatch(
309    const hidl_string &match, setEapAltSubjectMatch_cb _hidl_cb)
310{
311	return validateAndCall(
312	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
313	    &StaNetwork::setEapAltSubjectMatchInternal, _hidl_cb, match);
314}
315
316Return<void> StaNetwork::setEapEngine(bool enable, setEapEngine_cb _hidl_cb)
317{
318	return validateAndCall(
319	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
320	    &StaNetwork::setEapEngineInternal, _hidl_cb, enable);
321}
322
323Return<void> StaNetwork::setEapEngineID(
324    const hidl_string &id, setEapEngineID_cb _hidl_cb)
325{
326	return validateAndCall(
327	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
328	    &StaNetwork::setEapEngineIDInternal, _hidl_cb, id);
329}
330
331Return<void> StaNetwork::setEapDomainSuffixMatch(
332    const hidl_string &match, setEapDomainSuffixMatch_cb _hidl_cb)
333{
334	return validateAndCall(
335	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
336	    &StaNetwork::setEapDomainSuffixMatchInternal, _hidl_cb, match);
337}
338
339Return<void> StaNetwork::setProactiveKeyCaching(
340    bool enable, setProactiveKeyCaching_cb _hidl_cb)
341{
342	return validateAndCall(
343	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
344	    &StaNetwork::setProactiveKeyCachingInternal, _hidl_cb, enable);
345}
346
347Return<void> StaNetwork::setIdStr(
348    const hidl_string &id_str, setIdStr_cb _hidl_cb)
349{
350	return validateAndCall(
351	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
352	    &StaNetwork::setIdStrInternal, _hidl_cb, id_str);
353}
354
355Return<void> StaNetwork::setUpdateIdentifier(
356    uint32_t id, setUpdateIdentifier_cb _hidl_cb)
357{
358	return validateAndCall(
359	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
360	    &StaNetwork::setUpdateIdentifierInternal, _hidl_cb, id);
361}
362
363Return<void> StaNetwork::getSsid(getSsid_cb _hidl_cb)
364{
365	return validateAndCall(
366	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
367	    &StaNetwork::getSsidInternal, _hidl_cb);
368}
369
370Return<void> StaNetwork::getBssid(getBssid_cb _hidl_cb)
371{
372	return validateAndCall(
373	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
374	    &StaNetwork::getBssidInternal, _hidl_cb);
375}
376
377Return<void> StaNetwork::getScanSsid(getScanSsid_cb _hidl_cb)
378{
379	return validateAndCall(
380	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
381	    &StaNetwork::getScanSsidInternal, _hidl_cb);
382}
383
384Return<void> StaNetwork::getKeyMgmt(getKeyMgmt_cb _hidl_cb)
385{
386	return validateAndCall(
387	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
388	    &StaNetwork::getKeyMgmtInternal, _hidl_cb);
389}
390
391Return<void> StaNetwork::getProto(getProto_cb _hidl_cb)
392{
393	return validateAndCall(
394	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
395	    &StaNetwork::getProtoInternal, _hidl_cb);
396}
397
398Return<void> StaNetwork::getAuthAlg(getAuthAlg_cb _hidl_cb)
399{
400	return validateAndCall(
401	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
402	    &StaNetwork::getAuthAlgInternal, _hidl_cb);
403}
404
405Return<void> StaNetwork::getGroupCipher(getGroupCipher_cb _hidl_cb)
406{
407	return validateAndCall(
408	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
409	    &StaNetwork::getGroupCipherInternal, _hidl_cb);
410}
411
412Return<void> StaNetwork::getPairwiseCipher(getPairwiseCipher_cb _hidl_cb)
413{
414	return validateAndCall(
415	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
416	    &StaNetwork::getPairwiseCipherInternal, _hidl_cb);
417}
418
419Return<void> StaNetwork::getPskPassphrase(getPskPassphrase_cb _hidl_cb)
420{
421	return validateAndCall(
422	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
423	    &StaNetwork::getPskPassphraseInternal, _hidl_cb);
424}
425
426Return<void> StaNetwork::getPsk(getPsk_cb _hidl_cb)
427{
428	return validateAndCall(
429	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
430	    &StaNetwork::getPskInternal, _hidl_cb);
431}
432
433Return<void> StaNetwork::getWepKey(uint32_t key_idx, getWepKey_cb _hidl_cb)
434{
435	return validateAndCall(
436	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
437	    &StaNetwork::getWepKeyInternal, _hidl_cb, key_idx);
438}
439
440Return<void> StaNetwork::getWepTxKeyIdx(getWepTxKeyIdx_cb _hidl_cb)
441{
442	return validateAndCall(
443	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
444	    &StaNetwork::getWepTxKeyIdxInternal, _hidl_cb);
445}
446
447Return<void> StaNetwork::getRequirePmf(getRequirePmf_cb _hidl_cb)
448{
449	return validateAndCall(
450	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
451	    &StaNetwork::getRequirePmfInternal, _hidl_cb);
452}
453
454Return<void> StaNetwork::getEapMethod(getEapMethod_cb _hidl_cb)
455{
456	return validateAndCall(
457	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
458	    &StaNetwork::getEapMethodInternal, _hidl_cb);
459}
460
461Return<void> StaNetwork::getEapPhase2Method(getEapPhase2Method_cb _hidl_cb)
462{
463	return validateAndCall(
464	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
465	    &StaNetwork::getEapPhase2MethodInternal, _hidl_cb);
466}
467
468Return<void> StaNetwork::getEapIdentity(getEapIdentity_cb _hidl_cb)
469{
470	return validateAndCall(
471	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
472	    &StaNetwork::getEapIdentityInternal, _hidl_cb);
473}
474
475Return<void> StaNetwork::getEapAnonymousIdentity(
476    getEapAnonymousIdentity_cb _hidl_cb)
477{
478	return validateAndCall(
479	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
480	    &StaNetwork::getEapAnonymousIdentityInternal, _hidl_cb);
481}
482
483Return<void> StaNetwork::getEapPassword(getEapPassword_cb _hidl_cb)
484{
485	return validateAndCall(
486	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
487	    &StaNetwork::getEapPasswordInternal, _hidl_cb);
488}
489
490Return<void> StaNetwork::getEapCACert(getEapCACert_cb _hidl_cb)
491{
492	return validateAndCall(
493	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
494	    &StaNetwork::getEapCACertInternal, _hidl_cb);
495}
496
497Return<void> StaNetwork::getEapCAPath(getEapCAPath_cb _hidl_cb)
498{
499	return validateAndCall(
500	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
501	    &StaNetwork::getEapCAPathInternal, _hidl_cb);
502}
503
504Return<void> StaNetwork::getEapClientCert(getEapClientCert_cb _hidl_cb)
505{
506	return validateAndCall(
507	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
508	    &StaNetwork::getEapClientCertInternal, _hidl_cb);
509}
510
511Return<void> StaNetwork::getEapPrivateKeyId(getEapPrivateKeyId_cb _hidl_cb)
512{
513	return validateAndCall(
514	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
515	    &StaNetwork::getEapPrivateKeyIdInternal, _hidl_cb);
516}
517
518Return<void> StaNetwork::getEapSubjectMatch(getEapSubjectMatch_cb _hidl_cb)
519{
520	return validateAndCall(
521	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
522	    &StaNetwork::getEapSubjectMatchInternal, _hidl_cb);
523}
524
525Return<void> StaNetwork::getEapAltSubjectMatch(
526    getEapAltSubjectMatch_cb _hidl_cb)
527{
528	return validateAndCall(
529	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
530	    &StaNetwork::getEapAltSubjectMatchInternal, _hidl_cb);
531}
532
533Return<void> StaNetwork::getEapEngine(getEapEngine_cb _hidl_cb)
534{
535	return validateAndCall(
536	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
537	    &StaNetwork::getEapEngineInternal, _hidl_cb);
538}
539
540Return<void> StaNetwork::getEapEngineID(getEapEngineID_cb _hidl_cb)
541{
542	return validateAndCall(
543	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
544	    &StaNetwork::getEapEngineIDInternal, _hidl_cb);
545}
546
547Return<void> StaNetwork::getEapDomainSuffixMatch(
548    getEapDomainSuffixMatch_cb _hidl_cb)
549{
550	return validateAndCall(
551	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
552	    &StaNetwork::getEapDomainSuffixMatchInternal, _hidl_cb);
553}
554
555Return<void> StaNetwork::getIdStr(getIdStr_cb _hidl_cb)
556{
557	return validateAndCall(
558	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
559	    &StaNetwork::getIdStrInternal, _hidl_cb);
560}
561
562Return<void> StaNetwork::getWpsNfcConfigurationToken(
563    getWpsNfcConfigurationToken_cb _hidl_cb)
564{
565	return validateAndCall(
566	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
567	    &StaNetwork::getWpsNfcConfigurationTokenInternal, _hidl_cb);
568}
569
570Return<void> StaNetwork::enable(bool no_connect, enable_cb _hidl_cb)
571{
572	return validateAndCall(
573	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
574	    &StaNetwork::enableInternal, _hidl_cb, no_connect);
575}
576
577Return<void> StaNetwork::disable(disable_cb _hidl_cb)
578{
579	return validateAndCall(
580	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
581	    &StaNetwork::disableInternal, _hidl_cb);
582}
583
584Return<void> StaNetwork::select(select_cb _hidl_cb)
585{
586	return validateAndCall(
587	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
588	    &StaNetwork::selectInternal, _hidl_cb);
589}
590
591Return<void> StaNetwork::sendNetworkEapSimGsmAuthResponse(
592    const hidl_vec<ISupplicantStaNetwork::NetworkResponseEapSimGsmAuthParams>
593	&vec_params,
594    sendNetworkEapSimGsmAuthResponse_cb _hidl_cb)
595{
596	return validateAndCall(
597	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
598	    &StaNetwork::sendNetworkEapSimGsmAuthResponseInternal, _hidl_cb,
599	    vec_params);
600}
601
602Return<void> StaNetwork::sendNetworkEapSimGsmAuthFailure(
603    sendNetworkEapSimGsmAuthFailure_cb _hidl_cb)
604{
605	return validateAndCall(
606	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
607	    &StaNetwork::sendNetworkEapSimGsmAuthFailureInternal, _hidl_cb);
608}
609
610Return<void> StaNetwork::sendNetworkEapSimUmtsAuthResponse(
611    const ISupplicantStaNetwork::NetworkResponseEapSimUmtsAuthParams &params,
612    sendNetworkEapSimUmtsAuthResponse_cb _hidl_cb)
613{
614	return validateAndCall(
615	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
616	    &StaNetwork::sendNetworkEapSimUmtsAuthResponseInternal, _hidl_cb,
617	    params);
618}
619
620Return<void> StaNetwork::sendNetworkEapSimUmtsAutsResponse(
621    const hidl_array<uint8_t, 14> &auts,
622    sendNetworkEapSimUmtsAutsResponse_cb _hidl_cb)
623{
624	return validateAndCall(
625	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
626	    &StaNetwork::sendNetworkEapSimUmtsAutsResponseInternal, _hidl_cb,
627	    auts);
628}
629
630Return<void> StaNetwork::sendNetworkEapSimUmtsAuthFailure(
631    sendNetworkEapSimUmtsAuthFailure_cb _hidl_cb)
632{
633	return validateAndCall(
634	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
635	    &StaNetwork::sendNetworkEapSimUmtsAuthFailureInternal, _hidl_cb);
636}
637
638Return<void> StaNetwork::sendNetworkEapIdentityResponse(
639    const hidl_vec<uint8_t> &identity,
640    sendNetworkEapIdentityResponse_cb _hidl_cb)
641{
642	return validateAndCall(
643	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
644	    &StaNetwork::sendNetworkEapIdentityResponseInternal, _hidl_cb,
645	    identity);
646}
647
648std::pair<SupplicantStatus, uint32_t> StaNetwork::getIdInternal()
649{
650	return {{SupplicantStatusCode::SUCCESS, ""}, network_id_};
651}
652
653std::pair<SupplicantStatus, std::string> StaNetwork::getInterfaceNameInternal()
654{
655	return {{SupplicantStatusCode::SUCCESS, ""}, ifname_};
656}
657
658std::pair<SupplicantStatus, IfaceType> StaNetwork::getTypeInternal()
659{
660	return {{SupplicantStatusCode::SUCCESS, ""}, IfaceType::STA};
661}
662
663SupplicantStatus StaNetwork::registerCallbackInternal(
664    const sp<ISupplicantStaNetworkCallback> &callback)
665{
666	HidlManager *hidl_manager = HidlManager::getInstance();
667	if (!hidl_manager ||
668	    hidl_manager->addStaNetworkCallbackHidlObject(
669		ifname_, network_id_, callback)) {
670		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
671	}
672	return {SupplicantStatusCode::SUCCESS, ""};
673}
674
675SupplicantStatus StaNetwork::setSsidInternal(const std::vector<uint8_t> &ssid)
676{
677	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
678	if (ssid.size() == 0 ||
679	    ssid.size() >
680		static_cast<uint32_t>(ISupplicantStaNetwork::ParamSizeLimits::
681					  SSID_MAX_LEN_IN_BYTES)) {
682		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
683	}
684	if (setByteArrayFieldAndResetState(
685		ssid.data(), ssid.size(), &(wpa_ssid->ssid),
686		&(wpa_ssid->ssid_len), "ssid")) {
687		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
688	}
689	if (wpa_ssid->passphrase) {
690		wpa_config_update_psk(wpa_ssid);
691	}
692	return {SupplicantStatusCode::SUCCESS, ""};
693}
694
695SupplicantStatus StaNetwork::setBssidInternal(
696    const std::array<uint8_t, 6> &bssid)
697{
698	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
699	int prev_bssid_set = wpa_ssid->bssid_set;
700	u8 prev_bssid[ETH_ALEN];
701	os_memcpy(prev_bssid, wpa_ssid->bssid, ETH_ALEN);
702	// Zero'ed array is used to clear out the BSSID value.
703	if (os_memcmp(bssid.data(), kZeroBssid, ETH_ALEN) == 0) {
704		wpa_ssid->bssid_set = 0;
705		wpa_printf(MSG_MSGDUMP, "BSSID any");
706	} else {
707		os_memcpy(wpa_ssid->bssid, bssid.data(), ETH_ALEN);
708		wpa_ssid->bssid_set = 1;
709		wpa_hexdump(MSG_MSGDUMP, "BSSID", wpa_ssid->bssid, ETH_ALEN);
710	}
711	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
712	if ((wpa_ssid->bssid_set != prev_bssid_set ||
713	     os_memcmp(wpa_ssid->bssid, prev_bssid, ETH_ALEN) != 0)) {
714		wpas_notify_network_bssid_set_changed(wpa_s, wpa_ssid);
715	}
716	return {SupplicantStatusCode::SUCCESS, ""};
717}
718
719SupplicantStatus StaNetwork::setScanSsidInternal(bool enable)
720{
721	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
722	wpa_ssid->scan_ssid = enable ? 1 : 0;
723	resetInternalStateAfterParamsUpdate();
724	return {SupplicantStatusCode::SUCCESS, ""};
725}
726
727SupplicantStatus StaNetwork::setKeyMgmtInternal(uint32_t key_mgmt_mask)
728{
729	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
730	if (key_mgmt_mask & ~kAllowedKeyMgmtMask) {
731		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
732	}
733	wpa_ssid->key_mgmt = key_mgmt_mask;
734	wpa_printf(MSG_MSGDUMP, "key_mgmt: 0x%x", wpa_ssid->key_mgmt);
735	resetInternalStateAfterParamsUpdate();
736	return {SupplicantStatusCode::SUCCESS, ""};
737}
738
739SupplicantStatus StaNetwork::setProtoInternal(uint32_t proto_mask)
740{
741	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
742	if (proto_mask & ~kAllowedProtoMask) {
743		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
744	}
745	wpa_ssid->proto = proto_mask;
746	wpa_printf(MSG_MSGDUMP, "proto: 0x%x", wpa_ssid->proto);
747	resetInternalStateAfterParamsUpdate();
748	return {SupplicantStatusCode::SUCCESS, ""};
749}
750
751SupplicantStatus StaNetwork::setAuthAlgInternal(uint32_t auth_alg_mask)
752{
753	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
754	if (auth_alg_mask & ~kAllowedAuthAlgMask) {
755		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
756	}
757	wpa_ssid->auth_alg = auth_alg_mask;
758	wpa_printf(MSG_MSGDUMP, "auth_alg: 0x%x", wpa_ssid->auth_alg);
759	resetInternalStateAfterParamsUpdate();
760	return {SupplicantStatusCode::SUCCESS, ""};
761}
762
763SupplicantStatus StaNetwork::setGroupCipherInternal(uint32_t group_cipher_mask)
764{
765	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
766	if (group_cipher_mask & ~kAllowedGroupCipherMask) {
767		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
768	}
769	wpa_ssid->group_cipher = group_cipher_mask;
770	wpa_printf(MSG_MSGDUMP, "group_cipher: 0x%x", wpa_ssid->group_cipher);
771	resetInternalStateAfterParamsUpdate();
772	return {SupplicantStatusCode::SUCCESS, ""};
773}
774
775SupplicantStatus StaNetwork::setPairwiseCipherInternal(
776    uint32_t pairwise_cipher_mask)
777{
778	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
779	if (pairwise_cipher_mask & ~kAllowedPairwisewCipherMask) {
780		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
781	}
782	wpa_ssid->pairwise_cipher = pairwise_cipher_mask;
783	wpa_printf(
784	    MSG_MSGDUMP, "pairwise_cipher: 0x%x", wpa_ssid->pairwise_cipher);
785	resetInternalStateAfterParamsUpdate();
786	return {SupplicantStatusCode::SUCCESS, ""};
787}
788
789SupplicantStatus StaNetwork::setPskPassphraseInternal(const std::string &psk)
790{
791	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
792	if (isPskPassphraseValid(psk)) {
793		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
794	}
795	if (wpa_ssid->passphrase &&
796	    os_strlen(wpa_ssid->passphrase) == psk.size() &&
797	    os_memcmp(wpa_ssid->passphrase, psk.c_str(), psk.size()) == 0) {
798		return {SupplicantStatusCode::SUCCESS, ""};
799	}
800	// Flag to indicate if raw psk is calculated or not using
801	// |wpa_config_update_psk|. Deferred if ssid not already set.
802	wpa_ssid->psk_set = 0;
803	if (setStringKeyFieldAndResetState(
804		psk.c_str(), &(wpa_ssid->passphrase), "psk passphrase")) {
805		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
806	}
807	if (wpa_ssid->ssid_len) {
808		wpa_config_update_psk(wpa_ssid);
809	}
810	return {SupplicantStatusCode::SUCCESS, ""};
811}
812
813SupplicantStatus StaNetwork::setPskInternal(const std::array<uint8_t, 32> &psk)
814{
815	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
816	WPA_ASSERT(psk.size() == sizeof(wpa_ssid->psk));
817	str_clear_free(wpa_ssid->passphrase);
818	wpa_ssid->passphrase = nullptr;
819	os_memcpy(wpa_ssid->psk, psk.data(), sizeof(wpa_ssid->psk));
820	wpa_ssid->psk_set = 1;
821	resetInternalStateAfterParamsUpdate();
822	return {SupplicantStatusCode::SUCCESS, ""};
823}
824
825SupplicantStatus StaNetwork::setWepKeyInternal(
826    uint32_t key_idx, const std::vector<uint8_t> &wep_key)
827{
828	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
829	if (key_idx >=
830	    static_cast<uint32_t>(
831		ISupplicantStaNetwork::ParamSizeLimits::WEP_KEYS_MAX_NUM)) {
832		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
833	}
834	if (wep_key.size() !=
835		static_cast<uint32_t>(ISupplicantStaNetwork::ParamSizeLimits::
836					  WEP40_KEY_LEN_IN_BYTES) &&
837	    wep_key.size() !=
838		static_cast<uint32_t>(ISupplicantStaNetwork::ParamSizeLimits::
839					  WEP104_KEY_LEN_IN_BYTES)) {
840		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
841	}
842	os_memcpy(wpa_ssid->wep_key[key_idx], wep_key.data(), wep_key.size());
843	wpa_ssid->wep_key_len[key_idx] = wep_key.size();
844	std::string msg_dump_title("wep_key" + std::to_string(key_idx));
845	wpa_hexdump_key(
846	    MSG_MSGDUMP, msg_dump_title.c_str(), wpa_ssid->wep_key[key_idx],
847	    wpa_ssid->wep_key_len[key_idx]);
848	resetInternalStateAfterParamsUpdate();
849	return {SupplicantStatusCode::SUCCESS, ""};
850}
851
852SupplicantStatus StaNetwork::setWepTxKeyIdxInternal(uint32_t key_idx)
853{
854	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
855	if (key_idx >=
856	    static_cast<uint32_t>(
857		ISupplicantStaNetwork::ParamSizeLimits::WEP_KEYS_MAX_NUM)) {
858		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
859	}
860	wpa_ssid->wep_tx_keyidx = key_idx;
861	resetInternalStateAfterParamsUpdate();
862	return {SupplicantStatusCode::SUCCESS, ""};
863}
864
865SupplicantStatus StaNetwork::setRequirePmfInternal(bool enable)
866{
867	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
868	wpa_ssid->ieee80211w =
869	    enable ? MGMT_FRAME_PROTECTION_REQUIRED : NO_MGMT_FRAME_PROTECTION;
870	resetInternalStateAfterParamsUpdate();
871	return {SupplicantStatusCode::SUCCESS, ""};
872}
873
874SupplicantStatus StaNetwork::setEapMethodInternal(
875    ISupplicantStaNetwork::EapMethod method)
876{
877	uint32_t eap_method_idx = static_cast<
878	    std::underlying_type<ISupplicantStaNetwork::EapMethod>::type>(
879	    method);
880	if (eap_method_idx >= kEapMethodMax) {
881		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
882	}
883
884	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
885	int retrieved_vendor, retrieved_method;
886	const char *method_str = kEapMethodStrings[eap_method_idx];
887	// This string lookup is needed to check if the device supports the
888	// corresponding EAP type.
889	retrieved_method = eap_peer_get_type(method_str, &retrieved_vendor);
890	if (retrieved_vendor == EAP_VENDOR_IETF &&
891	    retrieved_method == EAP_TYPE_NONE) {
892		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
893	}
894	if (wpa_ssid->eap.eap_methods) {
895		os_free(wpa_ssid->eap.eap_methods);
896	}
897	// wpa_supplicant can support setting multiple eap methods for each
898	// network. But, this is not really used by Android. So, just adding
899	// support for setting one EAP method for each network. The additional
900	// |eap_method_type| member in the array is used to indicate the end
901	// of list.
902	wpa_ssid->eap.eap_methods =
903	    (eap_method_type *)os_malloc(sizeof(eap_method_type) * 2);
904	if (!wpa_ssid->eap.eap_methods) {
905		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
906	}
907	wpa_ssid->eap.eap_methods[0].vendor = retrieved_vendor;
908	wpa_ssid->eap.eap_methods[0].method = retrieved_method;
909	wpa_ssid->eap.eap_methods[1].vendor = EAP_VENDOR_IETF;
910	wpa_ssid->eap.eap_methods[1].method = EAP_TYPE_NONE;
911
912	wpa_ssid->leap = 0;
913	wpa_ssid->non_leap = 0;
914	if (retrieved_vendor == EAP_VENDOR_IETF &&
915	    retrieved_method == EAP_TYPE_LEAP) {
916		wpa_ssid->leap++;
917	} else {
918		wpa_ssid->non_leap++;
919	}
920	wpa_hexdump(
921	    MSG_MSGDUMP, "eap methods", (u8 *)wpa_ssid->eap.eap_methods,
922	    sizeof(eap_method_type) * 2);
923	resetInternalStateAfterParamsUpdate();
924	return {SupplicantStatusCode::SUCCESS, ""};
925}
926
927SupplicantStatus StaNetwork::setEapPhase2MethodInternal(
928    ISupplicantStaNetwork::EapPhase2Method method)
929{
930	uint32_t eap_phase2_method_idx = static_cast<
931	    std::underlying_type<ISupplicantStaNetwork::EapPhase2Method>::type>(
932	    method);
933	if (eap_phase2_method_idx >= kEapPhase2MethodMax) {
934		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
935	}
936
937	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
938	// EAP method needs to be set for us to construct the eap
939	// phase 2 method string.
940	SupplicantStatus status;
941	ISupplicantStaNetwork::EapMethod eap_method;
942	std::tie(status, eap_method) = getEapMethodInternal();
943	if (status.code != SupplicantStatusCode::SUCCESS) {
944		return {SupplicantStatusCode::FAILURE_UNKNOWN,
945			"EAP method not set"};
946	}
947	std::string eap_phase2_str;
948	if (method == ISupplicantStaNetwork::EapPhase2Method::NONE) {
949		eap_phase2_str = "";
950	} else if (
951	    eap_method == ISupplicantStaNetwork::EapMethod::TTLS &&
952	    method == ISupplicantStaNetwork::EapPhase2Method::GTC) {
953		eap_phase2_str = kEapPhase2AuthEapPrefix;
954	} else {
955		eap_phase2_str = kEapPhase2AuthPrefix;
956	}
957	eap_phase2_str += kEapPhase2MethodStrings[eap_phase2_method_idx];
958	if (setStringFieldAndResetState(
959		eap_phase2_str.c_str(), &(wpa_ssid->eap.phase2),
960		"eap phase2")) {
961		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
962	}
963	return {SupplicantStatusCode::SUCCESS, ""};
964}
965
966SupplicantStatus StaNetwork::setEapIdentityInternal(
967    const std::vector<uint8_t> &identity)
968{
969	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
970	if (setByteArrayFieldAndResetState(
971		identity.data(), identity.size(), &(wpa_ssid->eap.identity),
972		&(wpa_ssid->eap.identity_len), "eap identity")) {
973		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
974	}
975	return {SupplicantStatusCode::SUCCESS, ""};
976}
977
978SupplicantStatus StaNetwork::setEapAnonymousIdentityInternal(
979    const std::vector<uint8_t> &identity)
980{
981	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
982	if (setByteArrayFieldAndResetState(
983		identity.data(), identity.size(),
984		&(wpa_ssid->eap.anonymous_identity),
985		&(wpa_ssid->eap.anonymous_identity_len),
986		"eap anonymous_identity")) {
987		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
988	}
989	return {SupplicantStatusCode::SUCCESS, ""};
990}
991
992SupplicantStatus StaNetwork::setEapPasswordInternal(
993    const std::vector<uint8_t> &password)
994{
995	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
996	if (setByteArrayKeyFieldAndResetState(
997		password.data(), password.size(), &(wpa_ssid->eap.password),
998		&(wpa_ssid->eap.password_len), "eap password")) {
999		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1000	}
1001	wpa_ssid->eap.flags &= ~EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
1002	wpa_ssid->eap.flags &= ~EAP_CONFIG_FLAGS_EXT_PASSWORD;
1003	return {SupplicantStatusCode::SUCCESS, ""};
1004}
1005
1006SupplicantStatus StaNetwork::setEapCACertInternal(const std::string &path)
1007{
1008	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1009	if (setStringFieldAndResetState(
1010		path.c_str(), &(wpa_ssid->eap.ca_cert), "eap ca_cert")) {
1011		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1012	}
1013	return {SupplicantStatusCode::SUCCESS, ""};
1014}
1015
1016SupplicantStatus StaNetwork::setEapCAPathInternal(const std::string &path)
1017{
1018	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1019	if (setStringFieldAndResetState(
1020		path.c_str(), &(wpa_ssid->eap.ca_path), "eap ca_path")) {
1021		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1022	}
1023	return {SupplicantStatusCode::SUCCESS, ""};
1024}
1025
1026SupplicantStatus StaNetwork::setEapClientCertInternal(const std::string &path)
1027{
1028	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1029	if (setStringFieldAndResetState(
1030		path.c_str(), &(wpa_ssid->eap.client_cert),
1031		"eap client_cert")) {
1032		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1033	}
1034	return {SupplicantStatusCode::SUCCESS, ""};
1035}
1036
1037SupplicantStatus StaNetwork::setEapPrivateKeyIdInternal(const std::string &id)
1038{
1039	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1040	if (setStringFieldAndResetState(
1041		id.c_str(), &(wpa_ssid->eap.key_id), "eap key_id")) {
1042		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1043	}
1044	return {SupplicantStatusCode::SUCCESS, ""};
1045}
1046
1047SupplicantStatus StaNetwork::setEapSubjectMatchInternal(
1048    const std::string &match)
1049{
1050	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1051	if (setStringFieldAndResetState(
1052		match.c_str(), &(wpa_ssid->eap.subject_match),
1053		"eap subject_match")) {
1054		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1055	}
1056	return {SupplicantStatusCode::SUCCESS, ""};
1057}
1058
1059SupplicantStatus StaNetwork::setEapAltSubjectMatchInternal(
1060    const std::string &match)
1061{
1062	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1063	if (setStringFieldAndResetState(
1064		match.c_str(), &(wpa_ssid->eap.altsubject_match),
1065		"eap altsubject_match")) {
1066		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1067	}
1068	return {SupplicantStatusCode::SUCCESS, ""};
1069}
1070
1071SupplicantStatus StaNetwork::setEapEngineInternal(bool enable)
1072{
1073	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1074	wpa_ssid->eap.engine = enable ? 1 : 0;
1075	return {SupplicantStatusCode::SUCCESS, ""};
1076}
1077
1078SupplicantStatus StaNetwork::setEapEngineIDInternal(const std::string &id)
1079{
1080	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1081	if (setStringFieldAndResetState(
1082		id.c_str(), &(wpa_ssid->eap.engine_id), "eap engine_id")) {
1083		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1084	}
1085	return {SupplicantStatusCode::SUCCESS, ""};
1086}
1087
1088SupplicantStatus StaNetwork::setEapDomainSuffixMatchInternal(
1089    const std::string &match)
1090{
1091	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1092	if (setStringFieldAndResetState(
1093		match.c_str(), &(wpa_ssid->eap.domain_suffix_match),
1094		"eap domain_suffix_match")) {
1095		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1096	}
1097	return {SupplicantStatusCode::SUCCESS, ""};
1098}
1099
1100SupplicantStatus StaNetwork::setProactiveKeyCachingInternal(bool enable)
1101{
1102	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1103	wpa_ssid->proactive_key_caching = enable ? 1 : 0;
1104	resetInternalStateAfterParamsUpdate();
1105	return {SupplicantStatusCode::SUCCESS, ""};
1106}
1107
1108SupplicantStatus StaNetwork::setIdStrInternal(const std::string &id_str)
1109{
1110	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1111	if (setStringFieldAndResetState(
1112		id_str.c_str(), &(wpa_ssid->id_str), "id_str")) {
1113		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1114	}
1115	return {SupplicantStatusCode::SUCCESS, ""};
1116}
1117
1118SupplicantStatus StaNetwork::setUpdateIdentifierInternal(uint32_t id)
1119{
1120	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1121	wpa_ssid->update_identifier = id;
1122	wpa_printf(
1123	    MSG_MSGDUMP, "update_identifier: %d", wpa_ssid->update_identifier);
1124	resetInternalStateAfterParamsUpdate();
1125	return {SupplicantStatusCode::SUCCESS, ""};
1126}
1127
1128std::pair<SupplicantStatus, std::vector<uint8_t>> StaNetwork::getSsidInternal()
1129{
1130	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1131	std::vector<uint8_t> ssid;
1132	ssid.assign(wpa_ssid->ssid, wpa_ssid->ssid + wpa_ssid->ssid_len);
1133	return {{SupplicantStatusCode::SUCCESS, ""}, std::move(ssid)};
1134}
1135
1136std::pair<SupplicantStatus, std::array<uint8_t, 6>>
1137StaNetwork::getBssidInternal()
1138{
1139	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1140	std::array<uint8_t, 6> bssid{};
1141	os_memcpy(bssid.data(), kZeroBssid, ETH_ALEN);
1142	if (wpa_ssid->bssid_set) {
1143		os_memcpy(bssid.data(), wpa_ssid->bssid, ETH_ALEN);
1144	}
1145	return {{SupplicantStatusCode::SUCCESS, ""}, std::move(bssid)};
1146}
1147
1148std::pair<SupplicantStatus, bool> StaNetwork::getScanSsidInternal()
1149{
1150	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1151	return {{SupplicantStatusCode::SUCCESS, ""},
1152		(wpa_ssid->scan_ssid == 1)};
1153}
1154
1155std::pair<SupplicantStatus, uint32_t> StaNetwork::getKeyMgmtInternal()
1156{
1157	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1158	return {{SupplicantStatusCode::SUCCESS, ""},
1159		wpa_ssid->key_mgmt & kAllowedKeyMgmtMask};
1160}
1161
1162std::pair<SupplicantStatus, uint32_t> StaNetwork::getProtoInternal()
1163{
1164	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1165	return {{SupplicantStatusCode::SUCCESS, ""},
1166		wpa_ssid->proto & kAllowedProtoMask};
1167}
1168
1169std::pair<SupplicantStatus, uint32_t> StaNetwork::getAuthAlgInternal()
1170{
1171	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1172	return {{SupplicantStatusCode::SUCCESS, ""},
1173		wpa_ssid->auth_alg & kAllowedAuthAlgMask};
1174}
1175
1176std::pair<SupplicantStatus, uint32_t> StaNetwork::getGroupCipherInternal()
1177{
1178	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1179	return {{SupplicantStatusCode::SUCCESS, ""},
1180		wpa_ssid->group_cipher & kAllowedGroupCipherMask};
1181}
1182
1183std::pair<SupplicantStatus, uint32_t> StaNetwork::getPairwiseCipherInternal()
1184{
1185	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1186	return {{SupplicantStatusCode::SUCCESS, ""},
1187		wpa_ssid->pairwise_cipher & kAllowedPairwisewCipherMask};
1188}
1189
1190std::pair<SupplicantStatus, std::string> StaNetwork::getPskPassphraseInternal()
1191{
1192	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1193	if (!wpa_ssid->passphrase) {
1194		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1195	}
1196	return {{SupplicantStatusCode::SUCCESS, ""}, wpa_ssid->passphrase};
1197}
1198
1199std::pair<SupplicantStatus, std::array<uint8_t, 32>>
1200StaNetwork::getPskInternal()
1201{
1202	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1203	WPA_ASSERT(psk.size() == sizeof(wpa_ssid->psk));
1204	if (!wpa_ssid->psk_set) {
1205		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1206	}
1207	std::array<uint8_t, 32> psk;
1208	os_memcpy(psk.data(), wpa_ssid->psk, psk.size());
1209	return {{SupplicantStatusCode::SUCCESS, ""}, psk};
1210}
1211
1212std::pair<SupplicantStatus, std::vector<uint8_t>> StaNetwork::getWepKeyInternal(
1213    uint32_t key_idx)
1214{
1215	std::vector<uint8_t> wep_key;
1216	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1217	if (key_idx >=
1218	    static_cast<uint32_t>(
1219		ISupplicantStaNetwork::ParamSizeLimits::WEP_KEYS_MAX_NUM)) {
1220		return {{SupplicantStatusCode::FAILURE_ARGS_INVALID, ""},
1221			wep_key};
1222	}
1223	wep_key.assign(
1224	    wpa_ssid->wep_key[key_idx],
1225	    wpa_ssid->wep_key[key_idx] + wpa_ssid->wep_key_len[key_idx]);
1226	return {{SupplicantStatusCode::SUCCESS, ""}, std::move(wep_key)};
1227}
1228
1229std::pair<SupplicantStatus, uint32_t> StaNetwork::getWepTxKeyIdxInternal()
1230{
1231	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1232	return {{SupplicantStatusCode::SUCCESS, ""}, wpa_ssid->wep_tx_keyidx};
1233}
1234
1235std::pair<SupplicantStatus, bool> StaNetwork::getRequirePmfInternal()
1236{
1237	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1238	return {{SupplicantStatusCode::SUCCESS, ""},
1239		(wpa_ssid->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED)};
1240}
1241
1242std::pair<SupplicantStatus, ISupplicantStaNetwork::EapMethod>
1243StaNetwork::getEapMethodInternal()
1244{
1245	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1246	if (!wpa_ssid->eap.eap_methods) {
1247		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1248	}
1249	// wpa_supplicant can support setting multiple eap methods for each
1250	// network. But, this is not really used by Android. So, just reading
1251	// the first EAP method for each network.
1252	const std::string eap_method_str = eap_get_name(
1253	    wpa_ssid->eap.eap_methods[0].vendor,
1254	    static_cast<EapType>(wpa_ssid->eap.eap_methods[0].method));
1255	size_t eap_method_idx =
1256	    std::find(
1257		std::begin(kEapMethodStrings), std::end(kEapMethodStrings),
1258		eap_method_str) -
1259	    std::begin(kEapMethodStrings);
1260	if (eap_method_idx >= kEapMethodMax) {
1261		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1262	}
1263	return {{SupplicantStatusCode::SUCCESS, ""},
1264		static_cast<ISupplicantStaNetwork::EapMethod>(eap_method_idx)};
1265}
1266
1267std::pair<SupplicantStatus, ISupplicantStaNetwork::EapPhase2Method>
1268StaNetwork::getEapPhase2MethodInternal()
1269{
1270	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1271	if (!wpa_ssid->eap.phase2) {
1272		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1273	}
1274	const std::string eap_phase2_method_str_with_prefix =
1275	    wpa_ssid->eap.phase2;
1276	std::string eap_phase2_method_str;
1277	// Strip out the phase 2 method prefix before doing a reverse lookup
1278	// of phase 2 string to the Eap Phase 2 type.
1279	if (eap_phase2_method_str_with_prefix.find(kEapPhase2AuthPrefix) == 0) {
1280		eap_phase2_method_str =
1281		    eap_phase2_method_str_with_prefix.substr(
1282			strlen(kEapPhase2AuthPrefix),
1283			eap_phase2_method_str_with_prefix.size());
1284	} else if (
1285	    eap_phase2_method_str_with_prefix.find(kEapPhase2AuthEapPrefix) ==
1286	    0) {
1287		eap_phase2_method_str =
1288		    eap_phase2_method_str_with_prefix.substr(
1289			strlen(kEapPhase2AuthEapPrefix),
1290			eap_phase2_method_str_with_prefix.size());
1291	}
1292	size_t eap_phase2_method_idx =
1293	    std::find(
1294		std::begin(kEapPhase2MethodStrings),
1295		std::end(kEapPhase2MethodStrings), eap_phase2_method_str) -
1296	    std::begin(kEapPhase2MethodStrings);
1297	if (eap_phase2_method_idx >= kEapPhase2MethodMax) {
1298		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1299	}
1300	return {{SupplicantStatusCode::SUCCESS, ""},
1301		static_cast<ISupplicantStaNetwork::EapPhase2Method>(
1302		    eap_phase2_method_idx)};
1303}
1304
1305std::pair<SupplicantStatus, std::vector<uint8_t>>
1306StaNetwork::getEapIdentityInternal()
1307{
1308	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1309	if (!wpa_ssid->eap.identity) {
1310		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1311	}
1312	return {{SupplicantStatusCode::SUCCESS, ""},
1313		std::vector<uint8_t>(
1314		    wpa_ssid->eap.identity,
1315		    wpa_ssid->eap.identity + wpa_ssid->eap.identity_len)};
1316}
1317
1318std::pair<SupplicantStatus, std::vector<uint8_t>>
1319StaNetwork::getEapAnonymousIdentityInternal()
1320{
1321	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1322	if (!wpa_ssid->eap.anonymous_identity) {
1323		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1324	}
1325	return {{SupplicantStatusCode::SUCCESS, ""},
1326		std::vector<uint8_t>(
1327		    wpa_ssid->eap.anonymous_identity,
1328		    wpa_ssid->eap.anonymous_identity +
1329			wpa_ssid->eap.anonymous_identity_len)};
1330}
1331
1332std::pair<SupplicantStatus, std::vector<uint8_t>>
1333StaNetwork::getEapPasswordInternal()
1334{
1335	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1336	if (!wpa_ssid->eap.password) {
1337		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1338	}
1339	return {{SupplicantStatusCode::SUCCESS, ""},
1340		std::vector<uint8_t>(
1341		    wpa_ssid->eap.password,
1342		    wpa_ssid->eap.password + wpa_ssid->eap.password_len)};
1343}
1344
1345std::pair<SupplicantStatus, std::string> StaNetwork::getEapCACertInternal()
1346{
1347	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1348	if (!wpa_ssid->eap.ca_cert) {
1349		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1350	}
1351	return {{SupplicantStatusCode::SUCCESS, ""},
1352		reinterpret_cast<char *>(wpa_ssid->eap.ca_cert)};
1353}
1354
1355std::pair<SupplicantStatus, std::string> StaNetwork::getEapCAPathInternal()
1356{
1357	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1358	if (!wpa_ssid->eap.ca_path) {
1359		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1360	}
1361	return {{SupplicantStatusCode::SUCCESS, ""},
1362		reinterpret_cast<char *>(wpa_ssid->eap.ca_path)};
1363}
1364
1365std::pair<SupplicantStatus, std::string> StaNetwork::getEapClientCertInternal()
1366{
1367	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1368	if (!wpa_ssid->eap.client_cert) {
1369		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1370	}
1371	return {{SupplicantStatusCode::SUCCESS, ""},
1372		reinterpret_cast<char *>(wpa_ssid->eap.client_cert)};
1373}
1374
1375std::pair<SupplicantStatus, std::string>
1376StaNetwork::getEapPrivateKeyIdInternal()
1377{
1378	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1379	if (!wpa_ssid->eap.key_id) {
1380		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1381	}
1382	return {{SupplicantStatusCode::SUCCESS, ""}, wpa_ssid->eap.key_id};
1383}
1384
1385std::pair<SupplicantStatus, std::string>
1386StaNetwork::getEapSubjectMatchInternal()
1387{
1388	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1389	if (!wpa_ssid->eap.subject_match) {
1390		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1391	}
1392	return {{SupplicantStatusCode::SUCCESS, ""},
1393		reinterpret_cast<char *>(wpa_ssid->eap.subject_match)};
1394}
1395
1396std::pair<SupplicantStatus, std::string>
1397StaNetwork::getEapAltSubjectMatchInternal()
1398{
1399	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1400	if (!wpa_ssid->eap.altsubject_match) {
1401		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1402	}
1403	return {{SupplicantStatusCode::SUCCESS, ""},
1404		reinterpret_cast<char *>(wpa_ssid->eap.altsubject_match)};
1405}
1406
1407std::pair<SupplicantStatus, bool> StaNetwork::getEapEngineInternal()
1408{
1409	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1410	return {{SupplicantStatusCode::SUCCESS, ""}, wpa_ssid->eap.engine == 1};
1411}
1412
1413std::pair<SupplicantStatus, std::string> StaNetwork::getEapEngineIDInternal()
1414{
1415	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1416	if (!wpa_ssid->eap.engine_id) {
1417		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1418	}
1419	return {{SupplicantStatusCode::SUCCESS, ""}, {wpa_ssid->eap.engine_id}};
1420}
1421
1422std::pair<SupplicantStatus, std::string>
1423StaNetwork::getEapDomainSuffixMatchInternal()
1424{
1425	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1426	if (!wpa_ssid->eap.domain_suffix_match) {
1427		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1428	}
1429	return {{SupplicantStatusCode::SUCCESS, ""},
1430		{wpa_ssid->eap.domain_suffix_match}};
1431}
1432
1433std::pair<SupplicantStatus, std::string> StaNetwork::getIdStrInternal()
1434{
1435	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1436	if (!wpa_ssid->id_str) {
1437		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1438	}
1439	return {{SupplicantStatusCode::SUCCESS, ""}, {wpa_ssid->id_str}};
1440}
1441
1442std::pair<SupplicantStatus, std::vector<uint8_t>>
1443StaNetwork::getWpsNfcConfigurationTokenInternal()
1444{
1445	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1446	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1447	auto token_buf = misc_utils::createWpaBufUniquePtr(
1448	    wpas_wps_network_config_token(wpa_s, 0, wpa_ssid));
1449	if (!token_buf) {
1450		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
1451	}
1452	return {{SupplicantStatusCode::SUCCESS, ""},
1453		misc_utils::convertWpaBufToVector(token_buf.get())};
1454}
1455
1456SupplicantStatus StaNetwork::enableInternal(bool no_connect)
1457{
1458	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1459	if (wpa_ssid->disabled == 2) {
1460		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1461	}
1462	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1463	if (no_connect) {
1464		wpa_ssid->disabled = 0;
1465	} else {
1466		wpa_s->scan_min_time.sec = 0;
1467		wpa_s->scan_min_time.usec = 0;
1468		wpa_supplicant_enable_network(wpa_s, wpa_ssid);
1469	}
1470	return {SupplicantStatusCode::SUCCESS, ""};
1471}
1472
1473SupplicantStatus StaNetwork::disableInternal()
1474{
1475	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1476	if (wpa_ssid->disabled == 2) {
1477		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1478	}
1479	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1480	wpa_supplicant_disable_network(wpa_s, wpa_ssid);
1481	return {SupplicantStatusCode::SUCCESS, ""};
1482}
1483
1484SupplicantStatus StaNetwork::selectInternal()
1485{
1486	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1487	if (wpa_ssid->disabled == 2) {
1488		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1489	}
1490	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1491	wpa_s->scan_min_time.sec = 0;
1492	wpa_s->scan_min_time.usec = 0;
1493	wpa_supplicant_select_network(wpa_s, wpa_ssid);
1494	return {SupplicantStatusCode::SUCCESS, ""};
1495}
1496
1497SupplicantStatus StaNetwork::sendNetworkEapSimGsmAuthResponseInternal(
1498    const std::vector<ISupplicantStaNetwork::NetworkResponseEapSimGsmAuthParams>
1499	&vec_params)
1500{
1501	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1502	// Convert the incoming parameters to a string to pass to
1503	// wpa_supplicant.
1504	std::string ctrl_rsp_param = std::string(kNetworkEapSimGsmAuthResponse);
1505	for (const auto &params : vec_params) {
1506		uint32_t kc_hex_len = params.kc.size() * 2 + 1;
1507		std::vector<char> kc_hex(kc_hex_len);
1508		uint32_t sres_hex_len = params.sres.size() * 2 + 1;
1509		std::vector<char> sres_hex(sres_hex_len);
1510		wpa_snprintf_hex(
1511		    kc_hex.data(), kc_hex.size(), params.kc.data(),
1512		    params.kc.size());
1513		wpa_snprintf_hex(
1514		    sres_hex.data(), sres_hex.size(), params.sres.data(),
1515		    params.sres.size());
1516		ctrl_rsp_param += ":" + std::string(kc_hex.data()) + ":" +
1517				  std::string(sres_hex.data());
1518	}
1519	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
1520	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1521	if (wpa_supplicant_ctrl_rsp_handle(
1522		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.data(),
1523                ctrl_rsp_param.size())) {
1524		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1525	}
1526	eapol_sm_notify_ctrl_response(wpa_s->eapol);
1527	wpa_hexdump_ascii_key(
1528	    MSG_DEBUG, "network sim gsm auth response param",
1529	    (const u8 *)ctrl_rsp_param.c_str(), ctrl_rsp_param.size());
1530	return {SupplicantStatusCode::SUCCESS, ""};
1531}
1532
1533SupplicantStatus StaNetwork::sendNetworkEapSimGsmAuthFailureInternal()
1534{
1535	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1536	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1537	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
1538	if (wpa_supplicant_ctrl_rsp_handle(
1539		wpa_s, wpa_ssid, rtype, kNetworkEapSimGsmAuthFailure,
1540                strlen(kNetworkEapSimGsmAuthFailure))) {
1541		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1542	}
1543	eapol_sm_notify_ctrl_response(wpa_s->eapol);
1544	return {SupplicantStatusCode::SUCCESS, ""};
1545}
1546
1547SupplicantStatus StaNetwork::sendNetworkEapSimUmtsAuthResponseInternal(
1548    const ISupplicantStaNetwork::NetworkResponseEapSimUmtsAuthParams &params)
1549{
1550	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1551	// Convert the incoming parameters to a string to pass to
1552	// wpa_supplicant.
1553	uint32_t ik_hex_len = params.ik.size() * 2 + 1;
1554	std::vector<char> ik_hex(ik_hex_len);
1555	uint32_t ck_hex_len = params.ck.size() * 2 + 1;
1556	std::vector<char> ck_hex(ck_hex_len);
1557	uint32_t res_hex_len = params.res.size() * 2 + 1;
1558	std::vector<char> res_hex(res_hex_len);
1559	wpa_snprintf_hex(
1560	    ik_hex.data(), ik_hex.size(), params.ik.data(), params.ik.size());
1561	wpa_snprintf_hex(
1562	    ck_hex.data(), ck_hex.size(), params.ck.data(), params.ck.size());
1563	wpa_snprintf_hex(
1564	    res_hex.data(), res_hex.size(), params.res.data(),
1565	    params.res.size());
1566	std::string ctrl_rsp_param =
1567	    std::string(kNetworkEapSimUmtsAuthResponse) + ":" +
1568	    std::string(ik_hex.data()) + ":" + std::string(ck_hex.data()) +
1569	    ":" + std::string(res_hex.data());
1570	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
1571	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1572	if (wpa_supplicant_ctrl_rsp_handle(
1573		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.data(),
1574                ctrl_rsp_param.size())) {
1575		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1576	}
1577	eapol_sm_notify_ctrl_response(wpa_s->eapol);
1578	wpa_hexdump_ascii_key(
1579	    MSG_DEBUG, "network sim umts auth response param",
1580	    (const u8 *)ctrl_rsp_param.c_str(), ctrl_rsp_param.size());
1581	return {SupplicantStatusCode::SUCCESS, ""};
1582}
1583
1584SupplicantStatus StaNetwork::sendNetworkEapSimUmtsAutsResponseInternal(
1585    const std::array<uint8_t, 14> &auts)
1586{
1587	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1588	uint32_t auts_hex_len = auts.size() * 2 + 1;
1589	std::vector<char> auts_hex(auts_hex_len);
1590	wpa_snprintf_hex(
1591	    auts_hex.data(), auts_hex.size(), auts.data(), auts.size());
1592	std::string ctrl_rsp_param =
1593	    std::string(kNetworkEapSimUmtsAutsResponse) + ":" +
1594	    std::string(auts_hex.data());
1595	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
1596	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1597	if (wpa_supplicant_ctrl_rsp_handle(
1598		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.data(),
1599                ctrl_rsp_param.size())) {
1600		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1601	}
1602	eapol_sm_notify_ctrl_response(wpa_s->eapol);
1603	wpa_hexdump_ascii_key(
1604	    MSG_DEBUG, "network sim umts auts response param",
1605	    (const u8 *)ctrl_rsp_param.c_str(), ctrl_rsp_param.size());
1606	return {SupplicantStatusCode::SUCCESS, ""};
1607}
1608
1609SupplicantStatus StaNetwork::sendNetworkEapSimUmtsAuthFailureInternal()
1610{
1611	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1612	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1613	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
1614	if (wpa_supplicant_ctrl_rsp_handle(
1615		wpa_s, wpa_ssid, rtype, kNetworkEapSimUmtsAuthFailure,
1616                strlen(kNetworkEapSimUmtsAuthFailure))) {
1617		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1618	}
1619	eapol_sm_notify_ctrl_response(wpa_s->eapol);
1620	return {SupplicantStatusCode::SUCCESS, ""};
1621}
1622
1623SupplicantStatus StaNetwork::sendNetworkEapIdentityResponseInternal(
1624    const std::vector<uint8_t> &identity)
1625{
1626	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1627	std::string ctrl_rsp_param(identity.begin(), identity.end());
1628	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_EAP_IDENTITY;
1629	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1630	if (wpa_supplicant_ctrl_rsp_handle(
1631		wpa_s, wpa_ssid, rtype,  ctrl_rsp_param.data(),
1632                ctrl_rsp_param.size())) {
1633		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1634	}
1635	eapol_sm_notify_ctrl_response(wpa_s->eapol);
1636	wpa_hexdump_ascii_key(
1637	    MSG_DEBUG, "network identity response param",
1638	    (const u8 *)ctrl_rsp_param.c_str(), ctrl_rsp_param.size());
1639	return {SupplicantStatusCode::SUCCESS, ""};
1640}
1641
1642/**
1643 * Retrieve the underlying |wpa_ssid| struct pointer for
1644 * this network.
1645 * If the underlying network is removed or the interface
1646 * this network belong to
1647 * is removed, all RPC method calls on this object will
1648 * return failure.
1649 */
1650struct wpa_ssid *StaNetwork::retrieveNetworkPtr()
1651{
1652	wpa_supplicant *wpa_s = retrieveIfacePtr();
1653	if (!wpa_s)
1654		return nullptr;
1655	return wpa_config_get_network(wpa_s->conf, network_id_);
1656}
1657
1658/**
1659 * Retrieve the underlying |wpa_supplicant| struct
1660 * pointer for
1661 * this network.
1662 */
1663struct wpa_supplicant *StaNetwork::retrieveIfacePtr()
1664{
1665	return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
1666}
1667
1668/**
1669 * Check if the provided psk passhrase is valid or not.
1670 *
1671 * Returns 0 if valid, 1 otherwise.
1672 */
1673int StaNetwork::isPskPassphraseValid(const std::string &psk)
1674{
1675	if (psk.size() <
1676		static_cast<uint32_t>(ISupplicantStaNetwork::ParamSizeLimits::
1677					  PSK_PASSPHRASE_MIN_LEN_IN_BYTES) ||
1678	    psk.size() >
1679		static_cast<uint32_t>(ISupplicantStaNetwork::ParamSizeLimits::
1680					  PSK_PASSPHRASE_MAX_LEN_IN_BYTES)) {
1681		return 1;
1682	}
1683	if (has_ctrl_char((u8 *)psk.c_str(), psk.size())) {
1684		return 1;
1685	}
1686	return 0;
1687}
1688
1689/**
1690 * Reset internal wpa_supplicant state machine state
1691 * after params update (except
1692 * bssid).
1693 */
1694void StaNetwork::resetInternalStateAfterParamsUpdate()
1695{
1696	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1697	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1698
1699	wpa_sm_pmksa_cache_flush(wpa_s->wpa, wpa_ssid);
1700
1701	if (wpa_s->current_ssid == wpa_ssid || wpa_s->current_ssid == NULL) {
1702		/*
1703		 * Invalidate the EAP session cache if
1704		 * anything in the
1705		 * current or previously used
1706		 * configuration changes.
1707		 */
1708		eapol_sm_invalidate_cached_session(wpa_s->eapol);
1709	}
1710}
1711
1712/**
1713 * Helper function to set value in a string field in |wpa_ssid| structue
1714 * instance for this network.
1715 * This function frees any existing data in these fields.
1716 */
1717int StaNetwork::setStringFieldAndResetState(
1718    const char *value, uint8_t **to_update_field, const char *hexdump_prefix)
1719{
1720	return setStringFieldAndResetState(
1721	    value, (char **)to_update_field, hexdump_prefix);
1722}
1723
1724/**
1725 * Helper function to set value in a string field in |wpa_ssid| structue
1726 * instance for this network.
1727 * This function frees any existing data in these fields.
1728 */
1729int StaNetwork::setStringFieldAndResetState(
1730    const char *value, char **to_update_field, const char *hexdump_prefix)
1731{
1732	int value_len = strlen(value);
1733	if (*to_update_field) {
1734		os_free(*to_update_field);
1735	}
1736	*to_update_field = dup_binstr(value, value_len);
1737	if (!(*to_update_field)) {
1738		return 1;
1739	}
1740	wpa_hexdump_ascii(
1741	    MSG_MSGDUMP, hexdump_prefix, *to_update_field, value_len);
1742	resetInternalStateAfterParamsUpdate();
1743	return 0;
1744}
1745
1746/**
1747 * Helper function to set value in a string key field in |wpa_ssid| structue
1748 * instance for this network.
1749 * This function frees any existing data in these fields.
1750 */
1751int StaNetwork::setStringKeyFieldAndResetState(
1752    const char *value, char **to_update_field, const char *hexdump_prefix)
1753{
1754	int value_len = strlen(value);
1755	if (*to_update_field) {
1756		str_clear_free(*to_update_field);
1757	}
1758	*to_update_field = dup_binstr(value, value_len);
1759	if (!(*to_update_field)) {
1760		return 1;
1761	}
1762	wpa_hexdump_ascii_key(
1763	    MSG_MSGDUMP, hexdump_prefix, *to_update_field, value_len);
1764	resetInternalStateAfterParamsUpdate();
1765	return 0;
1766}
1767
1768/**
1769 * Helper function to set value in a string field with a corresponding length
1770 * field in |wpa_ssid| structue instance for this network.
1771 * This function frees any existing data in these fields.
1772 */
1773int StaNetwork::setByteArrayFieldAndResetState(
1774    const uint8_t *value, const size_t value_len, uint8_t **to_update_field,
1775    size_t *to_update_field_len, const char *hexdump_prefix)
1776{
1777	if (*to_update_field) {
1778		os_free(*to_update_field);
1779	}
1780	*to_update_field = (uint8_t *)os_malloc(value_len);
1781	if (!(*to_update_field)) {
1782		return 1;
1783	}
1784	os_memcpy(*to_update_field, value, value_len);
1785	*to_update_field_len = value_len;
1786
1787	wpa_hexdump_ascii(
1788	    MSG_MSGDUMP, hexdump_prefix, *to_update_field,
1789	    *to_update_field_len);
1790	resetInternalStateAfterParamsUpdate();
1791	return 0;
1792}
1793
1794/**
1795 * Helper function to set value in a string key field with a corresponding
1796 * length field in |wpa_ssid| structue instance for this network.
1797 * This function frees any existing data in these fields.
1798 */
1799int StaNetwork::setByteArrayKeyFieldAndResetState(
1800    const uint8_t *value, const size_t value_len, uint8_t **to_update_field,
1801    size_t *to_update_field_len, const char *hexdump_prefix)
1802{
1803	if (*to_update_field) {
1804		bin_clear_free(*to_update_field, *to_update_field_len);
1805	}
1806	*to_update_field = (uint8_t *)os_malloc(value_len);
1807	if (!(*to_update_field)) {
1808		return 1;
1809	}
1810	os_memcpy(*to_update_field, value, value_len);
1811	*to_update_field_len = value_len;
1812
1813	wpa_hexdump_ascii_key(
1814	    MSG_MSGDUMP, hexdump_prefix, *to_update_field,
1815	    *to_update_field_len);
1816	resetInternalStateAfterParamsUpdate();
1817	return 0;
1818}
1819
1820}  // namespace implementation
1821}  // namespace V1_0
1822}  // namespace wifi
1823}  // namespace supplicant
1824}  // namespace hardware
1825}  // namespace android
1826