/*构造组播通告分组*/ static short pack_msk_announcement(struct auth_sta_info_t *sta_info, u8 *sendto_asue, u8 stakey_flag, BOOL if_multi_rekey) { u8 *hmac_data = NULL; u8 *hmac_tar_data =NULL; u8 used_key = sta_info->usksa.dynamic_key_used;; u8 iv[16] = {0,}; wai_fixdata_flag flag ; packet_head head; u16 offset = 0; u16 hmac_data_len = 0; apdata_info *pap = sta_info->pap; memset((u8 *)&flag, 0, 1); memset((u8 *)&head, 0, sizeof(packet_head)); head.version = VERSIONNOW; head.type = WAI; head.sub_type = MSK_ANNOUNCE; head.reserved = RESERVEDDEF; head.data_len = 0x0000; head.frame_sc = 0x00; head.flag = 0x00; head.group_sc = sta_info->ae_group_sc; switch(stakey_flag) { case 0:/*bit5-0,bit6-0*/ flag &= 0x9F ;/*10011111*/ break; case 1:/*bit5-0,bit6-1*/ flag &= 0xDF ;/*11011111*/ break; case 2:/*bit5-1,bit6-0*/ flag &= 0xBF ;/*10111111*/ break; case 3:/*bit5-1,bit6-1*/ flag &= 0xFF ;/*11111111*/ break; default: break; } sta_info->flag &= 0x9F;/*0x9F:10011111*//*先将5和6位清零*/ sta_info->flag |= flag & 0x60;/*0x60:01100000*//*bit5:stakey-session bit6:stakey-del*/ offset = c_pack_packet_head(&head,sendto_asue,offset,FROM_MT_LEN); offset = c_pack_byte((u8)flag, sendto_asue, offset, FROM_MT_LEN); offset = c_pack_byte((u8)pap->msksa.mskid, sendto_asue, offset, FROM_MT_LEN); offset = c_pack_byte((u8)sta_info->usksa.dynamic_key_used, sendto_asue, offset, FROM_MT_LEN); offset = pack_mac(pap->macaddr, sendto_asue, offset); offset = pack_mac(sta_info->mac, sendto_asue, offset); if(if_multi_rekey == FALSE) { offset = c_pack_16bytes(sta_info->gsn, sendto_asue, offset, FROM_MT_LEN); } else{ u8 gsn[16] = {0x5c,0x36,0x5c,0x36,0x5c,0x36,0x5c,0x36, 0x5c,0x36,0x5c,0x36,0x5c,0x36,0x5c,0x36}; /*组播数据序号*/ offset = c_pack_16bytes(gsn, sendto_asue, offset, FROM_MT_LEN); } offset = c_pack_dword((u32)pap->gnonce[0], sendto_asue, offset, FROM_MT_LEN); offset = c_pack_dword((u32)pap->gnonce[1], sendto_asue, offset, FROM_MT_LEN); offset = c_pack_dword((u32)pap->gnonce[2], sendto_asue, offset, FROM_MT_LEN); offset = c_pack_dword((u32)pap->gnonce[3], sendto_asue, offset, FROM_MT_LEN); *(sendto_asue + offset) = MSK_LEN;/*密钥通告数据长度*/ offset += 1; /*加密组播密钥*/ memcpy(iv, (u8 *)pap->gnonce, MSK_LEN); htonl_buffer(iv, MSK_LEN); wpi_encrypt(iv, pap->msksa.msk, MSK_LEN, sta_info->usksa.usk[used_key].kek, sendto_asue+offset); offset += MSK_LEN; /*计算MIC*/ hmac_data = sendto_asue+sizeof(packet_head); hmac_data_len = offset - sizeof(packet_head); hmac_tar_data = (unsigned char *)sendto_asue + offset; hmac_sha256(hmac_data, hmac_data_len, sta_info->usksa.usk[used_key].mck, PAIRKEY_LEN, hmac_tar_data, HMAC_LEN); offset += HMAC_LEN; set_packet_data_len(sendto_asue,offset); return offset; }
/*ofb decrypt*/ int wpi_decrypt(unsigned char * pofbiv_in,unsigned char * pcw_in,unsigned int plcw_in,unsigned char * prkey_in,unsigned char * pbw_out) { return wpi_encrypt(pofbiv_in,pcw_in,plcw_in,prkey_in,pbw_out); }
static int waigroup_multicast_1_2(struct wapi_asue_st* wpa_s, u8* payload, int len) { u8 *pos = payload; u8 mic[20] = {0,}; u8 ct_msk[16]={0,}; u8 iv[16]={0,}; u8 *key_an_id = pos+ 3+ ADDID_LEN + WAI_IV_LEN; u8 *key_data = key_an_id + WAI_KEY_AN_ID_LEN; u8 tmp_msk[16]; struct wapi_usk *usk = NULL; struct wapi_state_machine *sm = wpa_s->wapi_sm; wapi_supplicant_key_negotiation_state_report(WPA_GROUP_HANDSHAKE); iwn_wpa_printf(MSG_DEBUG, "waigroup_multicast_1_2 msg len = %d", len); iwn_wpa_hexdump(MSG_DEBUG, " msg = \n", payload, len); wpa_printf(MSG_DEBUG, "WPA: in %s:%d", __func__, __LINE__); if (WAPISM_UNI_ACK == wpa_s->wapi_state || WAPISM_FINISH == wpa_s->wapi_state) { } else { return -1; } if(payload[0] & BIT(5)) { wpa_printf(MSG_DEBUG, "WPA: STAKEY_NEG is not supptable by ASUE"); return -1; } pos += 1 + BKID_LEN; #ifdef REKEY if(payload[1] != !sm->msksa.mskid) { wpa_printf(MSG_DEBUG, "WPA: MSKID is not invalid"); return -1; } #endif sm->msksa.mskid = payload[1]; if(check_addid(wpa_s, payload + 3) != 0) { wpa_printf(MSG_DEBUG, "WPA: ADDID is wrong"); return -1; } if(check_iv(&sm->msksa, key_an_id) < 0) { wpa_printf(MSG_DEBUG, "WPA: Key annoucement identfier is wrong"); iwn_wpa_hexdump(MSG_DEBUG, "WPA: msk_ann_id", sm->msksa.msk_ann_id, WAI_IV_LEN); iwn_wpa_hexdump(MSG_DEBUG, "rx WPA: Key_an_id", key_an_id, WAI_IV_LEN); return -1; } memcpy(sm->msksa.msk_ann_id, key_an_id, WAI_IV_LEN ); usk = get_usk(sm, payload[2]); if(usk == NULL) { wpa_printf(MSG_DEBUG, "WPA: Key annoucement uskid is wrong"); return -1; } hmac_sha256(payload, len-WAI_MIC_LEN, usk->mak, PAIRKEY_LEN, mic, WAI_MIC_LEN); if(memcmp(mic, payload + len-WAI_MIC_LEN, WAI_MIC_LEN)!=0) { wpa_printf(MSG_DEBUG, "WPA: Multicast announcement packet mic is wrong"); return -1; } memcpy(ct_msk, &key_data[1], PAIRKEY_LEN); memcpy(iv, key_an_id, WAI_IV_LEN); iwn_wpa_hexdump(MSG_DEBUG, "ct_msk", &key_data[1], PAIRKEY_LEN); iwn_wpa_hexdump(MSG_DEBUG, "kek", usk->kek, PAIRKEY_LEN); iwn_wpa_hexdump(MSG_DEBUG, "iv", iv, WAI_IV_LEN); /* decrypt the multicast key */ memset(tmp_msk, 0, sizeof(tmp_msk)); memcpy(tmp_msk, key_data + 1, sizeof(tmp_msk)); wpi_encrypt(iv, tmp_msk, 16, usk->kek, ct_msk); iwn_wpa_hexdump(MSG_DEBUG, "outmkey", ct_msk, PAIRKEY_LEN); key_derivation(ct_msk, key_data[0], (u8 *)MSK_TEXT, strlen(MSK_TEXT), sm->msksa.msk, PAIRKEY_LEN*2, 0); iwn_wpa_hexdump(MSG_DEBUG, "msk", sm->msksa.msk, PAIRKEY_LEN * 2); /*wpa_build_bksa(msksa);*/ if (waigroup_multicast_2_2_send(wpa_s, payload, len)) return -1; return 0; }