eap_psk_common.c revision 189251
1189251Ssam/* 2189251Ssam * EAP server/peer: EAP-PSK shared routines 3189251Ssam * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi> 4189251Ssam * 5189251Ssam * This program is free software; you can redistribute it and/or modify 6189251Ssam * it under the terms of the GNU General Public License version 2 as 7189251Ssam * published by the Free Software Foundation. 8189251Ssam * 9189251Ssam * Alternatively, this software may be distributed under the terms of BSD 10189251Ssam * license. 11189251Ssam * 12189251Ssam * See README and COPYING for more details. 13189251Ssam */ 14189251Ssam 15189251Ssam#include "includes.h" 16189251Ssam 17189251Ssam#include "common.h" 18189251Ssam#include "aes_wrap.h" 19189251Ssam#include "eap_defs.h" 20189251Ssam#include "eap_psk_common.h" 21189251Ssam 22189251Ssam#define aes_block_size 16 23189251Ssam 24189251Ssam 25189251Ssamint eap_psk_key_setup(const u8 *psk, u8 *ak, u8 *kdk) 26189251Ssam{ 27189251Ssam os_memset(ak, 0, aes_block_size); 28189251Ssam if (aes_128_encrypt_block(psk, ak, ak)) 29189251Ssam return -1; 30189251Ssam os_memcpy(kdk, ak, aes_block_size); 31189251Ssam ak[aes_block_size - 1] ^= 0x01; 32189251Ssam kdk[aes_block_size - 1] ^= 0x02; 33189251Ssam if (aes_128_encrypt_block(psk, ak, ak) || 34189251Ssam aes_128_encrypt_block(psk, kdk, kdk)) 35189251Ssam return -1; 36189251Ssam return 0; 37189251Ssam} 38189251Ssam 39189251Ssam 40189251Ssamint eap_psk_derive_keys(const u8 *kdk, const u8 *rand_p, u8 *tek, u8 *msk, 41189251Ssam u8 *emsk) 42189251Ssam{ 43189251Ssam u8 hash[aes_block_size]; 44189251Ssam u8 counter = 1; 45189251Ssam int i; 46189251Ssam 47189251Ssam if (aes_128_encrypt_block(kdk, rand_p, hash)) 48189251Ssam return -1; 49189251Ssam 50189251Ssam hash[aes_block_size - 1] ^= counter; 51189251Ssam if (aes_128_encrypt_block(kdk, hash, tek)) 52189251Ssam return -1; 53189251Ssam hash[aes_block_size - 1] ^= counter; 54189251Ssam counter++; 55189251Ssam 56189251Ssam for (i = 0; i < EAP_MSK_LEN / aes_block_size; i++) { 57189251Ssam hash[aes_block_size - 1] ^= counter; 58189251Ssam if (aes_128_encrypt_block(kdk, hash, &msk[i * aes_block_size])) 59189251Ssam return -1; 60189251Ssam hash[aes_block_size - 1] ^= counter; 61189251Ssam counter++; 62189251Ssam } 63189251Ssam 64189251Ssam for (i = 0; i < EAP_EMSK_LEN / aes_block_size; i++) { 65189251Ssam hash[aes_block_size - 1] ^= counter; 66189251Ssam if (aes_128_encrypt_block(kdk, hash, 67189251Ssam &emsk[i * aes_block_size])) 68189251Ssam return -1; 69189251Ssam hash[aes_block_size - 1] ^= counter; 70189251Ssam counter++; 71189251Ssam } 72189251Ssam 73189251Ssam return 0; 74189251Ssam} 75