LCOV - code coverage report
Current view: top level - src/wps - wps_attr_build.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1393793999 Lines: 252 271 93.0 %
Date: 2014-03-02 Functions: 24 24 100.0 %
Branches: 60 76 78.9 %

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

Generated by: LCOV version 1.9