📄 transaction.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 + -