📄 sim.c
字号:
/**
* EAPOL Function implementations for supplicant
*
* Licensed under a dual GPL/BSD license. (See LICENSE file for more info.)
*
* \file sim.c
*
* \author chris@open1x.org
*
* \todo Add IPC error events
*
* $Id: sim.c,v 1.11.2.8 2007/04/20 18:35:54 chessing Exp $
* $Date: 2007/04/20 18:35:54 $
**/
/*******************************************************************
*
* The development of the EAP/SIM support was funded by Internet
* Foundation Austria (http://www.nic.at/ipa)
*
*******************************************************************/
#ifdef EAP_SIM_ENABLE
#include <strings.h>
#include <string.h>
#include <inttypes.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <openssl/hmac.h>
#include "winscard.h"
#include "profile.h"
#include "xsupconfig.h"
#include "xsup_common.h"
#include "eap_sm.h"
#include "sim.h"
#include "eapsim.h"
#include "simd5.h"
#include "simd11.h"
#include "sm_handler.h"
#include "xsup_debug.h"
#include "xsup_err.h"
#include "fips.h"
#include "eap_types/eap_type_common.h"
#ifdef USE_EFENCE
#include <efence.h>
#endif
int sim_build_start(struct eaptypedata *mydata, uint8_t *out, int *outptr)
{
struct typelength *typelen;
struct typelengthres *typelenres;
if (!xsup_assert((mydata != NULL), "mydata != NULL", FALSE))
return XEMALLOC;
if (!xsup_assert((out != NULL), "out != NULL", FALSE))
return XEMALLOC;
if (!xsup_assert((outptr != NULL), "outptr != NULL", FALSE))
return XEMALLOC;
debug_printf(DEBUG_AUTHTYPES, "Got SIM_START!\n");
memset(out, 0x00, 100);
typelen = (struct typelength *)&out[0];
typelen->type = SIM_START;
typelen->length = 0;
typelenres = (struct typelengthres *)&out[3];
typelenres->type = AT_NONCE_MT;
typelenres->length = 5;
typelenres->reserved = 0;
// Generate a few random bytes for our NONCE MT.
mydata->nonce_mt = (char *)Malloc(16);
if (mydata->nonce_mt == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for NONCE MT! "
"(%s:%d)\n", __FUNCTION__, __LINE__);
return XEMALLOC;
}
RAND_bytes(mydata->nonce_mt,16);
debug_printf(DEBUG_AUTHTYPES, "NONCE MT = ");
debug_hex_printf(DEBUG_AUTHTYPES, mydata->nonce_mt, 16);
*outptr = 7;
memcpy(&out[*outptr], mydata->nonce_mt, 16);
*outptr += 16;
return XENONE;
}
int sim_build_fullauth(char *username, uint8_t *dataoffs, int *packet_offset,
uint8_t *out, int *outptr)
{
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;
if (!xsup_assert((out != NULL), "out != NULL", FALSE))
return XEMALLOC;
if (!xsup_assert((outptr != NULL), "outptr != NULL", FALSE))
return XEMALLOC;
debug_printf(DEBUG_AUTHTYPES, "Got AT_FULLAUTH_ID_REQ or AT_PERMANENT_ID_REQ!\n");
typelenres = (struct typelengthres *)&dataoffs[*packet_offset];
if ((typelenres->length != 5) && (typelenres->length != 1))
{
debug_printf(DEBUG_NORMAL, "Invalid AT_FULLAUTH_ID_REQ length!\n");
return XESIMBADLEN;
}
*packet_offset+=4; // Skip the reserved and length bytes.
// Build an AT_IDENTITY response.
typelenres = (struct typelengthres *)&out[*outptr];
typelenres->type = AT_IDENTITY;
typelenres->length = (strlen(username)/4)+1;
if ((strlen(username) % 4) != 0)
{
// We have a number that isn't evenly divisible by 4. We need to
// add one more to the length to account for it.
typelenres->length++;
}
typelenres->reserved = htons(strlen(username));
*outptr+=sizeof(struct typelengthres);
memcpy(&out[*outptr], username, strlen(username));
*outptr += strlen(username) + (4-(strlen(username) % 4));
return XENONE;
}
int sim_at_version_list(char *username, struct eaptypedata *mydata,
uint8_t *dataoffs, int *packet_offset, uint8_t *out,
int *outptr)
{
int numVers, maxver, i, value16;
struct typelengthres *typelenres;
if (!xsup_assert((username != NULL), "username != 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((out != NULL), "out != NULL", FALSE))
return XEMALLOC;
if (!xsup_assert((outptr != NULL), "outptr != NULL", FALSE))
return XEMALLOC;
debug_printf(DEBUG_AUTHTYPES, "Got an AT_VERSION_LIST request!\n");
typelenres = (struct typelengthres *)&dataoffs[*packet_offset];
debug_printf(DEBUG_AUTHTYPES, "Version List Length (# versions) : %d\n", typelenres->length);
numVers = typelenres->length;
mydata->verlistlen = ntohs(typelenres->reserved);
debug_printf(DEBUG_AUTHTYPES, "Version List Length (bytes) : %d\n",
mydata->verlistlen);
*packet_offset+=sizeof(struct typelengthres);
maxver = 0; // Set the starting value to be 0.
mydata->verlist = (char *)Malloc(mydata->verlistlen);
if (mydata->verlist == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for version list! (%s:%d)\n", __FUNCTION__, __LINE__);
return XEMALLOC;
}
memcpy(mydata->verlist, &dataoffs[*packet_offset],
mydata->verlistlen);
for (i=0;i<numVers;i++)
{
memcpy(&value16, &dataoffs[*packet_offset], 2);
value16 = ntohs(value16);
debug_printf(DEBUG_AUTHTYPES, "AT_VERSION_LIST Value : %d\n",
value16);
if (value16 > maxver) maxver = value16;
*packet_offset += 2;
}
if (maxver > EAPSIM_MAX_SUPPORTED_VER)
maxver = EAPSIM_MAX_SUPPORTED_VER;
debug_printf(DEBUG_AUTHTYPES, "Setting version to %d\n",maxver);
typelenres = (struct typelengthres *)&out[*outptr];
typelenres->type = AT_SELECTED_VERSION;
typelenres->length = 1;
typelenres->reserved = htons(maxver);
*outptr += sizeof(struct typelengthres);
mydata->workingversion = maxver;
return XENONE;
}
int sim_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",
dataoffs[*packet_offset]);
*packet_offset+= (typelenres->length * 4);
return XENONE;
}
int sim_do_at_mac(eap_type_data *thisint, struct eaptypedata *mydata,
uint8_t *dataoffs, int insize, int *packet_offset,
uint8_t *out, int *outptr, char *K_int)
{
int saved_offset;
char mac_val[16], mac_calc[16];
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((out != NULL), "out != NULL", FALSE))
return XEMALLOC;
if (!xsup_assert((outptr != NULL), "outptr != NULL", FALSE))
return XEMALLOC;
if (!xsup_assert((K_int != NULL), "K_int != NULL", FALSE))
return XEMALLOC;
debug_printf(DEBUG_AUTHTYPES, "Got an AT_MAC\n");
memset(&mac_calc[0], 0x00, 16);
memset(&mac_val[0], 0x00, 16);
saved_offset = (*packet_offset);
memcpy(&mac_val[0], &dataoffs[*packet_offset+4], 16);
*packet_offset+=20;
if (mydata->workingversion == 0)
{
if (do_v0_at_mac(thisint, K_int, dataoffs, insize,
saved_offset, &mac_calc[0]) == -1)
{
debug_printf(DEBUG_NORMAL, "Error calculating AT_MAC for Version 0!\n");
return XESIMBADMAC;
}
} else {
debug_printf(DEBUG_AUTHTYPES, "K_int = ");
debug_hex_printf(DEBUG_AUTHTYPES, K_int, 16);
if (do_v1_at_mac(thisint, K_int, dataoffs, insize,
saved_offset, mydata->nonce_mt,
mydata->verlist, mydata->verlistlen,
mydata->workingversion, &mac_calc[0]) == -1)
{
debug_printf(DEBUG_NORMAL, "Error calculating AT_MAC for Version 1!\n");
return XESIMBADMAC;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -