INT AirPDcapCcmpDecrypt(
	UINT8 *m,
        gint mac_header_len,
	INT len,
	UCHAR TK1[16])
{
	PAIRPDCAP_MAC_FRAME wh;
	UINT8 aad[2 * AES_BLOCK_LEN];
	UINT8 b0[AES_BLOCK_LEN], b[AES_BLOCK_LEN], a[AES_BLOCK_LEN];
	UINT8 mic[AES_BLOCK_LEN];
	size_t data_len;
	UINT i;
	UINT8 *pos;
	UINT space;
	INT z = mac_header_len;
	rijndael_ctx key;
	UINT64 PN;
	UINT8 *ivp=m+z;

	PN = READ_6(ivp[0], ivp[1], ivp[4], ivp[5], ivp[6], ivp[7]);

	/* freebsd	*/
	rijndael_set_key(&key, TK1, 128);
	wh = (PAIRPDCAP_MAC_FRAME )m;
	data_len = len - (z + AIRPDCAP_CCMP_HEADER+AIRPDCAP_CCMP_TRAILER);
	if (data_len < 1)
	    return 0;
	ccmp_init_blocks(&key, wh, PN, data_len, b0, aad, a, b);
	memcpy(mic, m+len-AIRPDCAP_CCMP_TRAILER, AIRPDCAP_CCMP_TRAILER);
	XOR_BLOCK(mic, b, AIRPDCAP_CCMP_TRAILER);

	i = 1;
	pos = (UINT8 *)m + z + AIRPDCAP_CCMP_HEADER;
	space = len - (z + AIRPDCAP_CCMP_HEADER);

	if (space > data_len)
		space = (UINT)data_len;
	while (space >= AES_BLOCK_LEN) {
		CCMP_DECRYPT(i, b, b0, pos, a, AES_BLOCK_LEN);
		pos += AES_BLOCK_LEN, space -= AES_BLOCK_LEN;
		data_len -= AES_BLOCK_LEN;
		i++;
	}

	if (space != 0)         /* short last block */
		CCMP_DECRYPT(i, b, b0, pos, a, space);

	/*	MIC Key ?= MIC																				*/
	if (memcmp(mic, a, AIRPDCAP_CCMP_TRAILER) == 0) {
		return 0;
	}

	/* TODO replay check	(IEEE 802.11i-2004, pg. 62)			*/
	/* TODO PN must be incremental (IEEE 802.11i-2004, pg. 62)		*/

	return 1;
}
/*		sys/net80211/ieee80211_crypto_tkip.c, 936											*/
INT AirPDcapTkipDecrypt(
    UCHAR *tkip_mpdu,
    size_t mpdu_len,
    UCHAR TA[AIRPDCAP_MAC_LEN],
    UCHAR TK[AIRPDCAP_TK_LEN])
{
    UINT64 TSC64;
    UINT32 TSC;
    UINT16 TSC16;
    UINT8 *IV;
    UINT16 TTAK[AIRPDCAP_TTAK_LEN];
    UINT8 wep_seed[AIRPDCAP_WEP_128_KEY_LEN];

    /* DEBUG_DUMP("TA", TA, 6); */

    IV = tkip_mpdu;

    TSC64 = READ_6(IV[2], IV[0], IV[4], IV[5], IV[6], IV[7]);
    TSC16 = (UINT16)TSC64;

    /* The original code made no sense!!  We were shifting a 16-bit number 16 bits to the right. */
    /* We instead have to have READ_6() be returned to a UINT64 and shift *that* value. */
    TSC = (UINT32)(TSC64 >> 16);

    AirPDcapTkipMixingPhase1(TTAK, TK, TA, TSC);

    AirPDcapTkipMixingPhase2(wep_seed, TK, TTAK, TSC16);

    return AirPDcapWepDecrypt(
               wep_seed,
               AIRPDCAP_WEP_128_KEY_LEN,
               tkip_mpdu + AIRPDCAP_TKIP_HEADER,
               mpdu_len-(AIRPDCAP_TKIP_HEADER+AIRPDCAP_WEP_ICV));	/* MPDU - TKIP_HEADER - MIC	*/

    /* TODO check (IEEE 802.11i-2004, pg. 44)												*/

}
예제 #3
0
IOReturn
IOSCSITape::ReadWrite(IOMemoryDescriptor *dataBuffer, int *realizedBytes)
{
	SCSITaskIdentifier	task			= NULL;
	IOReturn			status			= kIOReturnNoResources;
	SCSITaskStatus		taskStatus		= kSCSITaskStatus_No_Status;
	bool				cmdStatus		= false;
	int					transferSize	= 0;
	
	require((dataBuffer != 0), ErrorExit);
	
	transferSize = dataBuffer->getLength();

	if (IsFixedBlockSize())
	{
		if (transferSize % blksize)
		{
			STATUS_LOG("must be multiple of block size");
			return kIOReturnNotAligned;
		}
		
		transferSize /= blksize;
	}
	
	task = GetSCSITask();
	require((task != 0), ErrorExit);
	
	if (dataBuffer->getDirection() == kIODirectionIn)
	{
		cmdStatus = READ_6(
			task, 
			dataBuffer, 
			blksize, 
			0x0,
			IsFixedBlockSize() ? 0x1 : 0x0,
			transferSize,
			0x00);
	}
	else
	{
		cmdStatus = WRITE_6(
			task, 
			dataBuffer, 
			blksize, 
			IsFixedBlockSize() ? 0x1 : 0x0,
			transferSize, 
			0x00);

		flags |= ST_WRITTEN_TOGGLE;
	}
	
	if (cmdStatus == true)
		taskStatus = DoSCSICommand(task, SCSI_MOTION_TIMEOUT);
		
	*realizedBytes = GetRealizedDataTransferCount(task);

	if (taskStatus == kSCSITaskStatus_GOOD)
		status = kIOReturnSuccess;
	
	ReleaseSCSITask(task);
	
ErrorExit:
	
	return status;
}
예제 #4
0
/*
 * Validate and strip privacy headers (and trailer) for a
 * received frame. The specified key should be correct but
 * is also verified.
 */
