$search
00001 /* 00002 * EAP server/peer: EAP-PSK shared routines 00003 * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "includes.h" 00016 00017 #include "common.h" 00018 #include "crypto/aes_wrap.h" 00019 #include "eap_defs.h" 00020 #include "eap_psk_common.h" 00021 00022 #define aes_block_size 16 00023 00024 00025 int eap_psk_key_setup(const u8 *psk, u8 *ak, u8 *kdk) 00026 { 00027 os_memset(ak, 0, aes_block_size); 00028 if (aes_128_encrypt_block(psk, ak, ak)) 00029 return -1; 00030 os_memcpy(kdk, ak, aes_block_size); 00031 ak[aes_block_size - 1] ^= 0x01; 00032 kdk[aes_block_size - 1] ^= 0x02; 00033 if (aes_128_encrypt_block(psk, ak, ak) || 00034 aes_128_encrypt_block(psk, kdk, kdk)) 00035 return -1; 00036 return 0; 00037 } 00038 00039 00040 int eap_psk_derive_keys(const u8 *kdk, const u8 *rand_p, u8 *tek, u8 *msk, 00041 u8 *emsk) 00042 { 00043 u8 hash[aes_block_size]; 00044 u8 counter = 1; 00045 int i; 00046 00047 if (aes_128_encrypt_block(kdk, rand_p, hash)) 00048 return -1; 00049 00050 hash[aes_block_size - 1] ^= counter; 00051 if (aes_128_encrypt_block(kdk, hash, tek)) 00052 return -1; 00053 hash[aes_block_size - 1] ^= counter; 00054 counter++; 00055 00056 for (i = 0; i < EAP_MSK_LEN / aes_block_size; i++) { 00057 hash[aes_block_size - 1] ^= counter; 00058 if (aes_128_encrypt_block(kdk, hash, &msk[i * aes_block_size])) 00059 return -1; 00060 hash[aes_block_size - 1] ^= counter; 00061 counter++; 00062 } 00063 00064 for (i = 0; i < EAP_EMSK_LEN / aes_block_size; i++) { 00065 hash[aes_block_size - 1] ^= counter; 00066 if (aes_128_encrypt_block(kdk, hash, 00067 &emsk[i * aes_block_size])) 00068 return -1; 00069 hash[aes_block_size - 1] ^= counter; 00070 counter++; 00071 } 00072 00073 return 0; 00074 }