@@ -2868,7 +2868,8 @@ int owe_process_assoc_resp(const u8 *rsn_ie, size_t rsn_len, const uint8_t *dh_i
28682868 struct wpa_sm * sm ;
28692869 sm = get_wpa_sm ();
28702870
2871- wpabuf_free (sm -> owe_ie ); //free the dh ie constructed in owe_build_assoc_req
2871+ /* Deallocate the dh ie buffer constructed in owe_build_assoc_req */
2872+ wpabuf_free (sm -> owe_ie );
28722873 sm -> owe_ie = NULL ;
28732874
28742875 struct wpa_ie_data * parsed_rsn_data ;
@@ -2882,121 +2883,129 @@ int owe_process_assoc_resp(const u8 *rsn_ie, size_t rsn_len, const uint8_t *dh_i
28822883 goto fail ;
28832884 }
28842885
2886+ if (!dh_ie && parsed_rsn_data -> num_pmkid == 0 ) {
2887+ wpa_printf (MSG_ERROR , "OWE: Assoc response should either have pmkid or DH IE" );
2888+ goto fail ;
2889+ }
2890+
2891+ /* Check for PMK caching */
2892+ if (sm -> cur_pmksa && parsed_rsn_data && parsed_rsn_data -> num_pmkid == 1 && parsed_rsn_data -> pmkid ) {
2893+ if (os_memcmp (parsed_rsn_data -> pmkid , sm -> cur_pmksa -> pmkid , OWE_PMKID_LEN ) == 0 ) {
2894+ wpa_printf (MSG_DEBUG , "OWE: Using PMK caching" );
2895+ wpa_sm_set_pmk_from_pmksa (sm );
2896+ goto done ;
2897+ } else {
2898+ /* If PMKID mismatches, derive keys again */
2899+ wpa_printf (MSG_DEBUG , "OWE : Invalid PMKID in response" );
2900+ }
2901+ }
2902+
2903+ if (dh_ie == NULL ) {
2904+ wpa_printf (MSG_ERROR , "OWE: No Diffie Hellman IE in association response" );
2905+ goto fail ;
2906+ }
28852907 if (dh_ie && MIN_DH_LEN (dh_len )) {
28862908 wpa_printf (MSG_ERROR , "OWE: Invalid Diffie Hellman IE" );
28872909 goto fail ;
28882910 }
2889- if (!dh_ie && parsed_rsn_data -> num_pmkid == 0 ) {
2890- wpa_printf (MSG_ERROR , "OWE: Assoc response should either have pmkid or DH IE" );
2911+
2912+ /* If STA or AP does not have PMKID, or PMKID mismatches, proceed with normal association */
2913+ dh_len += 2 ;
2914+
2915+ dh_ie += 3 ;
2916+ dh_len -= 3 ;
2917+ group = WPA_GET_LE16 (dh_ie );
2918+
2919+ /* Only group 19 is supported */
2920+ if ((group != sm -> owe_group ) || (group != OWE_DH_GRP19 )) {
2921+ wpa_printf (MSG_ERROR , "OWE: Unexpected Diffie-Hellman group in response" );
28912922 goto fail ;
28922923 }
28932924
2894- if (!sm -> cur_pmksa ) { /* No PMK caching */
2895- if (dh_ie == NULL ) {
2896- goto fail ;
2897- }
2898- dh_len += 2 ;
2925+ prime_len = OWE_PRIME_LEN ;
28992926
2900- dh_ie += 3 ;
2901- dh_len -= 3 ;
2902- group = WPA_GET_LE16 (dh_ie );
2927+ /* Set peer's public key point and calculate shared secret */
2928+ sh_secret = crypto_ecdh_set_peerkey (sm -> owe_ecdh , 0 , dh_ie + 2 , dh_len - 2 );
2929+ sh_secret = wpabuf_zeropad (sh_secret , prime_len );
2930+ if (!sh_secret ) {
2931+ wpa_printf (MSG_ERROR , "OWE: Invalid peer DH public key" );
2932+ goto fail ;
2933+ }
29032934
2904- /* Only group 19 is supported */
2905- if ((group != sm -> owe_group ) || (group != OWE_DH_GRP19 )) {
2906- wpa_printf (MSG_ERROR , "OWE: Unexpected Diffie-Hellman group in response" );
2907- goto fail ;
2908- }
2935+ wpa_hexdump_buf_key (MSG_DEBUG , "OWE: DH shared secret" , sh_secret );
2936+ pub = crypto_ecdh_get_pubkey (sm -> owe_ecdh , 0 );
2937+ if (!pub ) {
2938+ wpa_printf (MSG_ERROR , "No own public key" );
2939+ goto fail ;
2940+ }
29092941
2910- prime_len = OWE_PRIME_LEN ;
2942+ /* PMKID = Truncate-128(Hash(C | A)) */
2943+ addr [0 ] = wpabuf_head (pub );
2944+ len [0 ] = wpabuf_len (pub );
2945+ addr [1 ] = dh_ie + 2 ;
2946+ len [1 ] = dh_len - 2 ;
29112947
2912- /* Set peer's public key point and calculate shared secret */
2913- sh_secret = crypto_ecdh_set_peerkey (sm -> owe_ecdh , 0 , dh_ie + 2 , dh_len - 2 );
2914- sh_secret = wpabuf_zeropad (sh_secret , prime_len );
2915- if (!sh_secret ) {
2916- wpa_printf (MSG_ERROR , "OWE: Invalid peer DH public key" );
2917- goto fail ;
2918- }
2948+ int res = sha256_vector (2 , addr , len , pmkid );
2949+ if (res < 0 ) {
2950+ goto fail ;
2951+ }
29192952
2920- wpa_hexdump_buf_key (MSG_DEBUG , "OWE: DH shared secret" , sh_secret );
2921- pub = crypto_ecdh_get_pubkey (sm -> owe_ecdh , 0 );
2922- if (!pub ) {
2923- wpa_printf (MSG_ERROR , "No own public key" );
2924- wpabuf_free (sh_secret );
2925- goto fail ;
2926- }
2953+ hash_len = SHA256_MAC_LEN ;
29272954
2928- /* PMKID = Truncate-128(Hash(C | A)) */
2929- addr [0 ] = wpabuf_head (pub );
2930- len [0 ] = wpabuf_len (pub );
2931- addr [1 ] = dh_ie + 2 ;
2932- len [1 ] = dh_len - 2 ;
2955+ pub = wpabuf_zeropad (pub , prime_len );
2956+ if (!pub ) {
2957+ goto fail ;
2958+ }
29332959
2934- int res = sha256_vector (2 , addr , len , pmkid );
2935- if (res < 0 ) {
2936- goto fail ;
2937- }
2960+ /* prk = HKDF-extract(C | A | group, z) */
2961+ hkey = wpabuf_alloc (wpabuf_len (pub ) + dh_len - 2 + 2 );
2962+ if (!hkey ) {
2963+ goto fail ;
2964+ }
29382965
2939- hash_len = SHA256_MAC_LEN ;
2966+ wpabuf_put_buf (hkey , pub ); /* C */
2967+ wpabuf_free (pub );
29402968
2941- pub = wpabuf_zeropad (pub , prime_len );
2969+ wpabuf_put_data (hkey , dh_ie + 2 , dh_len - 2 ); /* A */
2970+ wpabuf_put_le16 (hkey , sm -> owe_group ); /* group */
29422971
2943- /* prk = HKDF-extract(C | A | group, z) */
2944- hkey = wpabuf_alloc (wpabuf_len (pub ) + dh_len - 2 + 2 );
2972+ res = hmac_sha256 (wpabuf_head (hkey ), wpabuf_len (hkey ), wpabuf_head (sh_secret ), wpabuf_len (sh_secret ), prk );
2973+ if (res < 0 ) {
2974+ goto fail ;
2975+ }
29452976
2946- wpabuf_put_buf (hkey , pub ); /* C */
2947- wpabuf_free (pub );
2977+ hash_len = SHA256_MAC_LEN ;
29482978
2949- wpabuf_put_data (hkey , dh_ie + 2 , dh_len - 2 ); /* A */
2950- wpabuf_put_le16 ( hkey , sm -> owe_group ); /* group */
2979+ wpabuf_free (hkey );
2980+ wpabuf_clear_free ( sh_secret );
29512981
2952- res = hmac_sha256 (wpabuf_head (hkey ), wpabuf_len (hkey ), wpabuf_head (sh_secret ), wpabuf_len (sh_secret ), prk );
2953- if (res < 0 ) {
2954- goto fail ;
2955- }
2982+ wpa_hexdump_key (MSG_DEBUG , "OWE: prk" , prk , hash_len );
29562983
2957- hash_len = SHA256_MAC_LEN ;
2984+ /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */
2985+ res = hmac_sha256_kdf (prk , hash_len , NULL , (const u8 * )info ,
2986+ os_strlen (info ), pmk , hash_len );
2987+ if (res < 0 ) {
2988+ goto fail ;
2989+ }
29582990
2959- wpabuf_free ( hkey );
2960- wpabuf_free ( sh_secret );
2991+ forced_memzero ( prk , SHA256_MAC_LEN );
2992+ wpa_hexdump ( MSG_DEBUG , "OWE: PMKID" , pmkid , OWE_PMKID_LEN );
29612993
2962- wpa_hexdump_key (MSG_DEBUG , "OWE: prk" , prk , hash_len );
2994+ os_memcpy (sm -> pmk ,pmk ,hash_len );
2995+ sm -> pmk_len = hash_len ;
2996+ wpa_hexdump_key (MSG_DEBUG , "OWE: PMK" , sm -> pmk , sm -> pmk_len );
29632997
2964- /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */
2965- res = hmac_sha256_kdf (prk , hash_len , NULL , (const u8 * )info ,
2966- os_strlen (info ), pmk , hash_len );
2967- if (res < 0 ) {
2968- goto fail ;
2969- }
2998+ pmksa_cache_add (sm -> pmksa , sm -> pmk , sm -> pmk_len , pmkid , NULL , 0 ,
2999+ sm -> bssid , sm -> own_addr , sm -> network_ctx , sm -> key_mgmt );
29703000
2971- forced_memzero (prk , SHA256_MAC_LEN );
2972- wpa_hexdump (MSG_DEBUG , "OWE: PMKID" , pmkid , OWE_PMKID_LEN );
2973-
2974- os_memcpy (sm -> pmk ,pmk ,hash_len );
2975- sm -> pmk_len = hash_len ;
2976- wpa_hexdump_key (MSG_DEBUG , "OWE: PMK" , sm -> pmk , sm -> pmk_len );
2977-
2978- pmksa_cache_add (sm -> pmksa , sm -> pmk , sm -> pmk_len , pmkid , NULL , 0 ,
2979- sm -> bssid , sm -> own_addr , sm -> network_ctx , sm -> key_mgmt );
2980- goto done ;
2981- } else { /* PMK caching */
2982- if (parsed_rsn_data && sm -> cur_pmksa ) {
2983- if (parsed_rsn_data -> num_pmkid == 1 && parsed_rsn_data -> pmkid ) {
2984- if (os_memcmp (parsed_rsn_data -> pmkid , sm -> cur_pmksa -> pmkid , OWE_PMKID_LEN ) == 0 ) {
2985- wpa_printf (MSG_DEBUG , "OWE: Using PMK caching" );
2986- wpa_sm_set_pmk_from_pmksa (sm );
2987- goto done ;
2988- } else {
2989- wpa_printf (MSG_DEBUG , "OWE : Invalid PMKID in response" );
2990- goto fail ;
2991- }
2992- }
2993- }
2994- }
29953001done :
29963002 os_free (parsed_rsn_data );
29973003 return 0 ;
29983004fail :
29993005 os_free (parsed_rsn_data );
3006+ wpabuf_free (pub );
3007+ wpabuf_free (hkey );
3008+ wpabuf_clear_free (sh_secret );
30003009 return -1 ;
30013010}
30023011#endif // CONFIG_OWE_STA
0 commit comments