www.pudn.com > DS28E01-100-C-code-2008-4-29.zip > DS2801.C, change:2009-05-16,size:32548b


#include	"PORT.H" 
#include	"OWERROR.H" 
#include	"OWCOMD.H" 
#include	"OWBASIC.H" 
#include	"FC.H" 
#include	"SHA.H" 
#include	<string.h>						//For array setting purpose. 
#include	<stdlib.h>						//For random number purpose. 
 
/*Version 2.*/ 
 
/******************************************************************** 
*	The new version modified the Secret loaing process.          	*  
*	The secret loading is partitioned into 2 parts.					* 
*	The 1st part will load secret into the 64 bits secret region.	* 
*	The 2nd part will load extention secret into page3.          	* 
*	This is to avoid the mis-using of the secret loading process.	*           
*********************************************************************/ 
 
 
/******************************************************************** 
*	The authentication function is also been partitioned into 2		* 
 	parts.                                                       	* 
*	This is to avoid the mis-using of the original authenticatio 	* 
 	function.                                                    	* 
*********************************************************************/ 
 
//extern uint8 xdata SHAVM_Message[]; 
//extern uint8 data SHAVM_MAC[]; 
 
 
/*	Tis buffer is used to hold the data writen to DS28E01-100	*/ 
/*	only 8 bytes a time.	*/ 
uint8 xdata tempbuffer[8] = {0x00,0xEE,0xDD,0xEE,0xEE,0xDD,0x00,0x99}; 
 
static uint8 xdata dscrc_table[] = { 
        0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, 
      157,195, 33,127,252,162, 64, 30, 95,  1,227,189, 62, 96,130,220, 
       35,125,159,193, 66, 28,254,160,225,191, 93,  3,128,222, 60, 98, 
      190,224,  2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, 
       70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89,  7, 
      219,133,103, 57,186,228,  6, 88, 25, 71,165,251,120, 38,196,154, 
      101, 59,217,135,  4, 90,184,230,167,249, 27, 69,198,152,122, 36, 
      248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91,  5,231,185, 
      140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, 
       17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, 
      175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, 
       50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, 
      202,148,118, 40,171,245, 23, 73,  8, 86,180,234,105, 55,213,139, 
       87,  9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, 
      233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, 
      116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53}; 
 
static uint8 data CRC8; 
uint8 xdata ROMID[8]; 
 
static uint16 xdata oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; 
static uint16 data CRC16; 
 
/*	All bytes send/read by host in writesc/readsc are stored in this buffer.*/ 
/*	This is for the convenience calculating of CRC16.						*/ 
static uint8 xdata databuffer[14]; 
 
/*	This buffer is used to store data read back from an EEPROM page.	*/		 
static uint8 xdata pagebuffer[32]; 
		 
/*	Use this buffer to store subpage data.	*/ 
static uint8 xdata subpbuffer[8]; 
 
/*	The public(basic) serect is stored in this buffer,can be used in	*/  
/*	authentiction or to	generate unique secret.	*/ 
uint8 code basicsecret[8] = {0x00, 0x09, 0x10, 0x80, 0x77, 0x62, 0x88, 0xAB}; 
 
  
/*	This secret is the particial secret used in compute next secret.		*/									 
uint8 code particial[8] = {0x00, 0x19, 0x17, 0x80, 0x77, 0x62, 0x88, 0xAB}; 
 
/*	Copy the basic secret into device secret or put unique secret in device	*/ 
/*	secret.																	*/				 
static uint8 data devicesecret[8]; 
 
/*	Bascic extention secret stores in this buffer.These secrets are used to */ 
/*	extend the 64 bits secret.*/		 
uint8 code basicp3secret[32] = {0x12,0x22,0x4d,0x2a,0x43,0x29,0x4d,0x2a, 
								0x22,0x25,0x62,0x21,0x43,0x39,0x4e,0x2b, 
								0x33,0x26,0x4d,0x2a,0x43,0x09,0x4d,0x5e, 
								0x44,0x27,0x5d,0x20,0x03,0x29,0x0d,0x43}; 
								/*{0x00, 0x09, 0x10, 0x80, 0x77, 0x62, 0x88, 0xAB, 
							  	0x00, 0x09, 0x10, 0x80, 0x77, 0x62, 0x88, 0xAB, 
							  	0x00, 0x09, 0x10, 0x80, 0x77, 0x62, 0x88, 0xAB, 
							  	0x00, 0x09, 0x10, 0x80, 0x77, 0x62, 0x88, 0xAB};*/ 
 
/*	If the extention secret will be bonded with IC's ID, the bonded secret	*/ 
/*	is stored in this buffer.*/ 							  			 
static uint8 xdata p3secret[32]; 
 
 
/******************************************************************** 
*	The following 4 function prototypes declare functions that will	* 
*	be called by writememo to write data into a block of EEPROM.	*           
*********************************************************************/ 
uint8	writesc(uint8,uint8,uint8 *); 
uint8	readsc(void); 
uint8	copyscrath(uint8); 
uint8	writeowee(uint8, uint8, uint8 *); 
 
