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