static int
ccmp_decap(struct ieee80211_key *k, wbuf_t wbuf, int hdrlen, struct ieee80211_rx_status *rs)
{
    struct ccmp_ctx *ctx = k->wk_private;
    struct ieee80211vap *vap = ctx->cc_vap;
    struct ieee80211_frame *wh;
    uint8_t *ivp, *origHdr;
    u_int64_t pn;
    u_int8_t tid;
    struct ieee80211_mac_stats *mac_stats;
    u_int32_t hwmfp;
    uint8_t  update_keyrsc = 1;

    /*
     * Header should have extended IV and sequence number;
     * verify the former and validate the latter.
     */
    origHdr = (u_int8_t *)wbuf_header(wbuf);
    wh = (struct ieee80211_frame *)origHdr;
    mac_stats = IEEE80211_IS_MULTICAST(wh->i_addr1) ? &vap->iv_multicast_stats : &vap->iv_unicast_stats;
    if (IEEE80211_IS_MFP_FRAME(wh)) {
            IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, "%s MFP frame\n", __func__);
    }

    if (rs->rs_flags & IEEE80211_RX_DECRYPT_ERROR) {
        IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, "%s decrypt error\n", __func__);
        if (IEEE80211_IS_MFP_FRAME(wh)) {
            /* It may not be real crypto error, but hardware didn't do correct
             * decryption. Try software decrypt later.
             */
            rs->rs_flags &= ~IEEE80211_RX_DECRYPT_ERROR;
            rs->rs_flags |= IEEE80211_RX_MIC_ERROR;
        } else {
            /* The frame already failed decryption in hardware,
             * just update statistics and return. */
            mac_stats->ims_rx_ccmpmic++;
            return 0;
        }
    }

    ivp = origHdr + hdrlen;
    if ((ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV) == 0) {
        /*
         * No extended IV; discard frame.
         */
        IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2,
                           "%s", "Missing ExtIV for AES-CCM cipher");
        mac_stats->ims_rx_ccmpformat++;
        return 0;
    }
    tid = IEEE80211_NON_QOS_SEQ;
    if (IEEE80211_QOS_HAS_SEQ(wh)) {
        if ( (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) 
             == IEEE80211_FC1_DIR_DSTODS ) {
            tid = ((struct ieee80211_qosframe_addr4 *)wh)->i_qos[0] & IEEE80211_QOS_TID;
        } else {
            tid = ((struct ieee80211_qosframe *)wh)->i_qos[0] & IEEE80211_QOS_TID;
        }
    }

    /* NB: assume IEEEE80211_WEP_MINLEN covers the extended IV */ 
    pn = READ_6(ivp[0], ivp[1], ivp[4], ivp[5], ivp[6], ivp[7]);
    if (pn <= k->wk_keyrsc[tid]) {
        /*
         * Replay violation.
         */
        IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO,
                          "%s: CCMP Replay! Throw away. new pn=0x%x%x, "
                          "current pn=0x%x%x. seq=0x%x,Rsvd=0x%x,keyID=0x%x,tid=%d\n", 
                           __func__,
                           (u_int32_t)(pn>>32), (u_int32_t)pn, 
                           (u_int32_t)(k->wk_keyrsc[tid] >> 32), (u_int32_t)k->wk_keyrsc[tid],
                           *(u_int16_t*)(wh->i_seq), 
                           ivp[2], ivp[3],
                           tid
                           );
        ieee80211_notify_replay_failure(vap, wh, k, pn);
        mac_stats->ims_rx_ccmpreplay++;
        return 0;
    }