/******************************************************************** 
*	The following function prototype declares a function that will	* 
*	write data into a block of EEPROM.								* 
*	A block has 8 bytes,to write a full page(32 bytes),this function* 
*	should be called 4 times										*           
*********************************************************************/ 
uint8 writememo(uint8, uint8, uint8, uint8, uint8); 
 
//uint8 writeregi(uint8,uint8,); 
/******************************************************************** 
*	The following function prototype declares a function that will	* 
*	read back data from an EEPROM page.								* 
*	32 bytes of data can be read back at one time					* 
*********************************************************************/ 
uint8 readmemo(uint8, uint8, uint8, uint8);	 
 
/******************************************************************** 
*	The following function prototypes declare functions that will	* 
*	load 64bits secret into secret region.							* 
*	If "set64secret" was called with parameter "ENABLE",the 64bits	* 
*	will be bonded with IC's 64 bits ID.							* 
*********************************************************************/	 
uint8	cal64secret(void);			  
uint8	l64bitssecret(void);							 
uint8	set64secret(uint8); 
 
/******************************************************************** 
*	The following function prototypes declare functions that will	* 
*	load 256bits secret into page 3.								* 
*	If "set256secret" was called with parameter "ENABLE",the 256bits* 
*	will be bonded with IC's 64 bits ID.							* 
*********************************************************************/ 
uint8	cal256secret(void); 
uint8	set256secret(uint8); 
 
			 
 
/******************************************************************** 
*	The following function prototype declares a function that		*  
	will do the authentication based on 64bits secret.				*	 
*********************************************************************/ 
uint8	auth64(uint8,uint8,uint8);	 
 
/******************************************************************** 
*	The following function prototype declares a function that		* 
*	will do the authentication based on 64bits secret.				* 
*********************************************************************/ 
uint8	auth320(uint8,uint8, uint8);	 
 
/******************************************************************** 
*	The following function prototypes declare functions that		* 
*	will do the basic 1 wire operation								* 
*********************************************************************/			 
uint8	readrom(void);						 
uint8	getromid(void);							 
void	dowcrc(uint8); 
void	crc_romid(void); 
uint16	docrc16(uint16); 
 
/******************************************************************** 
*	The following declared functions are not implemented by now		*						* 
*********************************************************************/ 
uint8	comnese(uint8);				 
uint8	resrc(uint8, uint8);					 
 
 
/*	This function writes data to scracthpad.	*/ 
uint8 writesc(uint8 TA1, uint8 TA2, uint8 * DP) 
{ 
	uint8 idata i = 0x00; 
	uint8 idata j = 0x00; 
	if (rest()) { 
		return NODEVICE; 
	} 
	writebyte(SkipRom);				/*	Reset and find a 1 wire decive	*/ 
	databuffer[i++] = Wrscratch; 
	databuffer[i++] = TA1; 
	databuffer[i++] = TA2;			/*	Memory function command and target	*/  
									/*	address are stored in databuffer	*/ 
	while (j <= 0x07) {				/*	Data to be send are stored in databuffer.	*/ 
		databuffer[i++] = *DP ++; 
		j++; 
	} 
	for (j = 0; j <= (i - 1); j++) { 
		writebyte(databuffer[j]); 
	} 
	databuffer[i++] = readbyte();	/*	Read back first byte of CRC16.	*/ 
	databuffer[i] = readbyte();		/*	Read back second byte of CRC16.	*/ 
 
	CRC16 = 0x0000; 
	for (j = 0; j <= i; j++) { 
		docrc16(databuffer[j]);		/*	Run CRC16 check over the databuffer.	*/  
	}								/*	Commands + target address + 8 bytes data + 2 bytes CRC16 code.	*/ 
	if (CRC16 != 0xB001) { 
		return WRSCC16ER;			/*	Return CRC16 error.	*/ 
	} 
	return OK; 
} 
 
 
/*	This function reads data from scracthpad.	*/ 
uint8 readsc(void)  
{ 
	uint8 idata i = 0x00; 
	if (rest()) { 
		return NODEVICE; 
	} 
	writebyte(SkipRom);					/*	Reset and find a 1 wire device.	*/ 
	databuffer[i] = Rescratch;			/*	Read scratch command, stores in databuffer	*/  
	writebyte(Rescratch);				/*	for CRC16 check purpose.	*/ 
	for (i = 1; i <= 13; i++) { 
		databuffer[i] = readbyte();		/*	Read back TA1, TA2, E/S, 8 bytes data and 2	*/  
	}									/*	bytes CRC16 code.	*/ 
	CRC16 = 0x0000; 
    for (i = 0; i <= 13; i++) { 
		docrc16(databuffer[i]);			/*	Run CRC16 check over the databuffer.	*/  
	} 
	if (CRC16 != 0xB001) {				 
		return RDSCC16ER;				/*	Return CRC16 error.	*/ 
	} 
	return OK; 
} 
 
 
/******************************************************************** 
*	The following function used to copy data from scrachpad to		* 
*	EEPROM.The copying process involes SHA-1 computation which will * 
*	use the secret in the device.If the secret was bonded with IC's	* 
*	64 bits ID, the "copyscrath" should be called with the 2nd		* 
*	parameter with the value of "ENABLE"							* 
*********************************************************************/ 
uint8 copyscrath(uint8 page) 
{ 
	uint8 idata i; 
	//cal64secret(); 
	if (getromid()!= OK) { 
		return IDCRC8ER; 
	} 
	if (rest()) { 
		return NODEVICE; 
	} 
	writebyte(SkipRom);					 
    writebyte(Coscratch);								/*	Send copy scratchpad command.	*/ 
	for (i = 1; i <= 3; i++) { 
		writebyte(databuffer[i]);						/*	Send TA1,TA2,E/S the authenticate code got by read scratch excuted before	*/ 
	}													/*	this function to active the internal SHA-1 engine in DS28E01-100.	*/ 
										 
	if (page == 0x04) {									/*	If the page is the register page set the input buffer	*/ 
		memcpy(&SHAVM_Message[0], devicesecret, 4);		/*	as required by DS28E01-100.	*/ 
   		memcpy(&SHAVM_Message[4], devicesecret, 4); 
		memcpy(&SHAVM_Message[8], &devicesecret[4], 4); 
		memcpy(&SHAVM_Message[12], &pagebuffer[8], 20); 
		memcpy(&SHAVM_Message[32], &databuffer[4],8);	/*	Data in scratch pad copied to SHA-1 input buffer.	*/ 
   		SHAVM_Message[40] = 0x04;						/*	MPX	*/ 
		memcpy(&SHAVM_Message[41], ROMID, 7);			/*	ROMID should be got by calling "readromid".			*/ 
   		memcpy(&SHAVM_Message[48], &devicesecret[4], 4); 
		memset(&SHAVM_Message[52], 0xFF, 3); 
   		SHAVM_Message[55] = 0x80; 
   		memset(&SHAVM_Message[56], 0x00, 6); 
   		SHAVM_Message[62] = 0x01; 
   		SHAVM_Message[63] = 0xB8; 
	} 
	else { 
		memcpy(&SHAVM_Message[0], devicesecret, 4); 
   		memcpy(&SHAVM_Message[4], pagebuffer, 28); 
		memcpy(&SHAVM_Message[32], &databuffer[4], 8); 
		SHAVM_Message[40] = 0x00 | (databuffer[1] >> 5);/*	MPX,databuffer[1] is TA1.	*/ 
		memcpy(&SHAVM_Message[41], ROMID, 7); 
		memcpy(&SHAVM_Message[48], &devicesecret[4],4); 
		memset(&SHAVM_Message[52], 0xFF, 3); 
   		SHAVM_Message[55] = 0x80; 
   		memset(&SHAVM_Message[56], 0x00, 6); 
   		SHAVM_Message[62] = 0x01; 
   		SHAVM_Message[63] = 0xB8; 
	}	 
	SHAVM_Compute(); 
	for (i = 0; i <= 19; i++) { 
		writebyte(SHAVM_MAC[i]); 
	} 
	delayow(20000); 
	memset(devicesecret, 0x00, 8); 
	i = readbyte(); 
	if ( i == 0xAA || i == 0x55) { 
		return COPYOK; 
	} 
	return COPYER; 
} 
 
 
/******************************************************************** 
*	This fuction read data from a specified EEPROM page or a		*  
*	specified subpage.Up to 32 bytes can be read each time.			* 
*	"page"(Range 0-4) --- is used to specity which page to be read.	* 
*	"subpage"(Range 0-3)--- which subpage in a specified page to be	* 
*	 read.															* 
*	"bytes"(Range 1-32)--- how many bytes to be read.				* 
*	"check"(Range ENABLE or DISABLE)--- to control whether to active* 
*	the parameter checking function.								* 
*********************************************************************/ 
uint8 readmemo(uint8 page, uint8 subpage, uint8 bytes, uint8 check) 
{ 
	uint8 idata i; 
	uint8 idata TA1 = 0x00; 
	uint8 idata TA2 = 0x00; 
	if (check == ENABLE) { 
		if (page > 4) { 
			return PGER; 
		} 
/* 
		if (page == 4 && subpage > 0) {			Check if the subpage is valid in a register page.  
			return SPGER; 
		} 
*/ 
		else if (subpage > 3) {				/*	Check if the subpage is valid in EEPROM page.		*/							 
			return SPGER; 
		} 
		if (bytes > 32) { 
			return BYTER; 
		} 
	} 
 
	TA1 = TA1 | (page << 5); 
	TA1 = TA1 | (subpage << 3);				/*	Form the target address.	*/ 
 
	if (rest()) { 
		return NODEVICE; 
	} 
	writebyte(SkipRom);					 
	writebyte(Redmemory);				 
	writebyte(TA1);							/*	Target address1.	*/ 
	writebyte(TA2);							/*	Target address2.	*/ 
	for (i = 0; i < bytes; i++) { 
		pagebuffer[i] = readbyte();			/*	Read a subpage from EEPROM.	*/ 
	} 
	if (page == 3 && bytes == 32) {			/*	Check if Page3 read protected.*/ 
		i = 0; 
		while (pagebuffer[i] == 0xFF && i <= 31) { 
			i++; 
		} 
		if (i > 31) { 
			return P3PRO; 
		} 
	} 
	return OK; 
} 
 
/******************************************************************** 
*	This fuction calls "writesc", "readsc", "copysc" to achieve the	* 
*	writing EEPROM function.										* 
*	Parameters are passed in by its caller.							* 
*********************************************************************/ 
uint8 writeowee(uint8 page, uint8 subpage, uint8 * DP) 
{ 
	uint8 idata TA1 = 0x00; 
	uint8 idata TA2 = 0x00; 
	TA1 = TA1 | (page << 5); 
	TA1 = TA1 | (subpage << 3); 
 
	if (writesc(TA1,TA2,DP) == WRSCC16ER) { 
		//display("writesper");			 
		return WRERR; 
	} 
 
	if (readsc() == RDSCC16ER) { 
		//display("readscer");			 
		return WRERR; 
	} 
/*	 
	if (getromid()!= OK) { 
		return IDCRC8ER; 
	} 
*/  
	if (copyscrath(page) == COPYER) { 
		//display("copyscer")			 
		return WRERR; 
	} 
 
	return OK; 
} 
 
/******************************************************************** 
*	This function is used by user to write data into EEPROM.This	* 
*	function will call "readmemo" and "writeowee" to finish the		* 
*	writing.														* 
*	"page"(Range 0-4)--- specify which page to be written.			* 
*	"subpage"(Range 0-3)--- specify which subpage in a specified	* 
*	page to be written.												* 
*	"stp"(Range 0-7)--- specify where is the start point in a 		* 
*	subpage to be written.											* 
*	"fillbytes"(Range 1-8)--- specify how many bytes to be written	*	 
*	into the EEPROM													* 
*	"uniqb"(Range "ENABLE" or DISABLE")--- should be specified		*  
*	according to the way as "set64secret()"							*									 
*********************************************************************/ 
uint8 writememo(uint8 page, uint8 subpage, uint8 stp, uint8 fillbytes, uint8 uniqb) 
{ 
	uint8 * DP = subpbuffer;						 
	uint8 idata i,j; 
 
	if (page > 4) { 
		return PGER; 
	} 
	if (page == 4) { 
		if ((subpage == 0) || (subpage == 2) || (subpage > 3)) {		/* In register page, the  subpage can be */ 
			return SPGER;		/* written is subpage 1 and 3.					 */ 
		} 
	} 
	else if (subpage > 3) {														 
		return SPGER; 
	} 
 
	if (stp > 7) { 
		return STPER;								 
	} 
 
	if (fillbytes > (8 - stp)) { 
		return FILBER; 
	} 
 
	i = subpage; 
	subpage = 0x00; 
	if (readmemo(page,subpage,32,DISABLE) == OK) {	/*	Read back a whole page data.	*/ 
		switch (i) {								/*	Find the target subpage in pagedata[32].	*/ 
			case 0: 
				j = i + 0;							/*	Add offset to base.	*/ 
				break; 
			case 1: 
				j = i + 7; 
				break; 
			case 2: 
				j = i + 14; 
				break; 
			case 3: 
				j = i + 21; 
				break; 
		} 
		memcpy(subpbuffer, &pagebuffer[j], 8); 		/*	Put the target subpage data into subpbuffer.	*/ 
	} 
	else { 
		return RDEEER; 
	} 
	memcpy(&subpbuffer[stp], tempbuffer, fillbytes);/*	Revise the ralted data portion.	*/ 
	subpage = i;									/*	Get back the oringinal subpage number.	*/ 
	if (uniqb == ENABLE) { 
		if (cal64secret() == LOADER) { 
			return WRERR; 
		} 
	} 
	else { 
		memcpy(devicesecret, basicsecret, 8); 
	} 
 
	if (writeowee(page,subpage,DP) == WRERR) { 
		return WRERR; 
	} 
	return OK; 
} 
 
 
/******************************************************************** 
*	This fuction bonds the public(basic) secret with IC's 64 bits ID* 
*	togeher.This function is called by "set64secret(uint8)" with the* 
*	parameter as "ENABLE"											* 
*********************************************************************/ 
uint8 cal64secret() 
{ 
	uint8 data i;	 
	if (getromid() != OK) { 
		return IDCRC8ER; 
	}						 
	memcpy(SHAVM_Message, basicsecret, 4);			 
	memset(&SHAVM_Message[4], 0x00, 32);			 
	memset(&SHAVM_Message[36], 0xff, 4);			 
	SHAVM_Message[40] = ROMID[0] & 0x3f;			  
	memcpy(&SHAVM_Message[41], &ROMID[1], 7);		 
	memcpy(&SHAVM_Message[48], &basicsecret[4], 4);	 
	memset(&SHAVM_Message[52],0xff, 3);				 
	SHAVM_Message[55] = 0x80;											 
   	memset(&SHAVM_Message[56], 0x00, 6);						 
   	SHAVM_Message[62] = 0x01;												 
   	SHAVM_Message[63] = 0xB8;						 
    SHAVM_Compute();     							 
	memcpy(devicesecret, SHAVM_MAC, 8);   			 
	for (i = 0; i <= 19; i++) { 
		SHAVM_MAC[i] = 0x00; 
	} 
	return OK; 
} 
 
/******************************************************************** 
*	This fuction bonds the public(basic) extebtion secret with IC's * 
*	64 bits IDtogeher.This function is called by 					* 
*	"set256secret(uint8)" with the parameter as "ENABLE"			* 
*********************************************************************/ 
uint8 cal256secret() 
{ 
	uint8 data i; 
	if (getromid() != OK) { 
		return IDCRC8ER; 
	} 
	memcpy(SHAVM_Message, ROMID, 4); 
	memcpy(&SHAVM_Message[4], basicp3secret, 32); 
	memset(&SHAVM_Message[36], 0xff, 12); 
	//memcpy(&SHAVM_Message[36], devicesecret, 8); 
	//memset(&SHAVM_Message[44], 0x00, 4); 
	memcpy(&SHAVM_Message[48], &ROMID[4], 4); 
	memset(&SHAVM_Message[52], 0xff, 3); 
	SHAVM_Message[55] = 0x80; 
	memset(&SHAVM_Message[56], 0x00, 6); 
   	SHAVM_Message[62] = 0x01; 
   	SHAVM_Message[63] = 0xB8; 
	SHAVM_Compute(); 
	memcpy(p3secret, SHAVM_MAC, 20); 
	for (i = 0; i <= 19; i++) { 
		SHAVM_MAC[i] = 0x00; 
	} 
	memset(&p3secret[20], 0x00, 12); 
	return OK; 
} 
 
/******************************************************************** 
*	This fuction loads the 64bits secrest into secret region of 	* 
*	DS28E01.														* 
*********************************************************************/	 
uint8 l64bitssecret() 
{ 
	uint8 data i,j; 
	if (rest()) { 
		return NODEVICE; 
	} 
	writebyte(SkipRom); 
	writebyte(Loadfirse); 
	for (i = 1; i <= 3; i++) { 
		writebyte(databuffer[i]);			 
	} 
	delayow(30000); 
	i = readbyte(); 
	for (j = 0; j <= 7; j++) { 
		devicesecret[j] = 0x00; 
	} 
	writesc(databuffer[1], databuffer[2], devicesecret);		//Fill the devicesecret array and scratch pad with 0x00 to erase the secret. 
	if (i == 0xAA || i == 0x55) { 
		return OK; 
	} 
	return LOADER; 
} 
 
 
/******************************************************************** 
*	This fuction loads the 64bits secrest into secret region of 	* 
*	DS28E01.														* 
*	"uinque"(Range DISABLE or ENABLE),the recommended parameter is	* 
*	ENABLE, this will bring highest security level					* 
*********************************************************************/ 
uint8 set64secret(uint8 unique)  
{ 
	uint8 data TA1 = 0x80; 
    uint8 data TA2 = 0x00; 
 
	if (getromid() != OK) { 
		return FALSE; 
	} 
	if (unique == ENABLE) { 
		if (cal64secret() != OK) { 
			return SETSEER; 
		} 
	} 
	else { 
		memcpy(devicesecret, basicsecret, 8); 
	} 
 
	if (writesc(TA1, TA2, devicesecret) != OK) { 
		return SETSEER; 
	} 
	if (readsc() != OK) { 
		return SETSEER; 
	}	 
	if (l64bitssecret() != OK) { 
		return SETSEER; 
	} 
	return OK; 
} 
 
/******************************************************************** 
*	This fuction loads the 256bits extention secrest into page 3.	*  
*	"uinqueex"(Range DISABLE or ENABLE),the recommended parameter is* 
*	ENABLE, this will bring highest security level.					* 
*********************************************************************/ 
uint8	set256secret(uint8 uniqueex, uint8 uniqbasic) 
{ 
	uint8 data i,j,k; 
	if (uniqueex == ENABLE) { 
		if (cal256secret() != OK) { 
			return SETSEER; 
		} 
	}	 
	else { 
		memcpy(p3secret, basicp3secret, 32); 
	}	 
 
	k = 0; 
	for (i = 0; i <= 3; i++) {				 
		for (j = 0; j <= 7; j++) { 
			tempbuffer[j] = p3secret[k]; 
			k++; 
 		} 
		if (writememo(3,i,0,8,uniqbasic)!= OK) { 
			return LOADER; 
		} 
	} 
	return OK; 
} 
 
/******************************************************************** 
*	This fuction does anthentication work on 64 bits secret.It retu-* 
*	-rns "OK" when authentication pass, otherwise it returns "FLASE"*					* 
*	"page"(Range 0-3)---selects an EEPROM page to be put in SHA-1 e-* 
*	-ngine.															* 
*	"unique"(Range ENABLE or DISABLE)--- to select the secret.Should* 
*	be same as the one used to load the secert.						* 
*	"anoy"(Range ENABLE or DISABLE)--- to selcet if the ROMID should* 
*	be used in SHA-1 computation.When "DISABLE" is used,the ROMID	* 
*	will be used in SHA-1 computation.								*  
*********************************************************************/ 
uint8	auth64(uint8 page,uint8 unique,uint8 anoy) 
{ 
	uint8 data TA1, TA2; 
	uint8 data i = 0,j = 0; 
	uint8 xdata pageback[38];		/*	Array to store command,target address,32 bytes data	*/ 
									/*	, FF byte and 2 bytes inverting CRC16 code.	*/ 
	uint8 xdata dsmac[22]; 
 
	TA1 = 0x00; 
	TA1 = TA1 | (page << 5);		/*	Get real address and put them in arry.	*/ 
	TA2 = 0x00; 
 
	subpbuffer[i++] = 0x00;			/*	Get random numbers and write them to scratch pad.	*/ 
	subpbuffer[i++] = 0x00; 
 
	for (; i <= 6; i++) { 
    	subpbuffer[i] = (uint8)rand();	/*	Get five random number and cast the return value to uint8.	*/ 
		//subpbuffer[i] = 0x01; 
	} 
	subpbuffer[i] = 0x00; 
 
	if (writesc(TA1,TA2,subpbuffer) != OK) {	/*	Write them to scrach pad.	*/ 
		return FALSE; 
	} 
	if (readsc() != OK) { 
		return FALSE; 
	} 
	if (unique == ENABLE) { 
		if (cal64secret() != OK) { 
			return FALSE; 
		}  
	} 
	else { 
		memcpy(devicesecret, basicsecret, 8); 
	} 
	i = 0; 
	if (anoy == DISABLE) {						/*	ROMID will be used in SHA-1 computation	*/ 
		pageback[i++] = Reautpage;				/*	Authentication put Reautpage command in arry.	*/ 
		if (getromid() != OK) {				 
			return IDCRC8ER; 
		} 
	} 
	else {										/* 	ROMID will not be used in SHA-1 computation */ 
		pageback[i++] = Anautpage;				/*	Put Anautpage command in arry.	*/ 
		for (j = 0; j <= 7; j++) { 
			ROMID[j] = 0xFF;					/*	Fill the ROMID buffer with 0xFF.	*/ 
		} 
	} 
	pageback[i++] = TA1; 
	pageback[i] = TA2; 
 
	if (rest()) { 
		return NODEVICE; 
	} 
	writebyte(SkipRom);							 
 
	for (j = 0; j <= i; j++) {					  
		writebyte(pageback[j]); 
	} 
 	for (i = j; i <= 37; i++) {					/*	Read back page data, 0xFF and 2 bytes inverting CRC16 code.	*/ 
		pageback[i] = readbyte();				/*	Data stay in the buffer from pagedata[3] to pagedata[34].	*/ 
	} 
 
	CRC16 = 0x0000; 
    for (i = 0; i <= 37; i++) { 
		docrc16(pageback[i]);					 
	} 
	if (CRC16 != 0xB001) {				 
		return CRC16ER;							 
	} 
 
	memcpy(SHAVM_Message, devicesecret, 4);			/*	Copy the devicesecret to input buffer.	*/ 
	memcpy(&SHAVM_Message[4], &pageback[3], 32);	/*	Fill 32 bytes page data to input buffer.	*/ 
	memcpy(&SHAVM_Message[36], &subpbuffer[2] , 2);	/*	Set 2 bytes of challenge to input buffer.	*/ 
	SHAVM_Message[38] = 0xFF; 
	SHAVM_Message[39] = 0xFF; 
	SHAVM_Message[40] = 0x40 | TA1 >> 5;			/*	Set MPX.	*/  
	memcpy(&SHAVM_Message[41], ROMID, 7);			/*	Input ROMID	*/ 
	memcpy(&SHAVM_Message[48], &devicesecret[4], 4);/*	Input another 4 bytes of basic secret to input buffer.	*/ 
	memcpy(&SHAVM_Message[52], &subpbuffer[4], 3);	/*	Set the input buffer as defined by datasheet.	*/ 
	SHAVM_Message[55] = 0x80;						/*	Set the input buffer as defined by datasheet.	*/					 
   	memset(&SHAVM_Message[56], 0x00, 6);			/*	Set the input buffer as defined by datasheet.	*/		 
   	SHAVM_Message[62] = 0x01;						/*	Set the input buffer as defined by datasheet.	*/						 
   	SHAVM_Message[63] = 0xB8; 
	for (i = 0; i <= 7; i++) { 
		devicesecret[i] = 0x00; 
	} 
	SHAVM_Compute(); 
	for (i = 0; i <= 21; i++) {						/*	Read back the DS28E01-100 computed MAC.	*/ 
		dsmac[i] = readbyte(); 
	} 
 
	CRC16 = 0x0000; 
    for (i = 0; i <= 21; i++) { 
		docrc16(dsmac[i]);					 
	} 
	if (CRC16 != 0xB001) {				 
		return CRC16ER;							 
	} 
	i = 0; 
	while((dsmac[i] == SHAVM_MAC[i]) && (i <= 19)) { 
    	i++; 
	} 
	if (i > 19) { 
		return OK; 
	} 
	else { 
		return FALSE; 
	} 
} 
 
 
/******************************************************************** 
*	This fuction does anthentication work on 320 bits.It returns	* 
*	"OK" when authentication pass, otherwise it returns "FLASE".	*					* 
*	This aunthentication is based on page 3 and page 3 is set to be	* 
*	read protected.													* 
*	"unib"(Range ENABLE or DISABLE)--- to select the 64 bits secret.* 
*	Should be same as the one used to load the 64 bits secert.		* 
*	"uniex"(Range ENABLE or DISABLE)--- to select the 256 bits secr-* 
*	t,should be same as the one used to load 256 bits secret.		*														*  
*********************************************************************/		 
uint8	auth320(uint8 unib,uint8 uniex, uint8 anoy) 
{ 
	uint8 data TA1, TA2, page; 
	uint8 data i = 0,j = 0; 
	uint8 xdata pageback[38];					 
	uint8 xdata dsmac[22]; 
 
	page = 0x03; 
	TA1 = 0x00; 
	TA1 = TA1 | (page << 5);		/*	Get real address and put them in arry.	*/ 
	TA2 = 0x00; 
 
	subpbuffer[i++] = 0x00;			/*	Get random numbers and write them to scratch pad.	*/ 
	subpbuffer[i++] = 0x00; 
 
	for (; i <= 6; i++) { 
    	subpbuffer[i] = (uint8)rand();	/*	Get five random number and cast the return value to uint8.	*/ 
	} 
	subpbuffer[i] = 0x00; 
 
	if (writesc(TA1,TA2,subpbuffer) != OK) {	/*	Write them to scrach pad.	*/ 
		return FALSE; 
	} 
	if (readsc() != OK) { 
		return FALSE; 
	} 
	if (unib == ENABLE) { 
		if (cal64secret() != OK) { 
			return FALSE; 
		} 
	} 
	else { 
		memcpy(devicesecret, basicsecret, 8); 
	} 
	if (uniex == ENABLE) { 
		if (cal256secret() != OK) { 
			return FALSE; 
		} 
	}	 
	else { 
		memcpy(p3secret, basicp3secret, 32); 
	} 
	i = 0; 
	if (anoy == DISABLE) {						/*	ROMID will be used in SHA-1 computation	*/ 
		pageback[i++] = Reautpage;				/*	Authentication put Reautpage command in arry.	*/ 
		if (getromid() != OK) {				 
			return IDCRC8ER; 
		} 
	} 
	else {										/* 	ROMID will not be used in SHA-1 computation */ 
		pageback[i++] = Anautpage;				/*	Put Anautpage command in arry.	*/ 
		for (j = 0; j <= 7; j++) { 
			ROMID[j] = 0xFF;					/*	Fill the ROMID buffer with 0xFF.	*/ 
		} 
	} 
	pageback[i++] = TA1; 
	pageback[i] = TA2; 
 
	if (rest()) { 
		return NODEVICE; 
	} 
	writebyte(SkipRom);							 
 
	for (j = 0; j <= i; j++) {					  
		writebyte(pageback[j]); 
	} 
 	for (i = j; i <= 37; i++) {					/*	Read back page data, 0xFF and 2 bytes inverting CRC16 code.	*/ 
		pageback[i] = readbyte();				/*	Data stay in the buffer from pagedata[3] to pagedata[34].	*/ 
	} 
 
	CRC16 = 0x0000; 
    for (i = 0; i <= 37; i++) { 
		docrc16(pageback[i]);					 
	} 
	if (CRC16 != 0xB001) {				 
		return CRC16ER;							 
	} 
 
	memcpy(SHAVM_Message, devicesecret, 4);			/*	Copy the devicesecret to input buffer.	*/ 
	memcpy(&SHAVM_Message[4], p3secret, 32);		/*	Fill 32 bytes extention secret to input buffer.	*/ 
	memcpy(&SHAVM_Message[36], &subpbuffer[2] , 2);	/*	Set 2 bytes of challenge to input buffer.	*/ 
	SHAVM_Message[38] = 0xFF; 
	SHAVM_Message[39] = 0xFF; 
	SHAVM_Message[40] = 0x40 | TA1 >> 5;			/*	Set MPX.	*/  
	memcpy(&SHAVM_Message[41], ROMID, 7);			/*	Input ROMID	*/ 
	memcpy(&SHAVM_Message[48], &devicesecret[4], 4);/*	Input another 4 bytes of basic secret to input buffer.	*/ 
	memcpy(&SHAVM_Message[52], &subpbuffer[4], 3);	/*	Set the input buffer as defined by datasheet.	*/ 
	SHAVM_Message[55] = 0x80;						/*	Set the input buffer as defined by datasheet.	*/					 
   	memset(&SHAVM_Message[56], 0x00, 6);			/*	Set the input buffer as defined by datasheet.	*/		 
   	SHAVM_Message[62] = 0x01;						/*	Set the input buffer as defined by datasheet.	*/						 
   	SHAVM_Message[63] = 0xB8; 
 
	for (i = 0; i <= 7; i++) { 
		devicesecret[i] = 0x00; 
	} 
	for (i = 0; i <= 31; i++) { 
		p3secret[i] = 0x00; 
	}	 
	SHAVM_Compute(); 
	for (i = 0; i <= 21; i++) {						/*	Read back the DS28E01-100 computed MAC.	*/ 
		dsmac[i] = readbyte(); 
	} 
 
	CRC16 = 0x0000; 
    for (i = 0; i <= 21; i++) { 
		docrc16(dsmac[i]);					 
	} 
	if (CRC16 != 0xB001) {				 
		return CRC16ER;							 
	} 
	i = 0; 
	while((dsmac[i] == SHAVM_MAC[i]) && (i <= 19)) { 
    	i++; 
	} 
	if (i > 19) { 
		return OK; 
	} 
	else { 
		return FALSE; 
	} 
} 
 
 
/********************************************************* 
uint8 comnese(uint8 page) 
{	 
	uint8 idata i; 
	uint8 idata TA1 = 0x00; 
	uint8 idata TA2 = 0x00; 
	uint8 data sc[8]; 
	for (i = 0; i <= 7; i++) { 
		sc[i] = 0x00; 
	} 
	TA1 = TA1 | (page << 5); 
//	readmemo(page, 0 , 32, ENABLE);			//Read back the specified page data involved in computer next secret command. 
	writesc(TA1, TA2, particial);			//Write particial secret to scratch pad. 
	if (rest()) { 
		return NODEVICE; 
	} 
	writebyte(ReadRom); 
	writebyte(Comnextse); 
	delayow(10); 
	i = readbyte(); 
	writesc(TA1, TA2, sc); 
	if (i == 0xAA || i == 0x55) { 
		return OK; 
	} 
	return FALSE; 
} 
**********************************************************************/ 
 
