eap_psk_common.c
Go to the documentation of this file.
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 }


wpa_supplicant_node
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Jan 2 2014 11:25:13