18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP server/peer: EAP-PSK shared routines 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/aes_wrap.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_defs.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_psk_common.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define aes_block_size 16 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_psk_key_setup(const u8 *psk, u8 *ak, u8 *kdk) 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(ak, 0, aes_block_size); 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (aes_128_encrypt_block(psk, ak, ak)) 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(kdk, ak, aes_block_size); 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ak[aes_block_size - 1] ^= 0x01; 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt kdk[aes_block_size - 1] ^= 0x02; 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (aes_128_encrypt_block(psk, ak, ak) || 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt aes_128_encrypt_block(psk, kdk, kdk)) 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_psk_derive_keys(const u8 *kdk, const u8 *rand_p, u8 *tek, u8 *msk, 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *emsk) 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[aes_block_size]; 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 counter = 1; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (aes_128_encrypt_block(kdk, rand_p, hash)) 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash[aes_block_size - 1] ^= counter; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (aes_128_encrypt_block(kdk, hash, tek)) 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash[aes_block_size - 1] ^= counter; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt counter++; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < EAP_MSK_LEN / aes_block_size; i++) { 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash[aes_block_size - 1] ^= counter; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (aes_128_encrypt_block(kdk, hash, &msk[i * aes_block_size])) 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash[aes_block_size - 1] ^= counter; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt counter++; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < EAP_EMSK_LEN / aes_block_size; i++) { 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash[aes_block_size - 1] ^= counter; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (aes_128_encrypt_block(kdk, hash, 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &emsk[i * aes_block_size])) 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash[aes_block_size - 1] ^= counter; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt counter++; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 69