Ticket #7825: 0001-libertas-Reduce-the-WPA-key-installation-time.patch

File 0001-libertas-Reduce-the-WPA-key-installation-time.patch, 7.1 kB (added by jcardona, 6 years ago)
  • drivers/net/wireless/libertas/assoc.c

    From 5146ac8a430f625daf77cbb8bb2f5c6a8cb6473f Mon Sep 17 00:00:00 2001
    From: Javier Cardona <javier@cozybit.com>
    Date: Wed, 10 Sep 2008 19:37:41 -0700
    Subject: [PATCH] libertas:  Reduce the WPA key installation time.
    
    WPA requires that the PTK is installed immediately after the 4-way handshake
    in order to properly decrypt the subsequent incoming EAPOL-GTK frame.  If the
    PTK is not enabled by the time the EAPOL-GTK frame arrives, the frame is
    dropped and the supplicant does not receive the group key.
    
    This will happen with fast Access Points that send the EAPOL-GTK frame before
    the suplicant has successfully installed and enabled the PTK.  To mitigate
    this situation, this patch simplifies and accelerates the SIOCSIWENCODEEXT
    execution.
    ---
     drivers/net/wireless/libertas/assoc.c   |   12 +-----
     drivers/net/wireless/libertas/cmd.c     |   64 +++++++++++-------------------
     drivers/net/wireless/libertas/cmd.h     |    1 +
     drivers/net/wireless/libertas/hostcmd.h |    2 +
     drivers/net/wireless/libertas/wext.c    |   16 ++++++-
     5 files changed, 42 insertions(+), 53 deletions(-)
    
    diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
    index 4d27de3..2238e04 100644
    a b  
    358358 
    359359        if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { 
    360360                clear_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags); 
    361                 ret = lbs_prepare_and_send_command(priv, 
    362                                         CMD_802_11_KEY_MATERIAL, 
    363                                         CMD_ACT_SET, 
    364                                         CMD_OPTION_WAITFORRSP, 
    365                                         0, assoc_req); 
     361                ret = lbs_set_key_material(priv, &assoc_req->wpa_unicast_key); 
    366362                assoc_req->flags = flags; 
    367363        } 
    368364 
     
    372368        if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { 
    373369                clear_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); 
    374370 
    375                 ret = lbs_prepare_and_send_command(priv, 
    376                                         CMD_802_11_KEY_MATERIAL, 
    377                                         CMD_ACT_SET, 
    378                                         CMD_OPTION_WAITFORRSP, 
    379                                         0, assoc_req); 
     371                ret = lbs_set_key_material(priv, &assoc_req->wpa_mcast_key); 
    380372                assoc_req->flags = flags; 
    381373        } 
    382374 
  • drivers/net/wireless/libertas/cmd.c

    diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
    index 41f51a2..ac7c0c7 100644
    a b  
    419419        lbs_deb_leave(LBS_DEB_CMD); 
    420420} 
    421421 
    422 static int lbs_cmd_802_11_key_material(struct lbs_private *priv, 
    423                                         struct cmd_ds_command *cmd, 
    424                                         u16 cmd_action, 
    425                                         u32 cmd_oid, void *pdata_buf) 
     422/** 
     423 *  @brief Set key material 
     424 * 
     425 *  @param priv         A pointer to struct lbs_private structure 
     426 *  @param key          A pointer to key material 
     427 * 
     428 *  @return             0 on success, error on failure 
     429 */ 
     430int lbs_set_key_material(struct lbs_private *priv, struct enc_key *key) 
    426431{ 
    427         struct cmd_ds_802_11_key_material *pkeymaterial = 
    428             &cmd->params.keymaterial; 
    429         struct assoc_request * assoc_req = pdata_buf; 
     432        struct cmd_ds_802_11_key_material cmd; 
    430433        int ret = 0; 
    431         int index = 0; 
    432434 
    433435        lbs_deb_enter(LBS_DEB_CMD); 
    434436 
    435         cmd->command = cpu_to_le16(CMD_802_11_KEY_MATERIAL); 
    436         pkeymaterial->action = cpu_to_le16(cmd_action); 
    437  
    438         if (cmd_action == CMD_ACT_GET) { 
    439                 cmd->size = cpu_to_le16(S_DS_GEN + sizeof (pkeymaterial->action)); 
    440                 ret = 0; 
    441                 goto done; 
    442         } 
    443  
    444         memset(&pkeymaterial->keyParamSet, 0, sizeof(pkeymaterial->keyParamSet)); 
    445  
    446         if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { 
    447                 set_one_wpa_key(&pkeymaterial->keyParamSet[index], 
    448                                 &assoc_req->wpa_unicast_key); 
    449                 index++; 
    450         } 
    451  
    452         if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { 
    453                 set_one_wpa_key(&pkeymaterial->keyParamSet[index], 
    454                                 &assoc_req->wpa_mcast_key); 
    455                 index++; 
    456         } 
     437        memset(&cmd, 0, sizeof(cmd)); 
     438        cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 
     439        cmd.action = cpu_to_le16(CMD_ACT_SET); 
    457440 
    458         cmd->size = cpu_to_le16(  S_DS_GEN 
    459                                 + sizeof (pkeymaterial->action) 
    460                                 + (index * sizeof(struct MrvlIEtype_keyParamSet))); 
     441        memset(cmd.keyParamSet, 0, sizeof(cmd.keyParamSet)); 
     442        set_one_wpa_key(&cmd.keyParamSet[0], key); 
    461443 
    462         ret = 0; 
     444        ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd); 
     445        if (ret) 
     446                goto out; 
    463447 
    464 done: 
     448        if (key->flags & KEY_INFO_WPA_ENABLED) 
     449                lbs_deb_cmd("SET_WPA_KEY: %s%s installed\n", 
     450                        key->flags & KEY_INFO_WPA_UNICAST ?  "PTK" : "", 
     451                        key->flags & KEY_INFO_WPA_MCAST ? "GTK" : ""); 
     452out: 
    465453        lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 
    466454        return ret; 
    467455} 
     
    15011489                ret = lbs_cmd_80211_ad_hoc_stop(priv, cmdptr); 
    15021490                break; 
    15031491 
    1504         case CMD_802_11_KEY_MATERIAL: 
    1505                 ret = lbs_cmd_802_11_key_material(priv, cmdptr, cmd_action, 
    1506                                 cmd_oid, pdata_buf); 
    1507                 break; 
    1508  
    15091492        case CMD_802_11_PAIRWISE_TSC: 
    15101493                break; 
     1494 
    15111495        case CMD_802_11_GROUP_TSC: 
    15121496                break; 
    15131497 
  • drivers/net/wireless/libertas/cmd.h

    diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
    index 12cb089..ef93697 100644
    a b  
    3636 
    3737int lbs_get_data_rate(struct lbs_private *priv); 
    3838int lbs_set_data_rate(struct lbs_private *priv, u8 rate); 
     39int lbs_set_key_material(struct lbs_private *priv, struct enc_key *key); 
    3940 
    4041int lbs_get_channel(struct lbs_private *priv); 
    4142int lbs_set_channel(struct lbs_private *priv, u8 channel); 
  • drivers/net/wireless/libertas/hostcmd.h

    diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
    index f2dad51..63dc8e8 100644
    a b  
    599599 
    600600 
    601601struct cmd_ds_802_11_key_material { 
     602        struct cmd_header hdr; 
     603 
    602604        __le16 action; 
    603605        struct MrvlIEtype_keyParamSet keyParamSet[2]; 
    604606} __attribute__ ((packed)); 
  • drivers/net/wireless/libertas/wext.c

    diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
    index 0bd2fbf..fc67718 100644
    a b  
    3030        queue_delayed_work(priv->work_thread, &priv->assoc_work, HZ / 2); 
    3131} 
    3232 
     33static inline void lbs_do_association_work(struct lbs_private *priv) 
     34{ 
     35        if (priv->surpriseremoved) 
     36                return; 
     37        cancel_delayed_work(&priv->assoc_work); 
     38        queue_delayed_work(priv->work_thread, &priv->assoc_work, 0); 
     39} 
     40 
    3341static inline void lbs_cancel_association_work(struct lbs_private *priv) 
    3442{ 
    3543        cancel_delayed_work(&priv->assoc_work); 
     
    16081616                        set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); 
    16091617                } 
    16101618 
    1611                 disable_wep (assoc_req); 
     1619                /* Only disable wep if necessary: can't waste time here. */ 
     1620                if (priv->mac_control & CMD_ACT_MAC_WEP_ENABLE) 
     1621                        disable_wep(assoc_req); 
    16121622        } 
    16131623 
    16141624out: 
    1615         if (ret == 0) { 
    1616                 lbs_postpone_association_work(priv); 
     1625        if (ret == 0) {  /* key installation is time critical: postpone not! */ 
     1626                lbs_do_association_work(priv); 
    16171627        } else { 
    16181628                lbs_cancel_association_work(priv); 
    16191629        }