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

📄 aka.c

📁 linux 下通过802.1认证的安装包
💻 C
字号:
/**
 * EAPOL Function implementations for supplicant
 * 
 * \file aka.c
 *
 * Licensed under a dual GPL/BSD license.  (See LICENSE file for more info.)
 *
 * \author chris@open1x.org
 *
 * \todo Add IPC error message signaling.
 *
 * $Id: aka.c,v 1.13.2.9 2007/04/20 18:35:53 chessing Exp $
 * $Date: 2007/04/20 18:35:53 $
 **/

/*******************************************************************
 *
 * 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 "xsup_common.h"
#include "eap_sm.h"
#include "frame_structs.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"
#include "eap_types/eap_type_common.h"

#ifdef USE_EFENCE
#include <efence.h>
#endif

char *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(eap_type_data *eapdata, 
		  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((eapdata != NULL), "eapdata != 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;
    }
  
  if (Strncpy(tohash, (strlen(username)+33), username, strlen(username) + 1) != 0)
  {
	  debug_printf(DEBUG_NORMAL, "Attempt to overflow buffer in %s() at %d!\n",
		  __FUNCTION__, __LINE__);
	  return XEMALLOC;
  }

  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);
  
  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;
    }
  
  // Next, put the mk in to the fips prng.
  fips186_2_prng(mk, 20, NULL, 0, (char *)&keydata[0], 160);

  FREE(mk);
  
  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);
  
  // 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] = eap_type_common_get_eap_reqid(eapdata->eapReqData);
  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.
  memset((char *)&framecpy[(*packet_offset)+4+5], 0x00, 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;
}

uint8_t *aka_do_sync_fail(struct aka_eaptypedata *mydata, uint8_t reqId)
{
  struct typelength *typelen;
  struct typelengthres *typelenres;
  int outptr = 0;
  uint8_t *eapres;
  uint16_t buffersize = 0;
  struct eap_header *eaphdr;

  if (!xsup_assert((mydata != NULL), "mydata != NULL", FALSE))
    return XEMALLOC;

  debug_printf(DEBUG_AUTHTYPES, "Building AKA Sync Failure!\n");

  buffersize = sizeof(struct eap_header) + sizeof(struct typelength) +
    sizeof(struct typelengthres) + 16;

  eapres = Malloc(buffersize);
  if (eapres == NULL) 
    {
      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for AKA sync "
		   "failure result!\n");
      return NULL;
    }

  eaphdr = (struct eap_header *)eapres;

  eaphdr->eap_code = EAP_RESPONSE_PKT;
  eaphdr->eap_identifier = reqId;
  eaphdr->eap_type = EAP_TYPE_AKA;
  eaphdr->eap_length = htons(buffersize);

  outptr = sizeof(struct eap_header);
  typelen = (struct typelength *)&eapres[outptr];

  typelen->type = AKA_SYNC_FAILURE;
  typelen->length = 0;
  outptr += 3;
  
  typelenres = (struct typelengthres *)&eapres[outptr];
  outptr+=4;

  typelenres->type = AT_AUTS;
  typelenres->length = 5;
  typelenres->reserved = 0;

  memcpy(&eapres[outptr], mydata->auts, 16);
  outptr+=16;

  return eapres;
}


#endif

⌨️ 快捷键说明

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