eap_psk_common.c revision 8d520ff1dc2da35cdca849e982051b86468016d8
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP server/peer: EAP-PSK shared routines 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This program is free software; you can redistribute it and/or modify 68d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * it under the terms of the GNU General Public License version 2 as 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * published by the Free Software Foundation. 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * license. 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * See README and COPYING for more details. 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/aes_wrap.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_defs.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_psk_common.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define aes_block_size 16 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_psk_key_setup(const u8 *psk, u8 *ak, u8 *kdk) 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(ak, 0, aes_block_size); 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (aes_128_encrypt_block(psk, ak, ak)) 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(kdk, ak, aes_block_size); 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ak[aes_block_size - 1] ^= 0x01; 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt kdk[aes_block_size - 1] ^= 0x02; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (aes_128_encrypt_block(psk, ak, ak) || 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt aes_128_encrypt_block(psk, kdk, kdk)) 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_psk_derive_keys(const u8 *kdk, const u8 *rand_p, u8 *tek, u8 *msk, 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *emsk) 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[aes_block_size]; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 counter = 1; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (aes_128_encrypt_block(kdk, rand_p, hash)) 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash[aes_block_size - 1] ^= counter; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (aes_128_encrypt_block(kdk, hash, tek)) 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash[aes_block_size - 1] ^= counter; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt counter++; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < EAP_MSK_LEN / aes_block_size; i++) { 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash[aes_block_size - 1] ^= counter; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (aes_128_encrypt_block(kdk, hash, &msk[i * aes_block_size])) 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash[aes_block_size - 1] ^= counter; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt counter++; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < EAP_EMSK_LEN / aes_block_size; i++) { 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash[aes_block_size - 1] ^= counter; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (aes_128_encrypt_block(kdk, hash, 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &emsk[i * aes_block_size])) 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash[aes_block_size - 1] ^= counter; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt counter++; 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 75