xref: /freebsd/contrib/wpa/src/eap_common/eap_psk_common.c (revision 0bfd163f522701b486e066fa2e56624c02f5081a)
139beb93cSSam Leffler /*
239beb93cSSam Leffler  * EAP server/peer: EAP-PSK shared routines
339beb93cSSam Leffler  * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
439beb93cSSam Leffler  *
5*f05cddf9SRui Paulo  * This software may be distributed under the terms of the BSD license.
6*f05cddf9SRui Paulo  * See README for more details.
739beb93cSSam Leffler  */
839beb93cSSam Leffler 
939beb93cSSam Leffler #include "includes.h"
1039beb93cSSam Leffler 
1139beb93cSSam Leffler #include "common.h"
12e28a4053SRui Paulo #include "crypto/aes_wrap.h"
1339beb93cSSam Leffler #include "eap_defs.h"
1439beb93cSSam Leffler #include "eap_psk_common.h"
1539beb93cSSam Leffler 
1639beb93cSSam Leffler #define aes_block_size 16
1739beb93cSSam Leffler 
1839beb93cSSam Leffler 
eap_psk_key_setup(const u8 * psk,u8 * ak,u8 * kdk)1939beb93cSSam Leffler int eap_psk_key_setup(const u8 *psk, u8 *ak, u8 *kdk)
2039beb93cSSam Leffler {
2139beb93cSSam Leffler 	os_memset(ak, 0, aes_block_size);
2239beb93cSSam Leffler 	if (aes_128_encrypt_block(psk, ak, ak))
2339beb93cSSam Leffler 		return -1;
2439beb93cSSam Leffler 	os_memcpy(kdk, ak, aes_block_size);
2539beb93cSSam Leffler 	ak[aes_block_size - 1] ^= 0x01;
2639beb93cSSam Leffler 	kdk[aes_block_size - 1] ^= 0x02;
2739beb93cSSam Leffler 	if (aes_128_encrypt_block(psk, ak, ak) ||
2839beb93cSSam Leffler 	    aes_128_encrypt_block(psk, kdk, kdk))
2939beb93cSSam Leffler 		return -1;
3039beb93cSSam Leffler 	return 0;
3139beb93cSSam Leffler }
3239beb93cSSam Leffler 
3339beb93cSSam Leffler 
eap_psk_derive_keys(const u8 * kdk,const u8 * rand_p,u8 * tek,u8 * msk,u8 * emsk)3439beb93cSSam Leffler int eap_psk_derive_keys(const u8 *kdk, const u8 *rand_p, u8 *tek, u8 *msk,
3539beb93cSSam Leffler 			u8 *emsk)
3639beb93cSSam Leffler {
3739beb93cSSam Leffler 	u8 hash[aes_block_size];
3839beb93cSSam Leffler 	u8 counter = 1;
3939beb93cSSam Leffler 	int i;
4039beb93cSSam Leffler 
4139beb93cSSam Leffler 	if (aes_128_encrypt_block(kdk, rand_p, hash))
4239beb93cSSam Leffler 		return -1;
4339beb93cSSam Leffler 
4439beb93cSSam Leffler 	hash[aes_block_size - 1] ^= counter;
4539beb93cSSam Leffler 	if (aes_128_encrypt_block(kdk, hash, tek))
4639beb93cSSam Leffler 		return -1;
4739beb93cSSam Leffler 	hash[aes_block_size - 1] ^= counter;
4839beb93cSSam Leffler 	counter++;
4939beb93cSSam Leffler 
5039beb93cSSam Leffler 	for (i = 0; i < EAP_MSK_LEN / aes_block_size; i++) {
5139beb93cSSam Leffler 		hash[aes_block_size - 1] ^= counter;
5239beb93cSSam Leffler 		if (aes_128_encrypt_block(kdk, hash, &msk[i * aes_block_size]))
5339beb93cSSam Leffler 			return -1;
5439beb93cSSam Leffler 		hash[aes_block_size - 1] ^= counter;
5539beb93cSSam Leffler 		counter++;
5639beb93cSSam Leffler 	}
5739beb93cSSam Leffler 
5839beb93cSSam Leffler 	for (i = 0; i < EAP_EMSK_LEN / aes_block_size; i++) {
5939beb93cSSam Leffler 		hash[aes_block_size - 1] ^= counter;
6039beb93cSSam Leffler 		if (aes_128_encrypt_block(kdk, hash,
6139beb93cSSam Leffler 					  &emsk[i * aes_block_size]))
6239beb93cSSam Leffler 			return -1;
6339beb93cSSam Leffler 		hash[aes_block_size - 1] ^= counter;
6439beb93cSSam Leffler 		counter++;
6539beb93cSSam Leffler 	}
6639beb93cSSam Leffler 
6739beb93cSSam Leffler 	return 0;
6839beb93cSSam Leffler }
69