Example #1
0
static void test_vector_ccmp(void)
{
	u8 tk[] = { 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85,
		    0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f };
	u8 pn[] = { 0xB5, 0x03, 0x97, 0x76, 0xE7, 0x0C };
	u8 frame[] = {
		0x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28,
		0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
		0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33,
		0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae,
		0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb,
		0x7e, 0x78, 0xa0, 0x50
	};
	u8 *enc, *plain;
	size_t enc_len, plain_len;
	u8 fcs[4];

	wpa_printf(MSG_INFO, "\nIEEE Std 802.11-2012, M.6.4 CCMP test "
		   "vector\n");

	wpa_hexdump(MSG_INFO, "TK", tk, sizeof(tk));
	wpa_hexdump(MSG_INFO, "PN", pn, sizeof(pn));
	wpa_hexdump(MSG_INFO, "802.11 Header", frame, 24);
	wpa_hexdump(MSG_INFO, "Plaintext Data", frame + 24, sizeof(frame) - 24);

	enc = ccmp_encrypt(tk, frame, sizeof(frame), 24, NULL, pn, 0, &enc_len);
	if (enc == NULL) {
		wpa_printf(MSG_ERROR, "Failed to encrypt CCMP frame");
		return;
	}

	wpa_hexdump(MSG_INFO, "Encrypted MPDU (without FCS)", enc, enc_len);
	WPA_PUT_LE32(fcs, crc32(enc, enc_len));
	wpa_hexdump(MSG_INFO, "FCS", fcs, sizeof(fcs));

	wpa_debug_level = MSG_INFO;
	plain = ccmp_decrypt(tk, (const struct ieee80211_hdr *) enc,
			     enc + 24, enc_len - 24, &plain_len);
	wpa_debug_level = MSG_EXCESSIVE;
	os_free(enc);

	if (plain == NULL) {
		wpa_printf(MSG_ERROR, "Failed to decrypt CCMP frame");
		return;
	}

	if (plain_len != sizeof(frame) - 24 ||
	    os_memcmp(plain, frame + 24, plain_len) != 0) {
		wpa_hexdump(MSG_ERROR, "Decryption result did not match",
			    plain, plain_len);
	}

	os_free(plain);
}
Example #2
0
static void test_vector_ccmp_mgmt(void)
{
	u8 tk[] = { 0x66, 0xed, 0x21, 0x04, 0x2f, 0x9f, 0x26, 0xd7,
		    0x11, 0x57, 0x06, 0xe4, 0x04, 0x14, 0xcf, 0x2e };
	u8 pn[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
	u8 frame[] = {
		0xc0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
		0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
		0x02, 0x00
	};
	u8 *enc, *plain;
	size_t enc_len, plain_len;

	wpa_printf(MSG_INFO, "\nIEEE Std 802.11-2012, M.9.2 CCMP with unicast "
		   "Deauthentication frame\n");

	wpa_hexdump(MSG_INFO, "TK", tk, sizeof(tk));
	wpa_hexdump(MSG_INFO, "PN", pn, sizeof(pn));
	wpa_hexdump(MSG_INFO, "802.11 Header", frame, 24);
	wpa_hexdump(MSG_INFO, "Plaintext Data", frame + 24, sizeof(frame) - 24);

	enc = ccmp_encrypt(tk, frame, sizeof(frame), 24, NULL, pn, 0, &enc_len);
	if (enc == NULL) {
		wpa_printf(MSG_ERROR, "Failed to encrypt CCMP frame");
		return;
	}

	wpa_hexdump(MSG_INFO, "Encrypted MPDU (without FCS)", enc, enc_len);

	wpa_debug_level = MSG_INFO;
	plain = ccmp_decrypt(tk, (const struct ieee80211_hdr *) enc,
			     enc + 24, enc_len - 24, &plain_len);
	wpa_debug_level = MSG_EXCESSIVE;
	os_free(enc);

	if (plain == NULL) {
		wpa_printf(MSG_ERROR, "Failed to decrypt CCMP frame");
		return;
	}

	if (plain_len != sizeof(frame) - 24 ||
	    os_memcmp(plain, frame + 24, plain_len) != 0) {
		wpa_hexdump(MSG_ERROR, "Decryption result did not match",
			    plain, plain_len);
	}

	os_free(plain);
}
Example #3
0
/*
 * Add privacy headers appropriate for the specified key.
 */
static int
ccmp_encap(struct ieee80211_key *k, wbuf_t wbuf, u_int8_t keyid)
{
    struct ccmp_ctx *ctx = k->wk_private;
    struct ieee80211com *ic = ctx->cc_ic;
    u_int8_t *ivp;
    int hdrlen;
    int is4addr, isqos, owl_wdswar;
    struct ieee80211_frame *wh;
    struct ieee80211_node *ni = wbuf_get_node(wbuf);

    wh = (struct ieee80211_frame *)wbuf_header(wbuf);
    is4addr = ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) ? 1 : 0;
    isqos = IEEE80211_QOS_HAS_SEQ(wh);
    owl_wdswar = (ni->ni_flags & IEEE80211_NODE_OWL_WDSWAR);

    hdrlen = ieee80211_hdrspace(ic, wbuf_header(wbuf));

    /*
     * Copy down 802.11 header and add the IV, KeyID, and ExtIV.
     */
#ifndef __CARRIER_PLATFORM__
    ivp = (u_int8_t *)wbuf_push(wbuf, ccmp.ic_header);

    /* 
     * refresh the wh pointer,
     * wbuf header  pointer is changed with wbuf_push.
     */
    wh = (struct ieee80211_frame *) wbuf_header(wbuf); /* recompute wh */

    memmove(ivp, ivp + ccmp.ic_header, hdrlen);
#else
    if (wbuf_is_encap_done(wbuf)) {
        ivp = (u_int8_t *)wbuf_header(wbuf);
    }
    else { 
        ivp = (u_int8_t *)wbuf_push(wbuf, ccmp.ic_header);
        memmove(ivp, ivp + ccmp.ic_header, hdrlen);
        /* 
         * refresh the wh pointer,
         * wbuf header  pointer is changed with wbuf_push.
         */
        wh = (struct ieee80211_frame *) wbuf_header(wbuf); /* recompute wh */
    }
#endif
    ivp += hdrlen;

    /*
     * Due to OWL specific HW bug, increment key tsc by 16, since
     * we're copying the TID into bits [3:0] of IV0.
     * XXX: Need logic to not implement workaround for SOWL or greater.
     */
    if (is4addr && isqos && owl_wdswar)
        k->wk_keytsc += 16;
    else
        k->wk_keytsc++;		/* XXX wrap at 48 bits */

    ivp[0] = k->wk_keytsc >> 0;		/* PN0 */
    ivp[1] = k->wk_keytsc >> 8;		/* PN1 */
    ivp[2] = 0;				/* Reserved */
    ivp[3] = keyid | IEEE80211_WEP_EXTIV;	/* KeyID | ExtID */
    ivp[4] = k->wk_keytsc >> 16;		/* PN2 */
    ivp[5] = k->wk_keytsc >> 24;		/* PN3 */
    ivp[6] = k->wk_keytsc >> 32;		/* PN4 */
    ivp[7] = k->wk_keytsc >> 40;		/* PN5 */

    /*
     * Finally, do software encrypt if neeed.
     */
    if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
        if (!ccmp_encrypt(k, wbuf, hdrlen, 0)) {
            return 0;
        }
    }
    if ((k->wk_flags & IEEE80211_KEY_MFP) && IEEE80211_IS_MFP_FRAME(wh)) {
        if (ic->ic_get_mfpsupport(ic) != IEEE80211_MFP_HW_CRYPTO) {
            /* HW MFP is not enabled - do software encrypt */
            if (!ccmp_encrypt(k, wbuf, hdrlen, 1)) {
                return 0;
            }
        }
    }
    return 1;
}