/********************************************************************************************* 
//This function should be used in a enviromnet that the contact condition could not be ensured 
//to eliminate the weak powered bit in EEPROM to refresh a subpage each time 
 
uint8 refscr(uint8 page, uint8 subpage) 
{ 
	uint8 data i, j; 
	uint8 xdata re[13]; 
	uint8 idata TA1 = 0x00; 
	uint8 idata TA2 = 0x00; 
	TA1 = TA1 | (page << 5); 
	TA1 = TA1 | (subpage << 3); 
	if (rest()) { 
		return NODEVICE; 
	} 
	writebyte(SkipRom); 
	i = 0; 
	re[i++] = Refreshsc; 
	re[i++] = TA1; 
	re[i++] = TA2; 
	for (i = i; i <= 10; i++) { 
		re[i] = 0x00;					//Dummy bytes send by host to let DS28E01-100 load eeprom data to scratch pad. 
	} 
	for (i = 0; i <= 10; i++) { 
		writebyte(re[i]); 
	} 
 	re[i++] = readbyte(); 
	re[i] = readbyte(); 
	 
	CRC16 = 0x0000; 
    for (i = 0; i <= 12; i++) { 
		docrc16(re[i]);					//Run CRC16 check over the pagebcak. 
	} 
	if (CRC16 != 0xB001) {				 
		return CRC16ER;					//Return CRC16 error. 
	} 
	readsc();							//Read back the data in scratch pad. 
	i = 0;								//This part would be opened later. 
	j= 4; 
	while (i <= 0x07 && subpbuffer[i] == databuffer[j]) { 
		i++; 
		j++; 
	} 
	if (i > 7) { 
		loadsecret(); 
		return OK; 
	} 
	writememo(page,subpage, 0,8); 
	return RWEEP;						//Dismacth rewrite eeprom. 
} 
***************************************************************************************/ 
 
uint8 readrom() 
{ 
	uint8 idata i; 
	if (rest()) { 
		return NODEVICE; 
	} 
	writebyte(ReadRom); 
	for (i = 0; i <= 7; i ++) { 
		ROMID[i] = readbyte(); 
	} 
} 
 
void dowcrc(uint8 x) 
{ 
   CRC8 = dscrc_table[CRC8 ^ x]; 
} 
 
void crc_romid(void) 
{ 
	uint8 idata i; 
    //CRC8 check 
    CRC8 = 0; 
    for (i = 0; i <= 7; i ++) { 
    	dowcrc(ROMID[i]);  
    }	//check if reading ROM ID is right by CRC8 result  
} 
 
uint8 getromid() 
{ 
	uint8 idata i; 
	i = 0x03; 
	do { 
		readrom(); 
		crc_romid(); 
		i --; 
	} while (CRC8 != 0x00 && i != 0x00); 
 
	if (CRC8 != 0x00) { 
		return IDCRC8ER; 
	} 
	return OK; 
} 
		 
uint16 docrc16(uint16 cdata) 
{ 
   cdata = (cdata ^ (CRC16 & 0xff)) & 0xff; 
   CRC16 >>= 8; 
 
   if (oddparity[cdata & 0xf] ^ oddparity[cdata >> 4]) 
   CRC16 ^= 0xc001; 
 
   cdata <<= 6; 
   CRC16 ^= cdata; 
   cdata <<= 1; 
   CRC16 ^= cdata; 
 
   return CRC16; 
}