?? authcavefunc.c
字號:
/**********************************************************
* @Copyright (C) GDT 2002/07/10
* @Author 姓名:李建彬 付權(fq@mail.ndsc.com.cn)
* cavefunc.c
* @Description:
* 本文件中主要包括鑒權模塊需要用到的CAVE算法,包括CA
* VE算法、A_key的產生及其校驗、SSD的產生和更新、鑒權響應
* 的計算、CMEA加密鍵和VPM的產生。
*
* 主要修改1:
***********************************************************/
//#include "vxWorks.h"
#include <stdio.h>
//#include "authcaveinternal.h"
#include "userareastruct_inhlr.h"
#include "map_optsavearea.h"
#include "auth_macro.h"
#include "hlroamglobal.h"
/*-------------------------------------------------------------
CAVE算法相關用戶數據初始化
初始化內容:CURRENT_ESN[4]、A_key[8]、CURRENT_AAV、SSD_A、SSD_B、
--------------------------------------------------------------*/
void cave_init(U16 optID,U8 LocalType)
{
U8 i;
U32 *pCURRENT_ESN;
SUBSCRIBERINHLR *pUserDataHlr;
SUBSCRIBERINVLR *pUserDataVlr;
pUserDataVlr=NULL;
pUserDataHlr=NULL;
#ifdef _AUTH_DEBUG
printf("執行cave_init()函數 !\n");
#endif
if(LocalType==LOCALTYPEAC)
{
pUserDataHlr=(SUBSCRIBERINHLR *)((OptManageTabPtr+optID)->ptr_userarea);
if (pUserDataHlr==NULL)
{
#ifdef _AUTH_DEBUG
printf("用戶數據區指針為空,CAVE數據初始化失敗!\n");
#endif
return ;
}
/*Init CURRENT_ESN[4]*/
pCURRENT_ESN=(U32 *)&CURRENT_ESN[0];
*pCURRENT_ESN=pUserDataHlr->AssocACPoint->UIMNo;
/*Init A_key[8]*/
for(i=0;i<8;i++)
{
A_key[i]=pUserDataHlr->AssocACPoint->A_key[i];
}
/*Init CURRENT_AAV*/
CURRENT_AAV=pUserDataHlr->AssocACPoint->AAV;
#ifdef _AUTH_DEBUG_CAVE
printf("AAV=%2x !\n",CURRENT_AAV);
#endif
/*Init SSD_A、SSD_B*/
for(i=0;i<8;i++)
{
SSD_A[i]=pUserDataHlr->AssocACPoint->SSD_A[i];
SSD_B[i]=pUserDataHlr->AssocACPoint->SSD_B[i];
}
#ifdef _AUTH_DEBUG
printf("AC CAVE 初始化完成!\n");
#endif
}
else if(LocalType==LOCALTYPEVLR)
{
pUserDataVlr=(SUBSCRIBERINVLR *)((OptManageTabPtr+optID)->ptr_userarea);
if (pUserDataVlr==NULL)
{
#ifdef _AUTH_DEBUG
printf("用戶數據區指針為空,CAVE數據初始化失敗!\n");
#endif
return ;
}
/*Init CURRENT_ESN[4]*/
pCURRENT_ESN=(U32 *)&CURRENT_ESN[0];
*pCURRENT_ESN=pUserDataVlr->ESN;
/*Init CURRENT_AAV*/
CURRENT_AAV=pUserDataVlr->AuthParaPoint->AAV;
#ifdef _AUTH_DEBUG_CAVE
printf("AAV=%2x !\n",CURRENT_AAV);
#endif
/*Init SSD_A、SSD_B*/
for(i=0;i<8;i++)
{
SSD_A[i]=pUserDataVlr->AuthParaPoint->SSD_A[i];
SSD_B[i]=pUserDataVlr->AuthParaPoint->SSD_B[i];
}
#ifdef _AUTH_DEBUG
printf("VLR CAVE 初始化完成!\n");
#endif
}
else
{
#ifdef _AUTH_DEBUG
printf("傳遞的參數LocalType錯,CAVE數據初始化失敗!\n");
#endif
}
#ifdef _AUTH_DEBUG_CAVE1
CURRENT_ESN[0]=0XD7;
CURRENT_ESN[1]=0X5A;
CURRENT_ESN[2]=0X96;
CURRENT_ESN[3]=0XEC;
CURRENT_AAV=0XC7;
SSD_A[0]=0XCC;
SSD_A[1]=0X38;
SSD_A[2]=0X12;
SSD_A[3]=0X94;
SSD_A[4]=0X9F;
SSD_A[5]=0X4D;
SSD_A[6]=0XCD;
SSD_A[7]=0X0D;
SSD_B[0]=0X31;
SSD_B[1]=0X05;
SSD_B[2]=0X02;
SSD_B[3]=0X34;
SSD_B[4]=0X58;
SSD_B[5]=0X0E;
SSD_B[6]=0X63;
SSD_B[7]=0XB4;
#endif
return;
}
/*---------------------------------------------------
鑒權算法
----------------------------------------------------*/
static U8 bit_val(const U8 octet, const int bit)
{
return((octet << (7 - bit)) & 0x80);
}
static void LFSR_cycle(void)
{
U8 temp;
int i;
temp = bit_val(LFSR_B,6);
temp ^= bit_val(LFSR_D,2);
temp ^= bit_val(LFSR_D,1);
temp ^= bit_val(LFSR_D,0);
/* Shift right LFSR, Discard LFSR_D[0] bit */
for (i = 3; i > 0; i--)
{
LFSR[i] >>= 1;
if (LFSR[i-1] & 0x01)
LFSR[i] |= 0x80;
}
LFSR_A >>= 1;
LFSR_A |= temp;
return;
}
static void Rotate_right_Registers(void)
{
int i;
unsigned int temp_reg;
temp_reg = Register[15]; /* save lsb */
for (i = 15; i > 0; i--)
{
Register[i] >>= 1;
if (Register[i-1] & 0x01)
Register[i] |= 0x80;
}
Register[0] >>= 1;
if (temp_reg & 0x01)
Register[0] |= 0x80;
return;
}
void CAVE(const int number_of_rounds,int *offset_1,int *offset_2)
{
U8 temp_reg0;
U8 lowNibble;
U8 hiNibble;
U8 temp;
int round_index;
int R_index;
int fail_count;
U8 T[16];
#ifdef _AUTH_DEBUG
printf("執行CAVE算法!\n");
#endif
for (round_index = number_of_rounds - 1;round_index >= 0;round_index--)
{
/* save R0 for reuse later */
temp_reg0 = Register[0];
for (R_index = 0; R_index < 16; R_index++)
{
fail_count = 0;
while(1)
{
*offset_1 += (LFSR_A ^ Register[R_index]);
/* will overflow; mask to prevent */
*offset_1 &= 0xff;
lowNibble = map_SmpGlbVarPtr->CaveTable[*offset_1] & LOMASK;
if (lowNibble == (Register[R_index] & LOMASK))
{
LFSR_cycle();
fail_count++;
if (fail_count == 32)
{
LFSR_D++; /* no carry to LFSR_C */
break;
}
}
else
break;
}
while(1)
{
*offset_2 += (LFSR_B ^ Register[R_index]);
/* will overflow; mask to prevent */
*offset_2 &= 0xff;
hiNibble = map_SmpGlbVarPtr->CaveTable[*offset_2] & HIMASK;
if (hiNibble == (Register[R_index] & HIMASK))
{
LFSR_cycle();
fail_count++;
if (fail_count == 32)
{
LFSR_D++; /* no carry to LFSR_C */
break;
}
}
else
break;
}
temp = lowNibble | hiNibble;
if (R_index == 15)
Register[R_index] = temp_reg0 ^ temp;
else
Register[R_index] = Register[R_index+1] ^ temp;
LFSR_cycle();
}
Rotate_right_Registers();
/* shuffle the mixing Registers */
for (R_index = 0; R_index < 16; R_index++)
{
temp = map_SmpGlbVarPtr->CaveTable[16*round_index + R_index] & LOMASK;
T[temp] = Register[R_index];
}
for (R_index = 0; R_index < 16; R_index++)
{
Register[R_index] = T[R_index];
}
}
return;
}
/*----------------------------------------------
A_Key校驗和的產生
----------------------------------------------*/
void mul10(unsigned char i64[8], unsigned int carry)
{
int i;
unsigned int temp;
for (i = 7; i >= 0; i--)
{
temp = ((unsigned int)(i64[i]) * 10) + carry;
i64[i] = temp & 0xFF;
carry = temp >> 8;
}
return;
}
unsigned long Calc_Checksum(const unsigned char A_key[8])
{
int i,offset_1,offset_2;
unsigned long A_key_checksum;
/* see if 32 MSB are zero */
if ((A_key[0] | A_key[1] | A_key[2] | A_key[3]) != 0)
{
/* put 32 MSB into LFSR */
for (i = 0; i < 4; i++)
LFSR[i] = A_key[i];
}
else
{
/* put CURRENT_ESN into LFSR */
for (i = 0; i < 4; i++)
LFSR[i] = CURRENT_ESN[i];
}
/* put A_key into r0-r7 */
for (i = 0; i < 8; i++)
Register[i] = A_key[i];
Register[8] = CURRENT_AAV;
/* put ls 24 bits of A_key into r9-r11 */
for (i = 9; i < 12; i++)
Register[i] = A_key[5+i-9];
/* put CURRENT_ESN into r12-r15 */
for (i = 12; i < 16; i++)
Register[i] = CURRENT_ESN[i-12];
offset_1 = offset_2 = 128;
CAVE(8, &offset_1, &offset_2);
A_key_checksum = (((unsigned long)(Register[0] ^ Register[13]) << 16) +
((unsigned long)(Register[1] ^ Register[14]) << 8) +
((unsigned long)(Register[2] ^ Register[15]))) & 0x3ffff;
return (A_key_checksum);
}
/* A_KEY_DIGITS contains the ASCII digits in the order to be entered */
void A_Key_Checksum(const char A_KEY_DIGITS[20],char A_KEY_CHECKSUM[6])
{
int i;
unsigned char temp_A_key[8];
unsigned long A_key_checksum;
/* convert digits to 64-bit representation in temp_A_key */
for (i = 0; i < 8; i++)
temp_A_key[i] = 0;
for (i = 0; i < 20; i++)
{
mul10(temp_A_key,(unsigned int)(A_KEY_DIGITS[i] - '0'));
}
A_key_checksum = Calc_Checksum(temp_A_key);
/* convert checksum to decimal digits */
for (i = 0; i < 6; i++)
{
A_KEY_CHECKSUM[5-i] = '0' + (char)(A_key_checksum % 10);
A_key_checksum /= 10;
}
return;
}
/*--------------------------------------------------------------
A_Key的校驗
--------------------------------------------------------------*/
int A_Key_Verify(const char A_KEY_DIGITS[26])
{
int i;
unsigned char temp_A_key[8];
unsigned long entered_checksum;
/* convert first 20 digits to 64-bit representation in temp_A_key */
for (i = 0; i < 8; i++)
temp_A_key[i] = 0;
for (i = 0; i < 20; i++)
{
mul10(temp_A_key,(unsigned int)(A_KEY_DIGITS[i] - '0'));
}
/* convert last 6 digits to entered checksum */
entered_checksum = 0;
for (i = 20; i < 26; i++)
{
entered_checksum = (entered_checksum * 10) + (A_KEY_DIGITS[i] - '0');
}
if(Calc_Checksum(temp_A_key) == entered_checksum)
{
for (i = 0; i < 8; i++)
{
A_key[i] = temp_A_key[i];
SSD_A[i] = SSD_B[i] = 0;
}
return TRUE;
}
else
{
return FALSE;
}
}
/*------------------------------------------------
SSD的產生
------------------------------------------------*/
#ifdef _AUTH_DEBUG_CAVE1
#define SSD_GENERATION_ENTRY_PARA unsigned char RANDSSD[7]
#else
#define SSD_GENERATION_ENTRY_PARA const unsigned char RANDSSD[7]
#endif
void SSD_Generation(const unsigned char RANDSSD[7])
{
int i,offset_1,offset_2;
#ifdef _AUTH_DEBUG
printf("執行SSD_Generation()函數 !\n");
#endif
#ifdef _AUTH_DEBUG_CAVE1
A_key[0]=0xc4;
A_key[1]=0x42;
A_key[2]=0xF5;
A_key[3]=0x6B;
A_key[4]=0xE9;
A_key[5]=0xE1;
A_key[6]=0x71;
A_key[7]=0x58;
RANDSSD[0]=0X4D;
RANDSSD[1]=0X18;
RANDSSD[2]=0XEE;
RANDSSD[3]=0XAA;
RANDSSD[4]=0X05;
RANDSSD[5]=0X89;
RANDSSD[6]=0X5C;
#endif
#ifdef _AUTH_DEBUG
printf("\n");
printf("RANDSSD=");
for(i=0;i<7;i++)
printf("%2x",RANDSSD[i]);
printf("\n");
printf("A_key=");
for(i=0;i<8;i++)
printf("%2x",A_key[i]);
printf("\n");
#endif
for (i = 0; i < 4; i++)
{
LFSR[i] = RANDSSD[i+3] ^ A_key[i] ^ A_key[i+4];
}
if ((LFSR[0] | LFSR[1] | LFSR[2] | LFSR[3]) == 0)
{
for (i = 0; i < 4; i++)
LFSR[i] = RANDSSD[i+3];
}
for (i = 0; i < 8; i++)
Register[i] = A_key[i];
Register[8] = CURRENT_AAV;
for (i = 9; i < 12; i++)
Register[i] = RANDSSD[i-9];
for (i = 12; i < 16; i++)
Register[i] =CURRENT_ESN[i-12];
offset_1 = offset_2 = 128;
CAVE(8, &offset_1, &offset_2);
for (i = 0; i < 8; i++)
{
SSD_A_NEW[i] = Register[i];
SSD_B_NEW[i] = Register[i+8];
}
#ifdef _AUTH_DEBUG
printf("SSD_A_NEW[i]=0x:");
for(i=0;i<8;i++)
printf("%2x ",SSD_A_NEW[i]);
printf("\n");
printf("SSD_B_NEW[i]=0x:");
for(i=0;i<8;i++)
printf("%2x ",SSD_B_NEW[i]);
printf("\n");
#endif
return;
}
/*------------------------------------------------
SSD的更新
------------------------------------------------*/
/*void SSD_Update(void)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -