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

📄 transaction.c

📁 一个免费的SMART CARD OS系统。
💻 C
字号:
/* ============================================================================   Project Name : jayaCard   Module Name  : proto/bios/fs/transaction.c   Version : $Id: transaction.c,v 1.20 2004/03/07 10:43:22 dgil Exp $	Description: transaction management - add / commit / rollback    The Original Code is jayaCard code.    The Initial Developer of the Original Code is Gilles Dumortier.	Portions created by the Initial Developer are Copyright (C) 2002-2004 the    Initial Developer. All Rights Reserved.    Contributor(s):    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; see http://www.gnu.org/licenses/gpl.html   History Rev	Description   020203 dgil	wrote it from scratch   ============================================================================*/#include "precomp.h"#ifdef JAYA_TRANSACTION/* ============================================================================    __quick_write_stream()    Notes:    - buffer to eeprom only !    - use the transaction specific stream   ========================================================================= */jbyte __quick_write_stream(jbyte xdata* buf,jbyte length){    LOCAL(jbyte,n);    LOG3("STREAM","__quick_write_stream() : write addr=0x%.4x length=0x%.2X flag=%.2X",streamTrans.m_pos,length,streamTrans.m_flags);    /* crc-16 */    if ((streamTrans.m_flags&CRC_STREAM)!=0) {        for (n=0;n<length;n++) { HAL_CRC_COMPUTE(buf[n]); }    }    /* encipher ? */    if ((streamTrans.m_flags&CIPHER_STREAM)!=0) {        BIOS_CIPHER(buf,length,ENCIPHER);    }    /* write the stream */    if (HAL_EEPROM_WRITE(streamTrans.m_pos,buf,length) != EEPROM_HAL_OK) {        BIOS_SETERR(ERR_WRITE_ERROR);        return JSEC_FAIL;    }    /* check the write ? */    if ((streamTrans.m_flags&SECURE_STREAM)==SECURE_STREAM) {        HAL_VERIFY_EEPROM(buf,streamTrans.m_pos,length);    }    /* unique stream ? */    if ((streamTrans.m_flags&UNIQUE_STREAM)==UNIQUE_STREAM) {        HAL_ERASE_XRAM(buf,length);    }    /* update the stream */    streamTrans.m_pos += length;    return JSEC_OK;}/* ============================================================================	__bios_trans_add()	Secure algo: 		[the order *IS* very important - think a lot before changing it !]		secure read tfree pointer, pointing to the free area in transaction buf		check we have enough space to store the new transaction 		create the stream		init the CRC		secure store transaction destination address		secure store transaction length		secure store the transaction END OF marker		move the stream (unique + calculate CRC)		secure write of the CRC		secure update the transaction pointer		secure update the transaction state to TRANSACTION_STATE_VALID   ========================================================================= */jbyte __bios_trans_add(jbyte xdata* buf,jword adr,jbyte len){    LOCAL(jword,tfree);    LOCAL(jword,rlen);	/* dump the diff */	INTROSPECTION();	LOG3("TRANSACTION","__bios_trans_add(buf=0x%p,adr=0x%.4X,len=%d)\n",buf,adr,len);	/* get and check the free addr area */	tfree = HAL_EEPROM_READ_WORD(ADDR_TRANSACTION_FREE);	if ((HAL_EEPROM_READ_WORD(ADDR_TRANSACTION_FREE)!=tfree) || (tfree>ADDR_TRANSACTION_END) || (tfree<ADDR_TRANSACTION_BEGIN)) {		LOG("ATTACK","__bios_trans_add() security point #1");		LOG3("ATTACK","tree = %.4X not in [%.4X,%.4X] ?",tfree,ADDR_TRANSACTION_BEGIN,ADDR_TRANSACTION_END);attack:		/* parano: real case should be EEPROM failure to read or write ;-) */		HAL_HALT();		return JSEC_FAIL;	}	/* check we have enough size */	rlen = (jword)len+SIZEOF_TRANSACTION_INFO;	if ((tfree+rlen)>ADDR_TRANSACTION_END) {		/* __warn */		/* lasterr ? */		return JSEC_FAIL;	}	/* create the entry */    BIOS_INIT_STREAM(&streamTrans,WRITE_STREAM|CRC_STREAM,tfree+4,len);	HAL_CRC_INIT();	/* secure store the transaction address */	if (HAL_EEPROM_WRITE_WORD(tfree+1,adr) != EEPROM_HAL_OK) {writeerr:		LOG("TRANSACTION","__bios_trans_add() tfree write failure !");		BIOS_SETERR(ERR_WRITE_ERROR);		return JSEC_FAIL;	}	if (HAL_EEPROM_READ_WORD(tfree+1)!=adr) {		LOG("ATTACK","__bios_trans_add() security point #2");		goto attack;	}	HAL_CRC_COMPUTE(LOBYTE(adr));	HAL_CRC_COMPUTE(HIBYTE(adr));	/* secure store the transaction length */	if (HAL_EEPROM_WRITE_BYTE(tfree+3,len) != EEPROM_HAL_OK) goto writeerr;	if (HAL_EEPROM_READ_BYTE(tfree+3)!=len) {		LOG("ATTACK","__bios_trans_add() security point #3");		goto attack;	}	HAL_CRC_COMPUTE(len);	/* secure store the transaction END OF marker */	if (HAL_EEPROM_WRITE_BYTE(tfree+rlen,TRANSACTION_STATE_ENDOF) != EEPROM_HAL_OK) goto writeerr;	if (HAL_EEPROM_READ_BYTE(tfree+rlen)!=TRANSACTION_STATE_ENDOF) {		LOG("ATTACK","__bios_trans_add() security point #4");		goto attack;	}	/* at this point, all the markers are in place, so move the stream itself */    __quick_write_stream(buf,len);	/* secure write of the CRC */	if (HAL_EEPROM_WRITE_BYTE(tfree+rlen-2,HAL_CRC_LO()) != EEPROM_HAL_OK) goto writeerr;	if (HAL_EEPROM_WRITE_BYTE(tfree+rlen-1,HAL_CRC_HI()) != EEPROM_HAL_OK) goto writeerr;	/* secure update the transaction free pointer */	if (HAL_EEPROM_WRITE_WORD(ADDR_TRANSACTION_FREE,tfree+rlen) != EEPROM_HAL_OK) goto writeerr;	if (HAL_EEPROM_READ_WORD(ADDR_TRANSACTION_FREE)!=(tfree+rlen)) {		LOG("ATTACK","__bios_trans_add() security point #5");		goto attack;	}	/* secure update the transaction state */	if (HAL_EEPROM_WRITE_BYTE(tfree,TRANSACTION_STATE_VALID) != EEPROM_HAL_OK) goto writeerr;	if (HAL_EEPROM_READ_BYTE(tfree)!=TRANSACTION_STATE_VALID) {		LOG("ATTACK","__bios_trans_add() security point #6");		goto attack;	}	/* dump the diff */	INTROSPECTION();	return JSEC_OK;}/* ============================================================================	__bios_trans_rollback()	We need to delete all the transactions in the transaction area.	Secure algo: contant time + global semaphore + write redudancy		[the order *IS* very important - think a lot before changing it !]		secure erase the whole transaction area		secure write the free transaction pointer		secure write the EOT   ========================================================================= */void __bios_trans_rollback(void){	gGlobalSem = JSEC_OK;	/* dump the diff */	INTROSPECTION();	LOG("TRANSACTION","__bios_trans_rollback()");	/* erase the whole area */	#if 0    HAL_ERASE_EEPROM(ADDR_TRANSACTION_BEGIN,ADDR_TRANSACTION_AREASIZE,0x00);	gGlobalSem++;	#endif	/* secure write the free transaction pointer */	if (HAL_EEPROM_WRITE_WORD(ADDR_TRANSACTION_FREE,ADDR_TRANSACTION_BEGIN) != EEPROM_HAL_OK) {		LOG("ATTACK","__bios_trans_rollback() security point #1");attack:		/* parano: real case should be EEPROM failure to read or write ;-) */		HAL_HALT();		return;	}	if (HAL_EEPROM_READ_WORD(ADDR_TRANSACTION_FREE)!=ADDR_TRANSACTION_BEGIN) {		LOG("ATTACK","__bios_trans_rollback() security point #2");		goto attack;	}	/* secure write the EOT */	if (HAL_EEPROM_WRITE_BYTE(ADDR_TRANSACTION_BEGIN,TRANSACTION_STATE_ENDOF) != EEPROM_HAL_OK) {		LOG("ATTACK","__bios_trans_rollback() security point #3");		goto attack;	}	if (HAL_EEPROM_READ_BYTE(ADDR_TRANSACTION_BEGIN)!=TRANSACTION_STATE_ENDOF) {		LOG("ATTACK","__bios_trans_rollback() security point #4");		goto attack;	}	#if 0	if (gGlobalSem!=JSEC_SEM) {		LOG("ATTACK","__bios_trans_rollback() security point #5");		goto attack;	}	#endif	/* dump the diff */	INTROSPECTION();}/* ============================================================================	__bios_trans_commit()	Secure algo:		[the order *IS* very important - think a lot before changing it !]		initialize current to the beginning of transaction area		secure read tfree pointer		while current<tfree			secure read of transaction state			secure read of transaction destination address			secure read of transaction size			update the streams itself			move the stream for the transaction area to the final address			check the CRC			update the transaction state to DONE			compute address of next transaction		endwhile   ========================================================================= */void __bios_trans_commit(void){    LOCAL(jword,current);    /* current transaction */    LOCAL(jword,tfree);    LOCAL(jbyte,state);	/* dump the diff */	INTROSPECTION();	LOG("TRANSACTION","__bios_trans_commit()");	/* start at the beginning of the area */	current = ADDR_TRANSACTION_BEGIN;	/* get and check the free addr area */	tfree = HAL_EEPROM_READ_WORD(ADDR_TRANSACTION_FREE);	if ((HAL_EEPROM_READ_WORD(ADDR_TRANSACTION_FREE)!=tfree) || (tfree>ADDR_TRANSACTION_END) || (tfree<ADDR_TRANSACTION_BEGIN)) {		if (tfree==0x0000) {			LOG1("TRANSACTION","__bios_trans_commit() tfree=%.4X - unitialized area !",tfree);			goto rollback;		}		LOG1("ATTACK","__bios_trans_commit() security point #1 tfree=%.4X",tfree);attack:		/* parano: real case should be EEPROM failure to read or write ;-) */		HAL_HALT();		return;	}	/* while current<free */	while (current<tfree) {		HAL_CRC_INIT();		/* secure read of the state */		state = HAL_EEPROM_READ_BYTE(current);		if (HAL_EEPROM_READ_BYTE(current)!=state) {			LOG("ATTACK","__bios_trans_commit() security point #2");			goto attack;		}		/* secure read of address */		streamDest.m_start = HAL_EEPROM_READ_WORD(current+1);		if (HAL_EEPROM_READ_WORD(current+1)!=streamDest.m_start) {			LOG("ATTACK","__bios_trans_commit() security point #3");			goto attack;		}		streamDest.m_pos = streamDest.m_start;		HAL_CRC_COMPUTE(LOBYTE(streamDest.m_start));		HAL_CRC_COMPUTE(HIBYTE(streamDest.m_start));		/* secure read of size */		streamDest.m_size = HAL_EEPROM_READ_BYTE(current+3);		if (HAL_EEPROM_READ_BYTE(current+3)!=streamDest.m_size) {			LOG("ATTACK","__bios_trans_commit() security point #4");			goto attack;		}        HAL_CRC_COMPUTE(LOBYTE(streamDest.m_size));		/* update the streams itself */		streamDest.m_flags = WRITE_STREAM | UNIQUE_STREAM | CRC_STREAM;		streamDest.m_flags2 = 0x00;		BIOS_INIT_STREAM(&streamSrc,READ_STREAM,current+4,streamDest.m_size);		/* move the stream for the transaction area to the final address */		if (state==TRANSACTION_STATE_VALID) {			if (BIOS_STREAM2STREAM(&streamDest,&streamSrc,(jbyte)streamDest.m_size)==JSEC_FAIL) {				LOG("ATTACK","__bios_trans_commit() security point #5");				goto attack;			}		}		/* check the CRC		 	__todo: how to check the CRC before moving the stream ?			__solution: stream compute CRC and check CRC==0 because the last two bytes of the stream is the CRC		*/		if ( (HAL_EEPROM_READ_BYTE(streamSrc.m_pos)!=HAL_CRC_LO()) ||			 (HAL_EEPROM_READ_BYTE(streamSrc.m_pos+1)!=HAL_CRC_HI()) )		{			LOG2("ATTACK","__bios_trans_commit() security point #6 crclo=%.2X crchi=%.2X",HAL_CRC_LO(),HAL_CRC_HI());			goto attack;		}		if (state==TRANSACTION_STATE_ENDOF) {			/* strange but ... it is time to exit anyway __secure __thinkabout */			break;		}		/* change state to done */		if (HAL_EEPROM_WRITE_BYTE(current,TRANSACTION_STATE_DONE) != EEPROM_HAL_OK) {			LOG("ATTACK","__bios_trans_commit() security point #7");			goto attack;		}		/* next step */		current += streamDest.m_size+SIZEOF_TRANSACTION_INFO;	}	/* all has been done !	   => erase/reset all the transaction area calling the rollback mechanism !	*/rollback:	BIOS_TRANS_ROLLBACK();}/* =========================================================================	That's all folks !   ========================================================================= */#endif/* JAYA_TRANSACTION */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -