www.pudn.com > agsm2-1.2_src.zip > aka.cpp


/* aka.c:  sha based function for aka */ 
#include "stdafx.h" 
#include  
#include "aka.h" 
 
static uchar counter[8]={0}; 
 
static uchar G[20] = {  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
						0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
						0x00, 0x00, 0x00, 0x2d}; 
static uchar A[20] = {  0x9d, 0xe9, 0xc9, 0xc8, 0xef, 0xd5, 0x78, 0x11, 
						0x48, 0x23, 0x14, 0x01, 0x90, 0x1f, 0x2d, 0x49, 
						0x3f, 0x4c, 0x63, 0x65}; 
static uchar B[20] = {  0x75, 0xef, 0xd1, 0x5c, 0x4b, 0x8f, 0x8f, 0x51, 
						0x4e, 0xf3, 0xbc, 0xc3, 0x79, 0x4a, 0x76, 0x5e, 
						0x7e, 0xec, 0x45, 0xe0}; 
static 
void modred(uchar *z,int shift,uchar *base); 
 
/* This function performs the operation of (A*X+B) mod 2^160+2^5+2^3+2^2+1 
 * 
 * 
*/ 
 
void whiten(uchar xx[]) 
{ 
	uchar z[40]; 
	int i, j; 
 
	/* calculate A * X in polynomial form */ 
	for (i=0;i<40;i++) 
		z[i]=0; 
 
	for (i=0;i<20;i++) 
	{ 
		for (j=0;j<8;j++) 
		{ 
			if ((xx[i]<>= 8-bitshift; 
			q[i] |= yn1 << bitshift; 
		} 
		/* shift one more byte, since bits have effectively been 
		   shifted into the next byte upward */ 
		byteshift++; 
	} 
 
	/* z ^= q and send back result in z */ 
	for (i = 0; i < 20; i++) 
		z[i+20-byteshift] ^= q[i]; 
	if (bitshift != 0) 
		z[40-byteshift] ^= q[20]; 
} 
 
/* This function performs generation of 64-bit pseudo random number RAND. 
 * 
 * 
*/ 
 
void 
f0(uchar seed[],uchar fi,uchar Fmk[],uchar buff[]) 
{ 
	SHA_INFO sha_info; 
	uchar buf[64]; 
	uchar t; 
	int i; 
 
	shaInitial(&sha_info); 
	for (i = 0; i < L_KEY; i++) 
		sha_info.digest[i] ^= seed[i]; 
 
	for (i = 0; i < 64; i++) 
		buf[i] = 0x5c; 
 
	for (i = 0; i < 8; i++) 
	{ 
		buf[i] ^= counter[i]; 
		buf[i+16] ^= counter[i]; 
		buf[i+32] ^= counter[i]; 
		buf[i+48] ^= counter[i]; 
	} 
 
	buf[11] ^= fi; 
 
	for (i = 0; i < 4; i++) 
		buf[i+12] ^= Fmk[i]; 
	shaUpdate(&sha_info,buf,0,512); 
	/* perform (AX+B)mod G */ 
	whiten(sha_info.digest); 
 
	/* get 8 bytes or 64 bits */ 
	for (i=0;i<8;i++) 
		buff[i] = sha_info.digest[i]; 
 
	/* increment counter */ 
	for (i = 7; i >= 0; i--) 
	{ 
		t = counter[i]; 
		counter[i]++; 
		if (counter[i] > t) 
			break; 
	} 
} 
 
/* This function performs generation of authentication signature MACA. 
 * 
 * 
*/ 
 
void 
f1(uchar K[],uchar fi,uchar *RAND,uchar Fmk[],uchar SQN[],uchar AMF[],uchar MACA[]) 
{ 
	SHA_INFO sha_info; 
	uchar buf[64]; 
	int i; 
 
	/* NOTE: the following initialization of the sha_info struct can be performed 
	   once when K is provisioned, and the results copied into sha_info at the 
	   start of this function. */ 
	shaInitial(&sha_info); 
	for (i = 0; i < L_KEY; i++) 
		sha_info.digest[i] ^= K[i]; 
 
	for (i = 0; i < 64; i++) 
		buf[i] = 0x5c; 
 
	for (i = 0; i < 4; i++) 
		buf[i+12] ^= Fmk[i]; 
	for (i = 0; i < 16; i++) 
		buf[i+16] ^= RAND[i]; 
	for (i = 0; i < 6; i++) 
		buf[i+34] ^= SQN[i]; 
	for (i = 0; i < 2; i++) 
		buf[i+42] ^= AMF[i]; 
 
	buf[11] ^= fi; 
 
	shaUpdate(&sha_info,buf,0,512); 
 
	/* perform (AX+B)mod G */ 
	whiten(sha_info.digest); 
 
	for (i=0;i 16) 
		l_res = 16; 
 
	for (j = 0; j < 2; j++) 
	{ 
		/* NOTE: the following initialization of the sha_info struct can be performed 
		   once when K is provisioned, and the results copied into sha_info at the 
		   start of this loop. */ 
		shaInitial(&sha_info); 
		for (i = 0; i < L_KEY; i++) 
			sha_info.digest[i] ^= K[i]; 
 
		for (i = 0; i < 64; i++) 
			buf[i] = 0x5c; 
 
		for (i = 0; i < 4; i++) 
			buf[i+12] ^= Fmk[i]; 
		for (i = 0; i < 16; i++) 
			buf[i+24] ^= RAND[i]; 
 
		buf[3] ^= j; 
		buf[11] ^= fi; 
		buf[19] ^= j; 
		buf[35] ^= j; 
		buf[51] ^= j; 
 
		shaUpdate(&sha_info,buf,0,512); 
 
		whiten(sha_info.digest); 
		for (i=0;i<8;i++) 
		{ 
			RES[8*j+i] = sha_info.digest[i]; 
			if (--l_res == 0) 
				return; 
		} 
	} 
} 
 
/* This function performs generation of cipher key CK. 
 * 
 * 
*/ 
 
void 
f3(uchar K[],uchar fi,uchar *RAND,uchar Fmk[],uchar *CK) 
{ 
	SHA_INFO sha_info; 
	uchar j,buf[64]; 
	int i; 
 
	for (j = 0; j < 2; j++) 
	{ 
		/* NOTE: the following initialization of the sha_info struct can be performed 
		   once when K is provisioned, and the results copied into sha_info at the 
		   start of this loop. */ 
		shaInitial(&sha_info); 
		for (i = 0; i < L_KEY; i++) 
			sha_info.digest[i] ^= K[i]; 
 
		for (i = 0; i < 64; i++) 
			buf[i] = 0x5c; 
 
		for (i = 0; i < 4; i++) 
			buf[i+12] ^= Fmk[i]; 
		for (i = 0; i < 16; i++) 
			buf[i+24] ^= RAND[i]; 
 
		buf[3] ^= j; 
		buf[11] ^= fi; 
		buf[19] ^= j; 
		buf[35] ^= j; 
		buf[51] ^= j; 
 
		shaUpdate(&sha_info,buf,0,512); 
 
		whiten(sha_info.digest); 
		for (i=0;i<8;i++) 
			CK[8*j+i] = sha_info.digest[i]; 
	} 
} 
 
/* This function performs generation of integrity key IK. 
 * 
 * 
*/ 
 
void 
f4(uchar K[],uchar fi,uchar *RAND,uchar Fmk[],uchar *IK) 
{ 
	SHA_INFO sha_info; 
	uchar j,buf[64]; 
	int i; 
 
	for (j = 0; j < 2; j++) 
	{ 
		/* NOTE: the following initialization of the sha_info struct can be performed 
		   once when K is provisioned, and the results copied into sha_info at the 
		   start of this loop. */ 
		shaInitial(&sha_info); 
		for (i = 0; i < L_KEY; i++) 
			sha_info.digest[i] ^= K[i]; 
 
		for (i = 0; i < 64; i++) 
			buf[i] = 0x5c; 
 
		for (i = 0; i < 4; i++) 
			buf[i+12] ^= Fmk[i]; 
		for (i = 0; i < 16; i++) 
			buf[i+24] ^= RAND[i]; 
 
		buf[3] ^= j; 
		buf[11] ^= fi; 
		buf[19] ^= j; 
		buf[35] ^= j; 
		buf[51] ^= j; 
 
		shaUpdate(&sha_info,buf,0,512); 
 
		whiten(sha_info.digest); 
		for (i=0;i<8;i++) 
			IK[8*j+i] = sha_info.digest[i]; 
	} 
} 
 
/* This function performs generation of anonymity key AK. 
 * 
 * 
*/ 
 
void 
f5(uchar K[],uchar fi,uchar *RAND,uchar Fmk[],uchar AK[]) 
{ 
	SHA_INFO sha_info; 
	uchar buf[64]; 
	int i; 
 
	/* NOTE: the following initialization of the sha_info struct can be performed 
	   once when K is provisioned, and the results copied into sha_info at the 
	   start of this function. */ 
	shaInitial(&sha_info); 
	for (i = 0; i < L_KEY; i++) 
		sha_info.digest[i] ^= K[i]; 
 
	for (i = 0; i < 64; i++) 
		buf[i] = 0x5c; 
 
	for (i = 0; i < 4; i++) 
		buf[i+12] ^= Fmk[i]; 
	for (i = 0; i < 16; i++) 
		buf[i+16] ^= RAND[i]; 
 
	buf[11] ^= fi; 
 
	shaUpdate(&sha_info,buf,0,512); 
 
	/* perform (AX+B)mod G */ 
	whiten(sha_info.digest); 
 
	for (i=0;i