⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aka.c

📁 Linux上的802.1x 的supplicant的实现。很多supplicant程序都是基于它开发的
💻 C
字号:
/******************************************************************** EAPOL Function implementations for supplicant *  * File: aka.c * * Licensed under a dual GPL/BSD license.  (See LICENSE file for more info.) * * Authors: Chris.Hessing@utah.edu * * $Id: aka.c,v 1.13 2006/06/01 22:49:50 galimorerpg Exp $ * $Date: 2006/06/01 22:49:50 $ * $Log: aka.c,v $ * Revision 1.13  2006/06/01 22:49:50  galimorerpg * Converted all instances of u_char to uint8_t * Fixed a bad #include in the generic frame handler. * * Revision 1.12  2006/05/26 22:04:58  chessing * Fixed some memory access errors, and cleaned up some wext stuff that was causing issues with the madwifi driver in wext mode. * * Revision 1.11  2006/04/25 01:17:43  chessing * LOTS of code cleanups, new error checking/debugging code added, and other misc. fixes/changes. * * Revision 1.10  2006/03/28 21:16:07  chessing * Fixes to EAP-AKA, and PEAP.  PEAP now handles inner success messages, and works with Funk SBR. * * Revision 1.9  2006/03/21 18:22:10  chessing * Fixes to EAP-AKA code.  Changed a few defaults to disable Xsupplicant based roaming, and passive scanning for this release.  (It would currently cause more problems than it would solve. * * Revision 1.8  2006/03/08 00:16:04  chessing * Fixed EAP hints code to work correctly when the request ID packet is padded out with null bytes.  (Observed in Aruba APs.)  Some changes/fixes for the EAP-AKA module. * * Revision 1.7  2006/02/23 22:26:53  chessing * Fix for bug id #1415020.  'Building Xsupplicant 1.2.3 Fails on FC4'. * * Revision 1.6  2005/08/14 02:11:09  chessing * Fixes for EAP-AKA.  It should now really behave the way it is supposed to. ;) * * Revision 1.5  2005/08/09 01:39:15  chessing * Cleaned out old commit notes from the released version.  Added a few small features including the ability to disable the friendly warnings that are spit out.  (Such as the warning that is displayed when keys aren't rotated after 10 minutes.)  We should also be able to start when the interface is down.  Last, but not least, we can handle empty network configs.  (This may be useful for situations where there isn't a good reason to have a default network defined.) * * *******************************************************************//******************************************************************* * * The development of the EAP/AKA support was funded by Internet * Foundation Austria (http://www.nic.at/ipa) * *******************************************************************/#ifdef EAP_SIM_ENABLE#include <inttypes.h>#include <string.h>#include <openssl/hmac.h>#include <openssl/sha.h>#include "winscard.h"#include "profile.h"#include "xsupconfig.h"#include "eap.h"#include "../sim/eapsim.h"#include "eapaka.h"#include "xsup_debug.h"#include "xsup_err.h"#include "../sim/sm_handler.h"#include "../sim/fips.h"#ifdef USE_EFENCE#include <efence.h>#endifchar *do_sha1(char *tohash, int size);int aka_do_at_rand(struct aka_eaptypedata *mydata, uint8_t *dataoffs, 		   int *packet_offset){  struct typelengthres *typelenres;  if (!xsup_assert((mydata != NULL), "mydata != NULL", FALSE))    return XEMALLOC;  if (!xsup_assert((dataoffs != NULL), "dataoffs != NULL", FALSE))    return XEMALLOC;  if (!xsup_assert((packet_offset != NULL), "packet_offset != NULL", FALSE))    return XEMALLOC;  debug_printf(DEBUG_AUTHTYPES, "Got an AT_RAND.\n");  typelenres = (struct typelengthres *)&dataoffs[*packet_offset];  *packet_offset+=4;    memcpy(mydata->random_num, &dataoffs[*packet_offset], 16);  debug_printf(DEBUG_AUTHTYPES, "Random = ");  debug_hex_printf(DEBUG_AUTHTYPES, mydata->random_num, 16);  *packet_offset+=16;  return XENONE;}int aka_skip_not_implemented(uint8_t *dataoffs, int *packet_offset){  struct typelengthres *typelenres;  if (!xsup_assert((dataoffs != NULL), "dataoffs != NULL", FALSE))    return XEMALLOC;  if (!xsup_assert((packet_offset != NULL), "packet_offset != NULL", FALSE))    return XEMALLOC;  typelenres = (struct typelengthres *)&dataoffs[*packet_offset];  debug_printf(DEBUG_NORMAL, "Skipping unknown type! (%02X)\n", typelenres->type);  *packet_offset+= (typelenres->length * 4);  return XENONE;}int aka_do_at_autn(struct aka_eaptypedata *mydata, uint8_t *dataoffs,		   int *packet_offset){  struct typelengthres *typelenres;  if (!xsup_assert((mydata != NULL), "mydata != NULL", FALSE))    return XEMALLOC;  if (!xsup_assert((dataoffs != NULL), "dataoffs != NULL", FALSE))    return XEMALLOC;  if (!xsup_assert((packet_offset != NULL), "packet_offset != NULL", FALSE))    return XEMALLOC;  debug_printf(DEBUG_AUTHTYPES, "Got AT_AUTN!\n");  typelenres = (struct typelengthres *)&dataoffs[*packet_offset];  *packet_offset+=4;  memcpy(mydata->autn, &dataoffs[*packet_offset], 16);  debug_printf(DEBUG_AUTHTYPES, "AUTN = ");  debug_hex_printf(DEBUG_AUTHTYPES, mydata->autn, 16);  *packet_offset+=16;  return XENONE;}int aka_do_at_mac(struct generic_eap_data *thisint, 		  struct aka_eaptypedata *mydata, uint8_t *dataoffs, int insize,		  int *packet_offset, char *username){  int saved_offset, reslen, i, value16, x;  unsigned char auts[16], sres[16], ck[16], *keydata, mac_val[16];  unsigned char mac_calc[20], ik[16], *mk, kc[16], *tohash, *framecpy;  if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE))    return XEMALLOC;  if (!xsup_assert((mydata != NULL), "mydata != NULL", FALSE))    return XEMALLOC;  if (!xsup_assert((dataoffs != NULL), "dataoffs != NULL", FALSE))    return XEMALLOC;    if (!xsup_assert((packet_offset != NULL), "packet_offset != NULL", FALSE))    return XEMALLOC;  if (!xsup_assert((username != NULL), "username != NULL", FALSE))    return XEMALLOC;  debug_printf(DEBUG_AUTHTYPES, "Got an AT_MAC\n");  saved_offset = (*packet_offset);#ifndef RADIATOR_TEST    //First thing we need to do, is get our ik & ck.  if (sm_handler_do_3g_auth(&mydata->shdl, mydata->card_mode,			    mydata->random_num, mydata->autn,			    (unsigned char *)&auts, 			    (unsigned char *)&reslen, 			    (unsigned char *)&sres, 			    (unsigned char *)&ck, (unsigned char *)&ik,			    (unsigned char *)&kc) == -2)    {      // We have a sync failure.  So, return it.      memcpy((unsigned char *)&mydata->auts, (unsigned char *)&auts, 16);      return XEAKASYNCFAIL;    }#else  // Copy in the fake vectors that Radiator uses.  memcpy(sres, "2222222222222222", 16);  reslen = 16;  memcpy(ik, "3333333333333333", 16);  memcpy(ck, "4444444444444444", 16);#endif   debug_printf(DEBUG_AUTHTYPES, "SRES = ");  debug_hex_printf(DEBUG_AUTHTYPES, sres, 16);  memcpy(mydata->res, sres, reslen);  mydata->reslen = reslen;  debug_printf(DEBUG_AUTHTYPES, "CK = ");  debug_hex_printf(DEBUG_AUTHTYPES, ck, 16);  debug_printf(DEBUG_AUTHTYPES, "IK = ");  debug_hex_printf(DEBUG_AUTHTYPES, ik, 16);  tohash = (char *)malloc(strlen(username)+33);  // IK & CK are 16 bytes.  if (!tohash)    {      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for hash string!\n");      return XEMALLOC;    }  bzero(tohash, (strlen(username)+33));    strncpy(tohash, username, strlen(username));  memcpy((char *)&tohash[strlen(username)], (char *)&ik, 16);  memcpy((char *)&tohash[strlen(username)+16], (char *)&ck, 16);  printf("To hash : ");  for (x=0;x < (strlen(username)+32); x++)    {      printf("%02X ", tohash[x]);    }  printf("\n");  mk = do_sha1((char *)&tohash[0], (strlen(username)+32));  if (mk == NULL)    {      debug_printf(DEBUG_NORMAL, "An MK couldn't be created!  Authentication cannot be completed! (%s:%d)\n", __FUNCTION__, __LINE__);      return XESIMGENERR;    }  free(tohash);  tohash = NULL;    debug_printf(DEBUG_AUTHTYPES, "MK = ");  debug_hex_printf(DEBUG_AUTHTYPES, mk, 20);    keydata = (char *)malloc(160);  if (keydata == NULL)     {      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for keydata! (%s:%d)\n",		   __FUNCTION__, __LINE__);      return XEMALLOC;    }    bzero(keydata, 160);    // Next, put the mk in to the fips prng.  fips186_2_prng(mk, 20, NULL, 0, (char *)&keydata[0], 160);  free(mk);  mk = NULL;    memcpy(mydata->K_encr, keydata, 16);  debug_printf(DEBUG_AUTHTYPES, "K_encr = ");  debug_hex_printf(DEBUG_AUTHTYPES, mydata->K_encr, 16);    memcpy(mydata->K_aut, (char *)&keydata[16], 16);  debug_printf(DEBUG_AUTHTYPES, "K_aut = ");  debug_hex_printf(DEBUG_AUTHTYPES, mydata->K_aut, 16);    memcpy(mydata->msk, (char *)&keydata[32], 64);  debug_printf(DEBUG_AUTHTYPES, "MSK = ");  debug_hex_printf(DEBUG_AUTHTYPES, mydata->msk, 64);  mydata->keyingMaterial = mydata->msk;    memcpy(mydata->emsk, (char *)&keydata[96], 64);  debug_printf(DEBUG_AUTHTYPES, "EMSK = ");  debug_hex_printf(DEBUG_AUTHTYPES, mydata->emsk, 64);    memcpy(&mac_val[0], &dataoffs[(*packet_offset)+4], 16);    debug_printf(DEBUG_AUTHTYPES, "MAC = ");  debug_hex_printf(DEBUG_AUTHTYPES, (char *)&mac_val[0], 16);    debug_printf(DEBUG_AUTHTYPES, "Packet : \n");  debug_hex_dump(DEBUG_AUTHTYPES, dataoffs, insize);  free(keydata);  keydata = NULL;    // Now, we need a copy of the frame to work against.  framecpy = (char *)malloc(insize+5);  if (framecpy == NULL) return XEMALLOC;    framecpy[0] = 1;   // It was a request.  framecpy[1] = thisint->eapid;  value16 = insize + 5;  value16 = htons(value16);    memcpy((char *)&framecpy[2], &value16, 2);  framecpy[4] = EAP_TYPE_AKA;    memcpy((char *)&framecpy[5], dataoffs, insize);    // Zero out the mac.  bzero((char *)&framecpy[(*packet_offset)+4+5], 16);  debug_printf(DEBUG_AUTHTYPES, "Frame to hash : \n");  debug_hex_dump(DEBUG_AUTHTYPES, framecpy, insize+5);  HMAC(EVP_sha1(), mydata->K_aut, 16, framecpy,        (insize+5), (char *)&mac_calc[0], &i);  debug_printf(DEBUG_AUTHTYPES, "mac_calc = ");  debug_hex_printf(DEBUG_AUTHTYPES, &mac_calc[0], 16);    free(framecpy);  framecpy = NULL;    *packet_offset+=20;    if (memcmp(&mac_calc[0], &mac_val[0], 16) != 0)    {      debug_printf(DEBUG_NORMAL, "ERROR : AT_MAC failed MAC check!\n");      debug_printf(DEBUG_AUTHTYPES, "mac_calc = ");      debug_hex_printf(DEBUG_AUTHTYPES, &mac_calc[0], 16);      debug_printf(DEBUG_AUTHTYPES, "mac_val  = ");      debug_hex_printf(DEBUG_AUTHTYPES, &mac_val[0], 16);      return XESIMBADMAC;    }  return XENONE;}int aka_do_sync_fail(struct aka_eaptypedata *mydata, uint8_t *out, int *outsize){  struct typelength *typelen;  struct typelengthres *typelenres;  int outptr = 0;  if (!xsup_assert((mydata != NULL), "mydata != NULL", FALSE))    return XEMALLOC;  if (!xsup_assert((out != NULL), "out != NULL", FALSE))    return XEMALLOC;  if (!xsup_assert((outsize != NULL), "outsize != NULL", FALSE))    return XEMALLOC;  debug_printf(DEBUG_AUTHTYPES, "Building AKA Sync Failure!\n");  // Since a sync failure is it's own packet, and not an AV pair inside of  // a packet, we ignore anything that may already be in there, and start  // over.  typelen = (struct typelength *)&out[0];  typelen->type = AKA_SYNC_FAILURE;  typelen->length = 0;  outptr = 3;    typelenres = (struct typelengthres *)&out[outptr];  outptr+=4;  typelenres->type = AT_AUTS;  typelenres->length = 5;  typelenres->reserved = 0;  memcpy(&out[outptr], mydata->auts, 16);  outptr+=16;  *outsize = outptr;    return XENONE;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -