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

📄 authcavefunc.c

📁 在cdma2000移动通信系统中空中接口部分使用CAVE进行身份认证。
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********************************************************
 *  @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 + -