1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* 2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * EAP server/peer: EAP-PSK shared routines 3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi> 4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program is free software; you can redistribute it and/or modify 6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * it under the terms of the GNU General Public License version 2 as 7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * published by the Free Software Foundation. 8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * license. 11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * See README and COPYING for more details. 13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "includes.h" 16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "common.h" 18b349ef9e9f3f5399bf96b3c1c663cb9e547f50a1Dmitry Shmidt#include "crypto/aes_wrap.h" 19526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "eap_defs.h" 20526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "eap_psk_common.h" 21526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 22526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define aes_block_size 16 23526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 24526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint eap_psk_key_setup(const u8 *psk, u8 *ak, u8 *kdk) 26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(ak, 0, aes_block_size); 28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (aes_128_encrypt_block(psk, ak, ak)) 29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(kdk, ak, aes_block_size); 31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ak[aes_block_size - 1] ^= 0x01; 32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt kdk[aes_block_size - 1] ^= 0x02; 33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (aes_128_encrypt_block(psk, ak, ak) || 34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt aes_128_encrypt_block(psk, kdk, kdk)) 35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint eap_psk_derive_keys(const u8 *kdk, const u8 *rand_p, u8 *tek, u8 *msk, 41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *emsk) 42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 hash[aes_block_size]; 44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 counter = 1; 45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int i; 46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (aes_128_encrypt_block(kdk, rand_p, hash)) 48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hash[aes_block_size - 1] ^= counter; 51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (aes_128_encrypt_block(kdk, hash, tek)) 52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hash[aes_block_size - 1] ^= counter; 54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt counter++; 55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < EAP_MSK_LEN / aes_block_size; i++) { 57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hash[aes_block_size - 1] ^= counter; 58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (aes_128_encrypt_block(kdk, hash, &msk[i * aes_block_size])) 59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hash[aes_block_size - 1] ^= counter; 61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt counter++; 62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < EAP_EMSK_LEN / aes_block_size; i++) { 65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hash[aes_block_size - 1] ^= counter; 66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (aes_128_encrypt_block(kdk, hash, 67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &emsk[i * aes_block_size])) 68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hash[aes_block_size - 1] ^= counter; 70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt counter++; 71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 75