LCOV - code coverage report
Current view: top level - src/wps - wps_attr_build.c (source / functions) Hit Total Coverage
Test: wpa_supplicant hwsim test run 1388240082 Lines: 213 245 86.9 %
Date: 2013-12-28 Functions: 22 22 100.0 %
Branches: 38 60 63.3 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Wi-Fi Protected Setup - attribute building
       3                 :            :  * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
       4                 :            :  *
       5                 :            :  * This software may be distributed under the terms of the BSD license.
       6                 :            :  * See README for more details.
       7                 :            :  */
       8                 :            : 
       9                 :            : #include "includes.h"
      10                 :            : 
      11                 :            : #include "common.h"
      12                 :            : #include "crypto/aes_wrap.h"
      13                 :            : #include "crypto/crypto.h"
      14                 :            : #include "crypto/dh_group5.h"
      15                 :            : #include "crypto/sha256.h"
      16                 :            : #include "crypto/random.h"
      17                 :            : #include "common/ieee802_11_defs.h"
      18                 :            : #include "wps_i.h"
      19                 :            : 
      20                 :            : 
      21                 :        124 : int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg)
      22                 :            : {
      23                 :            :         struct wpabuf *pubkey;
      24                 :            : 
      25                 :        124 :         wpa_printf(MSG_DEBUG, "WPS:  * Public Key");
      26                 :        124 :         wpabuf_free(wps->dh_privkey);
      27                 :        124 :         wps->dh_privkey = NULL;
      28 [ +  + ][ +  + ]:        124 :         if (wps->dev_pw_id != DEV_PW_DEFAULT && wps->wps->dh_privkey &&
                 [ +  + ]
      29                 :          9 :             wps->wps->dh_ctx) {
      30                 :          2 :                 wpa_printf(MSG_DEBUG, "WPS: Using pre-configured DH keys");
      31         [ -  + ]:          2 :                 if (wps->wps->dh_pubkey == NULL) {
      32                 :          0 :                         wpa_printf(MSG_DEBUG,
      33                 :            :                                    "WPS: wps->wps->dh_pubkey == NULL");
      34                 :          0 :                         return -1;
      35                 :            :                 }
      36                 :          2 :                 wps->dh_privkey = wpabuf_dup(wps->wps->dh_privkey);
      37                 :          2 :                 wps->dh_ctx = wps->wps->dh_ctx;
      38                 :          2 :                 wps->wps->dh_ctx = NULL;
      39                 :          2 :                 pubkey = wpabuf_dup(wps->wps->dh_pubkey);
      40                 :            : #ifdef CONFIG_WPS_NFC
      41 [ +  + ][ -  + ]:        122 :         } else if (wps->dev_pw_id >= 0x10 && wps->wps->ap &&
                 [ #  # ]
      42                 :          0 :                    wps->dev_pw_id == wps->wps->ap_nfc_dev_pw_id) {
      43                 :          0 :                 wpa_printf(MSG_DEBUG, "WPS: Using NFC password token DH keys");
      44         [ #  # ]:          0 :                 if (wps->wps->ap_nfc_dh_privkey == NULL) {
      45                 :          0 :                         wpa_printf(MSG_DEBUG,
      46                 :            :                                    "WPS: wps->wps->ap_nfc_dh_privkey == NULL");
      47                 :          0 :                         return -1;
      48                 :            :                 }
      49         [ #  # ]:          0 :                 if (wps->wps->ap_nfc_dh_pubkey == NULL) {
      50                 :          0 :                         wpa_printf(MSG_DEBUG,
      51                 :            :                                    "WPS: wps->wps->ap_nfc_dh_pubkey == NULL");
      52                 :          0 :                         return -1;
      53                 :            :                 }
      54                 :          0 :                 wps->dh_privkey = wpabuf_dup(wps->wps->ap_nfc_dh_privkey);
      55                 :          0 :                 pubkey = wpabuf_dup(wps->wps->ap_nfc_dh_pubkey);
      56                 :          0 :                 wps->dh_ctx = dh5_init_fixed(wps->dh_privkey, pubkey);
      57                 :            : #endif /* CONFIG_WPS_NFC */
      58                 :            :         } else {
      59                 :        122 :                 wpa_printf(MSG_DEBUG, "WPS: Generate new DH keys");
      60                 :        122 :                 dh5_free(wps->dh_ctx);
      61                 :        122 :                 wps->dh_ctx = dh5_init(&wps->dh_privkey, &pubkey);
      62                 :        122 :                 pubkey = wpabuf_zeropad(pubkey, 192);
      63                 :            :         }
      64 [ +  - ][ +  - ]:        124 :         if (wps->dh_ctx == NULL || wps->dh_privkey == NULL || pubkey == NULL) {
                 [ -  + ]
      65                 :          0 :                 wpa_printf(MSG_DEBUG, "WPS: Failed to initialize "
      66                 :            :                            "Diffie-Hellman handshake");
      67                 :          0 :                 wpabuf_free(pubkey);
      68                 :          0 :                 return -1;
      69                 :            :         }
      70                 :        124 :         wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH Private Key", wps->dh_privkey);
      71                 :        124 :         wpa_hexdump_buf(MSG_DEBUG, "WPS: DH own Public Key", pubkey);
      72                 :            : 
      73                 :        124 :         wpabuf_put_be16(msg, ATTR_PUBLIC_KEY);
      74                 :        124 :         wpabuf_put_be16(msg, wpabuf_len(pubkey));
      75                 :        124 :         wpabuf_put_buf(msg, pubkey);
      76                 :            : 
      77         [ +  + ]:        124 :         if (wps->registrar) {
      78                 :         60 :                 wpabuf_free(wps->dh_pubkey_r);
      79                 :         60 :                 wps->dh_pubkey_r = pubkey;
      80                 :            :         } else {
      81                 :         64 :                 wpabuf_free(wps->dh_pubkey_e);
      82                 :         64 :                 wps->dh_pubkey_e = pubkey;
      83                 :            :         }
      84                 :            : 
      85                 :        124 :         return 0;
      86                 :            : }
      87                 :            : 
      88                 :            : 
      89                 :        966 : int wps_build_req_type(struct wpabuf *msg, enum wps_request_type type)
      90                 :            : {
      91                 :        966 :         wpa_printf(MSG_DEBUG, "WPS:  * Request Type");
      92                 :        966 :         wpabuf_put_be16(msg, ATTR_REQUEST_TYPE);
      93                 :        966 :         wpabuf_put_be16(msg, 1);
      94                 :        966 :         wpabuf_put_u8(msg, type);
      95                 :        966 :         return 0;
      96                 :            : }
      97                 :            : 
      98                 :            : 
      99                 :        685 : int wps_build_resp_type(struct wpabuf *msg, enum wps_response_type type)
     100                 :            : {
     101                 :        685 :         wpa_printf(MSG_DEBUG, "WPS:  * Response Type (%d)", type);
     102                 :        685 :         wpabuf_put_be16(msg, ATTR_RESPONSE_TYPE);
     103                 :        685 :         wpabuf_put_be16(msg, 1);
     104                 :        685 :         wpabuf_put_u8(msg, type);
     105                 :        685 :         return 0;
     106                 :            : }
     107                 :            : 
     108                 :            : 
     109                 :       1020 : int wps_build_config_methods(struct wpabuf *msg, u16 methods)
     110                 :            : {
     111                 :       1020 :         wpa_printf(MSG_DEBUG, "WPS:  * Config Methods (%x)", methods);
     112                 :       1020 :         wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
     113                 :       1020 :         wpabuf_put_be16(msg, 2);
     114                 :       1020 :         wpabuf_put_be16(msg, methods);
     115                 :       1020 :         return 0;
     116                 :            : }
     117                 :            : 
     118                 :            : 
     119                 :       2009 : int wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid)
     120                 :            : {
     121         [ -  + ]:       2009 :         if (wpabuf_tailroom(msg) < 4 + WPS_UUID_LEN)
     122                 :          0 :                 return -1;
     123                 :       2009 :         wpa_printf(MSG_DEBUG, "WPS:  * UUID-E");
     124                 :       2009 :         wpabuf_put_be16(msg, ATTR_UUID_E);
     125                 :       2009 :         wpabuf_put_be16(msg, WPS_UUID_LEN);
     126                 :       2009 :         wpabuf_put_data(msg, uuid, WPS_UUID_LEN);
     127                 :       2009 :         return 0;
     128                 :            : }
     129                 :            : 
     130                 :            : 
     131                 :       1020 : int wps_build_dev_password_id(struct wpabuf *msg, u16 id)
     132                 :            : {
     133                 :       1020 :         wpa_printf(MSG_DEBUG, "WPS:  * Device Password ID (%d)", id);
     134                 :       1020 :         wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
     135                 :       1020 :         wpabuf_put_be16(msg, 2);
     136                 :       1020 :         wpabuf_put_be16(msg, id);
     137                 :       1020 :         return 0;
     138                 :            : }
     139                 :            : 
     140                 :            : 
     141                 :       1023 : int wps_build_config_error(struct wpabuf *msg, u16 err)
     142                 :            : {
     143                 :       1023 :         wpa_printf(MSG_DEBUG, "WPS:  * Configuration Error (%d)", err);
     144                 :       1023 :         wpabuf_put_be16(msg, ATTR_CONFIG_ERROR);
     145                 :       1023 :         wpabuf_put_be16(msg, 2);
     146                 :       1023 :         wpabuf_put_be16(msg, err);
     147                 :       1023 :         return 0;
     148                 :            : }
     149                 :            : 
     150                 :            : 
     151                 :        423 : int wps_build_authenticator(struct wps_data *wps, struct wpabuf *msg)
     152                 :            : {
     153                 :            :         u8 hash[SHA256_MAC_LEN];
     154                 :            :         const u8 *addr[2];
     155                 :            :         size_t len[2];
     156                 :            : 
     157         [ -  + ]:        423 :         if (wps->last_msg == NULL) {
     158                 :          0 :                 wpa_printf(MSG_DEBUG, "WPS: Last message not available for "
     159                 :            :                            "building authenticator");
     160                 :          0 :                 return -1;
     161                 :            :         }
     162                 :            : 
     163                 :            :         /* Authenticator = HMAC-SHA256_AuthKey(M_prev || M_curr*)
     164                 :            :          * (M_curr* is M_curr without the Authenticator attribute)
     165                 :            :          */
     166                 :        423 :         addr[0] = wpabuf_head(wps->last_msg);
     167                 :        423 :         len[0] = wpabuf_len(wps->last_msg);
     168                 :        423 :         addr[1] = wpabuf_head(msg);
     169                 :        423 :         len[1] = wpabuf_len(msg);
     170                 :        423 :         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash);
     171                 :            : 
     172                 :        423 :         wpa_printf(MSG_DEBUG, "WPS:  * Authenticator");
     173                 :        423 :         wpabuf_put_be16(msg, ATTR_AUTHENTICATOR);
     174                 :        423 :         wpabuf_put_be16(msg, WPS_AUTHENTICATOR_LEN);
     175                 :        423 :         wpabuf_put_data(msg, hash, WPS_AUTHENTICATOR_LEN);
     176                 :            : 
     177                 :        423 :         return 0;
     178                 :            : }
     179                 :            : 
     180                 :            : 
     181                 :       3385 : int wps_build_version(struct wpabuf *msg)
     182                 :            : {
     183                 :            :         /*
     184                 :            :          * Note: This attribute is deprecated and set to hardcoded 0x10 for
     185                 :            :          * backwards compatibility reasons. The real version negotiation is
     186                 :            :          * done with Version2.
     187                 :            :          */
     188         [ -  + ]:       3385 :         if (wpabuf_tailroom(msg) < 5)
     189                 :          0 :                 return -1;
     190                 :       3385 :         wpa_printf(MSG_DEBUG, "WPS:  * Version (hardcoded 0x10)");
     191                 :       3385 :         wpabuf_put_be16(msg, ATTR_VERSION);
     192                 :       3385 :         wpabuf_put_be16(msg, 1);
     193                 :       3385 :         wpabuf_put_u8(msg, 0x10);
     194                 :       3385 :         return 0;
     195                 :            : }
     196                 :            : 
     197                 :            : 
     198                 :       3385 : int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
     199                 :            :                       const u8 *auth_macs, size_t auth_macs_count)
     200                 :            : {
     201                 :            : #ifdef CONFIG_WPS2
     202                 :            :         u8 *len;
     203                 :            : 
     204         [ -  + ]:       6770 :         if (wpabuf_tailroom(msg) <
     205         [ +  + ]:       3385 :             7 + 3 + (req_to_enroll ? 3 : 0) +
     206         [ +  + ]:       3385 :             (auth_macs ? 2 + auth_macs_count * ETH_ALEN : 0))
     207                 :          0 :                 return -1;
     208                 :       3385 :         wpabuf_put_be16(msg, ATTR_VENDOR_EXT);
     209                 :       3385 :         len = wpabuf_put(msg, 2); /* to be filled */
     210                 :       3385 :         wpabuf_put_be24(msg, WPS_VENDOR_ID_WFA);
     211                 :            : 
     212                 :       3385 :         wpa_printf(MSG_DEBUG, "WPS:  * Version2 (0x%x)", WPS_VERSION);
     213                 :       3385 :         wpabuf_put_u8(msg, WFA_ELEM_VERSION2);
     214                 :       3385 :         wpabuf_put_u8(msg, 1);
     215                 :       3385 :         wpabuf_put_u8(msg, WPS_VERSION);
     216                 :            : 
     217         [ +  + ]:       3385 :         if (req_to_enroll) {
     218                 :        606 :                 wpa_printf(MSG_DEBUG, "WPS:  * Request to Enroll (1)");
     219                 :        606 :                 wpabuf_put_u8(msg, WFA_ELEM_REQUEST_TO_ENROLL);
     220                 :        606 :                 wpabuf_put_u8(msg, 1);
     221                 :        606 :                 wpabuf_put_u8(msg, 1);
     222                 :            :         }
     223                 :            : 
     224 [ +  + ][ +  + ]:       3385 :         if (auth_macs && auth_macs_count) {
     225                 :            :                 size_t i;
     226                 :        120 :                 wpa_printf(MSG_DEBUG, "WPS:  * AuthorizedMACs (count=%d)",
     227                 :            :                            (int) auth_macs_count);
     228                 :        120 :                 wpabuf_put_u8(msg, WFA_ELEM_AUTHORIZEDMACS);
     229                 :        120 :                 wpabuf_put_u8(msg, auth_macs_count * ETH_ALEN);
     230                 :        120 :                 wpabuf_put_data(msg, auth_macs, auth_macs_count * ETH_ALEN);
     231         [ +  + ]:        240 :                 for (i = 0; i < auth_macs_count; i++)
     232                 :        120 :                         wpa_printf(MSG_DEBUG, "WPS:    AuthorizedMAC: " MACSTR,
     233                 :        720 :                                    MAC2STR(&auth_macs[i * ETH_ALEN]));
     234                 :            :         }
     235                 :            : 
     236                 :       3385 :         WPA_PUT_BE16(len, (u8 *) wpabuf_put(msg, 0) - len - 2);
     237                 :            : #endif /* CONFIG_WPS2 */
     238                 :            : 
     239                 :            : #ifdef CONFIG_WPS_TESTING
     240         [ -  + ]:       3385 :         if (WPS_VERSION > 0x20) {
     241         [ #  # ]:          0 :                 if (wpabuf_tailroom(msg) < 5)
     242                 :          0 :                         return -1;
     243                 :          0 :                 wpa_printf(MSG_DEBUG, "WPS:  * Extensibility Testing - extra "
     244                 :            :                            "attribute");
     245                 :          0 :                 wpabuf_put_be16(msg, ATTR_EXTENSIBILITY_TEST);
     246                 :          0 :                 wpabuf_put_be16(msg, 1);
     247                 :          0 :                 wpabuf_put_u8(msg, 42);
     248                 :            :         }
     249                 :            : #endif /* CONFIG_WPS_TESTING */
     250                 :       3385 :         return 0;
     251                 :            : }
     252                 :            : 
     253                 :            : 
     254                 :        559 : int wps_build_msg_type(struct wpabuf *msg, enum wps_msg_type msg_type)
     255                 :            : {
     256                 :        559 :         wpa_printf(MSG_DEBUG, "WPS:  * Message Type (%d)", msg_type);
     257                 :        559 :         wpabuf_put_be16(msg, ATTR_MSG_TYPE);
     258                 :        559 :         wpabuf_put_be16(msg, 1);
     259                 :        559 :         wpabuf_put_u8(msg, msg_type);
     260                 :        559 :         return 0;
     261                 :            : }
     262                 :            : 
     263                 :            : 
     264                 :        373 : int wps_build_enrollee_nonce(struct wps_data *wps, struct wpabuf *msg)
     265                 :            : {
     266                 :        373 :         wpa_printf(MSG_DEBUG, "WPS:  * Enrollee Nonce");
     267                 :        373 :         wpabuf_put_be16(msg, ATTR_ENROLLEE_NONCE);
     268                 :        373 :         wpabuf_put_be16(msg, WPS_NONCE_LEN);
     269                 :        373 :         wpabuf_put_data(msg, wps->nonce_e, WPS_NONCE_LEN);
     270                 :        373 :         return 0;
     271                 :            : }
     272                 :            : 
     273                 :            : 
     274                 :        318 : int wps_build_registrar_nonce(struct wps_data *wps, struct wpabuf *msg)
     275                 :            : {
     276                 :        318 :         wpa_printf(MSG_DEBUG, "WPS:  * Registrar Nonce");
     277                 :        318 :         wpabuf_put_be16(msg, ATTR_REGISTRAR_NONCE);
     278                 :        318 :         wpabuf_put_be16(msg, WPS_NONCE_LEN);
     279                 :        318 :         wpabuf_put_data(msg, wps->nonce_r, WPS_NONCE_LEN);
     280                 :        318 :         return 0;
     281                 :            : }
     282                 :            : 
     283                 :            : 
     284                 :        124 : int wps_build_auth_type_flags(struct wps_data *wps, struct wpabuf *msg)
     285                 :            : {
     286                 :        124 :         u16 auth_types = WPS_AUTH_TYPES;
     287                 :            : #ifdef CONFIG_WPS2
     288                 :        124 :         auth_types &= ~WPS_AUTH_SHARED;
     289                 :            : #endif /* CONFIG_WPS2 */
     290                 :        124 :         wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type Flags");
     291                 :        124 :         wpabuf_put_be16(msg, ATTR_AUTH_TYPE_FLAGS);
     292                 :        124 :         wpabuf_put_be16(msg, 2);
     293                 :        124 :         wpabuf_put_be16(msg, auth_types);
     294                 :        124 :         return 0;
     295                 :            : }
     296                 :            : 
     297                 :            : 
     298                 :        124 : int wps_build_encr_type_flags(struct wps_data *wps, struct wpabuf *msg)
     299                 :            : {
     300                 :        124 :         u16 encr_types = WPS_ENCR_TYPES;
     301                 :            : #ifdef CONFIG_WPS2
     302                 :        124 :         encr_types &= ~WPS_ENCR_WEP;
     303                 :            : #endif /* CONFIG_WPS2 */
     304                 :        124 :         wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type Flags");
     305                 :        124 :         wpabuf_put_be16(msg, ATTR_ENCR_TYPE_FLAGS);
     306                 :        124 :         wpabuf_put_be16(msg, 2);
     307                 :        124 :         wpabuf_put_be16(msg, encr_types);
     308                 :        124 :         return 0;
     309                 :            : }
     310                 :            : 
     311                 :            : 
     312                 :        124 : int wps_build_conn_type_flags(struct wps_data *wps, struct wpabuf *msg)
     313                 :            : {
     314                 :        124 :         wpa_printf(MSG_DEBUG, "WPS:  * Connection Type Flags");
     315                 :        124 :         wpabuf_put_be16(msg, ATTR_CONN_TYPE_FLAGS);
     316                 :        124 :         wpabuf_put_be16(msg, 1);
     317                 :        124 :         wpabuf_put_u8(msg, WPS_CONN_ESS);
     318                 :        124 :         return 0;
     319                 :            : }
     320                 :            : 
     321                 :            : 
     322                 :       1020 : int wps_build_assoc_state(struct wps_data *wps, struct wpabuf *msg)
     323                 :            : {
     324                 :       1020 :         wpa_printf(MSG_DEBUG, "WPS:  * Association State");
     325                 :       1020 :         wpabuf_put_be16(msg, ATTR_ASSOC_STATE);
     326                 :       1020 :         wpabuf_put_be16(msg, 2);
     327                 :       1020 :         wpabuf_put_be16(msg, WPS_ASSOC_NOT_ASSOC);
     328                 :       1020 :         return 0;
     329                 :            : }
     330                 :            : 
     331                 :            : 
     332                 :        301 : int wps_build_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg)
     333                 :            : {
     334                 :            :         u8 hash[SHA256_MAC_LEN];
     335                 :            : 
     336                 :        301 :         wpa_printf(MSG_DEBUG, "WPS:  * Key Wrap Authenticator");
     337                 :        301 :         hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, wpabuf_head(msg),
     338                 :            :                     wpabuf_len(msg), hash);
     339                 :            : 
     340                 :        301 :         wpabuf_put_be16(msg, ATTR_KEY_WRAP_AUTH);
     341                 :        301 :         wpabuf_put_be16(msg, WPS_KWA_LEN);
     342                 :        301 :         wpabuf_put_data(msg, hash, WPS_KWA_LEN);
     343                 :        301 :         return 0;
     344                 :            : }
     345                 :            : 
     346                 :            : 
     347                 :        301 : int wps_build_encr_settings(struct wps_data *wps, struct wpabuf *msg,
     348                 :            :                             struct wpabuf *plain)
     349                 :            : {
     350                 :            :         size_t pad_len;
     351                 :        301 :         const size_t block_size = 16;
     352                 :            :         u8 *iv, *data;
     353                 :            : 
     354                 :        301 :         wpa_printf(MSG_DEBUG, "WPS:  * Encrypted Settings");
     355                 :            : 
     356                 :            :         /* PKCS#5 v2.0 pad */
     357                 :        301 :         pad_len = block_size - wpabuf_len(plain) % block_size;
     358                 :        301 :         os_memset(wpabuf_put(plain, pad_len), pad_len, pad_len);
     359                 :            : 
     360                 :        301 :         wpabuf_put_be16(msg, ATTR_ENCR_SETTINGS);
     361                 :        301 :         wpabuf_put_be16(msg, block_size + wpabuf_len(plain));
     362                 :            : 
     363                 :        301 :         iv = wpabuf_put(msg, block_size);
     364         [ -  + ]:        301 :         if (random_get_bytes(iv, block_size) < 0)
     365                 :          0 :                 return -1;
     366                 :            : 
     367                 :        301 :         data = wpabuf_put(msg, 0);
     368                 :        301 :         wpabuf_put_buf(msg, plain);
     369         [ -  + ]:        301 :         if (aes_128_cbc_encrypt(wps->keywrapkey, iv, data, wpabuf_len(plain)))
     370                 :          0 :                 return -1;
     371                 :            : 
     372                 :        301 :         return 0;
     373                 :            : }
     374                 :            : 
     375                 :            : 
     376                 :            : #ifdef CONFIG_WPS_OOB
     377                 :          2 : int wps_build_oob_dev_pw(struct wpabuf *msg, u16 dev_pw_id,
     378                 :            :                          const struct wpabuf *pubkey, const u8 *dev_pw,
     379                 :            :                          size_t dev_pw_len)
     380                 :            : {
     381                 :            :         size_t hash_len;
     382                 :            :         const u8 *addr[1];
     383                 :            :         u8 pubkey_hash[WPS_HASH_LEN];
     384                 :            : 
     385                 :          2 :         wpa_printf(MSG_DEBUG, "WPS:  * OOB Device Password (dev_pw_id=%u)",
     386                 :            :                    dev_pw_id);
     387                 :          2 :         addr[0] = wpabuf_head(pubkey);
     388                 :          2 :         hash_len = wpabuf_len(pubkey);
     389                 :          2 :         sha256_vector(1, addr, &hash_len, pubkey_hash);
     390                 :            : 
     391                 :          2 :         wpabuf_put_be16(msg, ATTR_OOB_DEVICE_PASSWORD);
     392                 :          2 :         wpabuf_put_be16(msg, WPS_OOB_PUBKEY_HASH_LEN + 2 + dev_pw_len);
     393                 :          2 :         wpa_hexdump(MSG_DEBUG, "WPS: Public Key Hash",
     394                 :            :                     pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN);
     395                 :          2 :         wpabuf_put_data(msg, pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN);
     396                 :          2 :         wpabuf_put_be16(msg, dev_pw_id);
     397                 :          2 :         wpa_hexdump_key(MSG_DEBUG, "WPS: OOB Device Password",
     398                 :            :                         dev_pw, dev_pw_len);
     399                 :          2 :         wpabuf_put_data(msg, dev_pw, dev_pw_len);
     400                 :            : 
     401                 :          2 :         return 0;
     402                 :            : }
     403                 :            : #endif /* CONFIG_WPS_OOB */
     404                 :            : 
     405                 :            : 
     406                 :            : /* Encapsulate WPS IE data with one (or more, if needed) IE headers */
     407                 :       1310 : struct wpabuf * wps_ie_encapsulate(struct wpabuf *data)
     408                 :            : {
     409                 :            :         struct wpabuf *ie;
     410                 :            :         const u8 *pos, *end;
     411                 :            : 
     412                 :       1310 :         ie = wpabuf_alloc(wpabuf_len(data) + 100);
     413         [ -  + ]:       1310 :         if (ie == NULL) {
     414                 :          0 :                 wpabuf_free(data);
     415                 :          0 :                 return NULL;
     416                 :            :         }
     417                 :            : 
     418                 :       1310 :         pos = wpabuf_head(data);
     419                 :       1310 :         end = pos + wpabuf_len(data);
     420                 :            : 
     421         [ +  + ]:       2620 :         while (end > pos) {
     422                 :       1310 :                 size_t frag_len = end - pos;
     423         [ -  + ]:       1310 :                 if (frag_len > 251)
     424                 :          0 :                         frag_len = 251;
     425                 :       1310 :                 wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
     426                 :       1310 :                 wpabuf_put_u8(ie, 4 + frag_len);
     427                 :       1310 :                 wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
     428                 :       1310 :                 wpabuf_put_data(ie, pos, frag_len);
     429                 :       1310 :                 pos += frag_len;
     430                 :            :         }
     431                 :            : 
     432                 :       1310 :         wpabuf_free(data);
     433                 :            : 
     434                 :       1310 :         return ie;
     435                 :            : }
     436                 :            : 
     437                 :            : 
     438                 :        124 : int wps_build_mac_addr(struct wpabuf *msg, const u8 *addr)
     439                 :            : {
     440                 :        124 :         wpa_printf(MSG_DEBUG, "WPS:  * MAC Address (" MACSTR ")",
     441                 :        744 :                    MAC2STR(addr));
     442                 :        124 :         wpabuf_put_be16(msg, ATTR_MAC_ADDR);
     443                 :        124 :         wpabuf_put_be16(msg, ETH_ALEN);
     444                 :        124 :         wpabuf_put_data(msg, addr, ETH_ALEN);
     445                 :        124 :         return 0;
     446                 :            : }

Generated by: LCOV version 1.9