예제 #1
0
static int eap_gpsk_gkdf_cmac(const u8 *psk /* Y */,
			      const u8 *data /* Z */, size_t data_len,
			      u8 *buf, size_t len /* X */)
{
	u8 *opos;
	size_t i, n, hashlen, left, clen;
	u8 ibuf[2], hash[16];
	const u8 *addr[2];
	size_t vlen[2];

	hashlen = sizeof(hash);
	/* M_i = MAC_Y (i || Z); (MAC = AES-CMAC-128) */
	addr[0] = ibuf;
	vlen[0] = sizeof(ibuf);
	addr[1] = data;
	vlen[1] = data_len;

	opos = buf;
	left = len;
	n = (len + hashlen - 1) / hashlen;
	for (i = 1; i <= n; i++) {
		WPA_PUT_BE16(ibuf, i);
		if (omac1_aes_128_vector(psk, 2, addr, vlen, hash))
			return -1;
		clen = left > hashlen ? hashlen : left;
		os_memcpy(opos, hash, clen);
		opos += clen;
		left -= clen;
	}

	return 0;
}
예제 #2
0
int main(int argc, char *argv[])
{
	u8 kek[] = {
		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
	};
	u8 plain[] = {
		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
		0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
	};
	u8 crypt[] = {
		0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47,
		0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82,
		0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5
	};
	u8 result[24];
	int ret = 0;
	unsigned int i;
	struct omac1_test_vector *tv;

	if (aes_wrap(kek, 2, plain, result)) {
		printf("AES-WRAP-128-128 reported failure\n");
		ret++;
	}
	if (memcmp(result, crypt, 24) != 0) {
		printf("AES-WRAP-128-128 failed\n");
		ret++;
	}
	if (aes_unwrap(kek, 2, crypt, result)) {
		printf("AES-UNWRAP-128-128 reported failure\n");
		ret++;
	}
	if (memcmp(result, plain, 16) != 0) {
		printf("AES-UNWRAP-128-128 failed\n");
		ret++;
		for (i = 0; i < 16; i++)
			printf(" %02x", result[i]);
		printf("\n");
	}

	test_aes_perf();

	for (i = 0; i < ARRAY_SIZE(test_vectors); i++) {
		tv = &test_vectors[i];
		if (omac1_aes_128(tv->k, tv->msg, tv->msg_len, result) ||
		    memcmp(result, tv->tag, 16) != 0) {
			printf("OMAC1-AES-128 test vector %d failed\n", i);
			ret++;
		}

		if (tv->msg_len > 1) {
			const u8 *addr[2];
			size_t len[2];

			addr[0] = tv->msg;
			len[0] = 1;
			addr[1] = tv->msg + 1;
			len[1] = tv->msg_len - 1;

			if (omac1_aes_128_vector(tv->k, 2, addr, len,
						 result) ||
			    memcmp(result, tv->tag, 16) != 0) {
				printf("OMAC1-AES-128(vector) test vector %d "
				       "failed\n", i);
				ret++;
			}
		}
	}

	ret += test_eax();

	ret += test_cbc();

	ret += test_gcm();

	if (ret)
		printf("FAILED!\n");

	return ret;
}
예제 #3
0
int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr,
	       const u8 *ap_addr, u8 transaction_seqnum,
	       const u8 *mdie, size_t mdie_len,
	       const u8 *ftie, size_t ftie_len,
	       const u8 *rsnie, size_t rsnie_len,
	       const u8 *ric, size_t ric_len, u8 *mic)
{
	const u8 *addr[9];
	size_t len[9];
	size_t i, num_elem = 0;
	u8 zero_mic[16];

	if (kck_len != 16) {
		wpa_printf(MSG_WARNING, "FT: Unsupported KCK length %u",
			   (unsigned int) kck_len);
		return -1;
	}

	addr[num_elem] = sta_addr;
	len[num_elem] = ETH_ALEN;
	num_elem++;

	addr[num_elem] = ap_addr;
	len[num_elem] = ETH_ALEN;
	num_elem++;

	addr[num_elem] = &transaction_seqnum;
	len[num_elem] = 1;
	num_elem++;

	if (rsnie) {
		addr[num_elem] = rsnie;
		len[num_elem] = rsnie_len;
		num_elem++;
	}
	if (mdie) {
		addr[num_elem] = mdie;
		len[num_elem] = mdie_len;
		num_elem++;
	}
	if (ftie) {
		if (ftie_len < 2 + sizeof(struct rsn_ftie))
			return -1;

		/* IE hdr and mic_control */
		addr[num_elem] = ftie;
		len[num_elem] = 2 + 2;
		num_elem++;

		/* MIC field with all zeros */
		os_memset(zero_mic, 0, sizeof(zero_mic));
		addr[num_elem] = zero_mic;
		len[num_elem] = sizeof(zero_mic);
		num_elem++;

		/* Rest of FTIE */
		addr[num_elem] = ftie + 2 + 2 + 16;
		len[num_elem] = ftie_len - (2 + 2 + 16);
		num_elem++;
	}
	if (ric) {
		addr[num_elem] = ric;
		len[num_elem] = ric_len;
		num_elem++;
	}

	for (i = 0; i < num_elem; i++)
		wpa_hexdump(MSG_MSGDUMP, "FT: MIC data", addr[i], len[i]);
	if (omac1_aes_128_vector(kck, num_elem, addr, len, mic))
		return -1;

	return 0;
}