- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# /space/home/slher/rel/Beken/v6_4_5/macsw/ip/umac/src/mfp/mfp.c

Go to the documentation of this file.

    00001
    00012 #include "vif_mgmt.h"
    00013 #include "mac_ie.h"
    00014 #include "mfp.h"
    00015 #include "mfp_bip.h"
    00016
    00017 #if NX_MFP
    00018
    00037 static bool mfp_is_group_addressed_privacy(uint16_t frame_cntl, uint8_t action)
    00038 {
    00039     return  (((frame_cntl & MAC_FCTRL_TYPE_MASK) == MAC_FCTRL_MGT_T) &&
    00040              ((frame_cntl & MAC_FCTRL_SUBT_MASK) == MAC_FCTRL_ACTION_ST) &&
    00041              ((action == MAC_MESH_ACTION_CATEGORY) ||
    00042               (action == MAC_MULTIHOP_ACTION_CATEGORY)));
    00043 }
    00044
    00058 static bool mfp_check_mmic_ie(uint32_t frame, uint16_t length,
    00059                               uint16_t machdr_len, struct vif_info_tag *vif,
    00060                               struct sta_info_tag *sta)
    00061 {
    00062     struct key_info_tag *key;
    00063     uint16_t key_id, i;
    00064     uint64_t pn;
    00065     uint64_t mic, mic_check;
    00066     uint32_t mmic_ie;
    00067
    00068     if (length < machdr_len + 2 + MAC_MGMT_MIC_LEN)
    00069     {
    00070         return false;
    00071     }
    00072
    00073     mmic_ie = mac_ie_mgmt_mic_find(frame + machdr_len + 2, length - machdr_len - 2);
    00074
    00075     if (mmic_ie == 0)
    00076     {
    00077         return false;
    00078     }
    00079
    00080     key_id = co_read16p(mmic_ie + MAC_MGMT_MIC_KEYID_OFT);
    00081     pn = co_read64p(mmic_ie + MAC_MGMT_MIC_IPN_OFT) & 0xffffff;
    00082     mic = co_read64p(mmic_ie + MAC_MGMT_MIC_MIC_OFT);
    00083
    00084     if (key_id != 4 && key_id != 5)
    00085     {
    00086         return false;
    00087     }
    00088
    00089     #if (RW_MESH_EN)
    00090     if (vif->type == VIF_MESH_POINT)
    00091     {
    00092         key = &sta->sta_sec_info.key_mfp_mesh_info[key_id - MAC_DEFAULT_KEY_COUNT];
    00093     }
    00094     else
    00095     #endif //(RW_MESH_EN)
    00096     {
    00097         key = &vif->key_info[key_id];
    00098     }
    00099
    00100     if (!key->valid)
    00101     {
    00102         return false;
    00103     }
    00104
    00105     if (pn <= key->rx_pn[0])
    00106     {
    00107         return false;
    00108     }
    00109
    00110     key->rx_pn[0] = pn;
    00111
    00112     // reset mic before computation
    00113     for (i = 0; i < MAC_MGMT_MIC_MIC_LEN; i++)
    00114     {
    00115         co_write8p(mmic_ie + MAC_MGMT_MIC_MIC_OFT + i, 0);
    00116     }
    00117
    00118     mic_check = mfp_compute_bip(key, frame, length - MAC_MGMT_MIC_LEN, machdr_len, 0);
    00119     if (mic_check != mic)
    00120     {
    00121         return false;
    00122     }
    00123
    00124     return true;
    00125 }
    00126
    00127 /*
    00128  * PUBLIC FUNCTION DEFINITIONS
    00129  ******************************************************************************
    00130  */
    00131 bool mfp_is_robust_frame(uint16_t frame_cntl, uint8_t action)
    00132 {
    00133     if ((frame_cntl & MAC_FCTRL_TYPE_MASK) != MAC_FCTRL_MGT_T)
    00134         return false;
    00135
    00136     switch (frame_cntl & MAC_FCTRL_SUBT_MASK) {
    00137         case MAC_FCTRL_DEAUTHENT_ST:
    00138         case MAC_FCTRL_DISASSOC_ST:
    00139             return true;
    00140         case MAC_FCTRL_ACTION_ST:
    00141             switch (action) {
    00142                 case MAC_PUBLIC_ACTION_CATEGORY:
    00143                 case MAC_HT_ACTION_CATEGORY:
    00144                 case MAC_UNPROT_WNM_ACTION_CATEGORY:
    00145                 case MAC_SELF_PROT_ACTION_CATEGORY:
    00146                 case MAC_VENDOR_ACTION_CATEGORY:
    00147                     return false;
    00148                 default:
    00149                     return true;
    00150             }
    00151         default :
    00152             return false;
    00153     }
    00154 }
    00155
    00156 bool mfp_ignore_mgmt_frame(struct rx_cntrl_rx_status *rx_status, uint32_t *frame,
    00157                            uint16_t frmlen, bool *upload)
    00158 {
    00159     struct vif_info_tag *vif;
    00160     struct sta_info_tag *sta;
    00161     uint8_t action;
    00162
    00163     // don't ignore non robust mgmt frames
    00164     action = co_read8p((uint32_t)(CPU2HW(frame) + rx_status->machdr_len));
    00165     if (!mfp_is_robust_frame(rx_status->frame_cntl, action))
    00166     {
    00167         return false;
    00168     }
    00169
    00170     // don't expect robust mgt frames from unknown STA (even if MFP is not enabled)
    00171     if ((rx_status->sta_idx == INVALID_STA_IDX) ||
    00172         (rx_status->vif_idx == INVALID_VIF_IDX))
    00173     {
    00174         *upload = false;
    00175         return true;
    00176     }
    00177
    00178     vif = &vif_info_tab[rx_status->vif_idx];
    00179     sta = &sta_info_tab[rx_status->sta_idx];
    00180
    00181     // If no defaut_key, then encryption is not (yet) enabled.
    00182     // Test defaut_key and not default_mgmt_key because in some cases we want to
    00183     // do the following check even when MFP is not enabled:
    00184     // - "group addressed privacy" action frames
    00185     // - unicast robust mgt frames must always be protected for MESH STA
    00186     //   (capa MFP is always set on MESH STA)
    00187     if (! vif->default_key)
    00188     {
    00189         return false;
    00190     }
    00191
    00192     if (rx_status->frame_info & RXU_CNTRL_GROUP_ADDRESSED)
    00193     {
    00194         if (mfp_is_group_addressed_privacy(rx_status->frame_cntl, action))
    00195         {
    00196             // "Group Addressed Privacy" Action frame must be encrypted using group key
    00197             return !(rx_status->frame_cntl & MAC_FCTRL_PROTECTEDFRAME);
    00198         }
    00199         else if (!vif->default_mgmt_key)
    00200         {
    00201             // MFP not enabled
    00202             return false;
    00203         }
    00204         else if (mfp_check_mmic_ie(CPU2HW(frame), frmlen, rx_status->machdr_len, vif, sta))
    00205         {
    00206             // Other broad/muliticast must have a valid MGMT MIC IE
    00207             return false;
    00208         }
    00209         else
    00210         {
    00211             *upload = false;
    00212             return true;
    00213         }
    00214     }
    00215     else if (!STA_CAPA(sta, MFP) ||
    00216              (rx_status->frame_cntl & MAC_FCTRL_PROTECTEDFRAME))
    00217     {
    00218         return false;
    00219     }
    00220     else
    00221     {
    00222         // Unicast frame without encryption
    00223         if ((MAC_FCTRL_IS(rx_status->frame_cntl, DEAUTHENT) ||
    00224              MAC_FCTRL_IS(rx_status->frame_cntl, DISASSOC)) &&
    00225             (action == MAC_RS_CLASS_2_FORBIDDEN ||
    00226              action == MAC_RS_CLASS_3_FORBIDDEN))
    00227         {
    00228             // upload frame to host to start SA query procedure
    00229             *upload = true;
    00230         }
    00231         else
    00232         {
    00233             *upload = false;
    00234         }
    00235     }
    00236
    00237     return true;
    00238 }
    00239
    00240 enum mfp_protection mfp_protect_mgmt_frame(struct txdesc *txdesc,
    00241                                            uint16_t fctl, uint8_t action)
    00242 {
    00243     struct hostdesc *host = &txdesc->host;
    00244     struct vif_info_tag *vif = &vif_info_tab[host->vif_idx];
    00245     struct sta_info_tag *sta = &sta_info_tab[host->staid];
    00246
    00247     // See mfp_ignore_mgmt_frame to known why default_mgmt_key is not tested here
    00248     if ((host->staid == INVALID_STA_IDX) ||
    00249         (!vif->default_key))
    00250     {
    00251         return MFP_NO_PROT;
    00252     }
    00253
    00254     if (!mfp_is_robust_frame(fctl, action))
    00255     {
    00256         // don't protect non robust mgmt frames
    00257         return MFP_NO_PROT;
    00258     }
    00259
    00260     if (MAC_ADDR_GROUP(&sta->mac_addr))
    00261     {
    00262         if (mfp_is_group_addressed_privacy(fctl, action))
    00263             return MFP_UNICAST_PROT;
    00264         else if (!vif->default_mgmt_key)
    00265             return MFP_NO_PROT;
    00266         else
    00267             return MFP_MULTICAST_PROT;
    00268     }
    00269
    00270     if (!STA_CAPA(sta, MFP))
    00271     {
    00272         return MFP_NO_PROT;
    00273     }
    00274
    00275     return MFP_UNICAST_PROT;
    00276 }
    00277
    00278
    00279 int mfp_add_mgmt_mic(struct txdesc *txdesc, uint32_t frame, int len, uint32_t mmic)
    00280 {
    00281     struct hostdesc *host = &txdesc->host;
    00282     struct vif_info_tag *vif = &vif_info_tab[host->vif_idx];
    00283     struct key_info_tag *key;
    00284     uint32_t mmic_ie;
    00285     uint64_t mic;
    00286     int i;
    00287
    00288     if (!vif->default_mgmt_key)
    00289     {
    00290         return 0;
    00291     }
    00292     key = vif->default_mgmt_key;
    00293
    00294     if (mmic)
    00295         mmic_ie = mmic;
    00296     else
    00297         mmic_ie = frame + len;
    00298
    00299     // IE ID - len - key-id
    00300     co_write8p(mmic_ie + MAC_MGMT_MIC_ID_OFT, MAC_ELTID_MGMT_MIC);
    00301     co_write8p(mmic_ie + MAC_MGMT_MIC_LEN_OFT, MAC_MGMT_MIC_LEN - 2);
    00302     co_write16p(mmic_ie + MAC_MGMT_MIC_KEYID_OFT, key->key_idx);
    00303
    00304     // IPN
    00305     key->tx_pn++;
    00306     for (i = 0; i < MAC_MGMT_MIC_IPN_LEN; i++)
    00307     {
    00308         co_write8p(mmic_ie + MAC_MGMT_MIC_IPN_OFT + i, (key->tx_pn >> (8*i)) & 0xff);
    00309     }
    00310
    00311     // MIC
    00312     for (i = 0; i < MAC_MGMT_MIC_MIC_LEN; i++)
    00313     {
    00314         co_write8p(mmic_ie + MAC_MGMT_MIC_MIC_OFT + i, 0);
    00315     }
    00316
    00317     mic = mfp_compute_bip(key, frame, len, MAC_SHORT_MAC_HDR_LEN, mmic);
    00318     for (i = 0; i < MAC_MGMT_MIC_MIC_LEN; i++)
    00319     {
    00320         co_write8p(mmic_ie + MAC_MGMT_MIC_MIC_OFT + i, (mic >> (8*i)) & 0xff);
    00321     }
    00322
    00323     return MAC_MGMT_MIC_LEN;
    00324 }
    00325
    00329 #endif /* NX_MFP */