📄 stream.c
字号:
/* ============================================================================ Project Name : jayaCard Module Name : proto/bios/fs/stream.c Version : $Id: stream.c,v 1.35 2004/03/07 10:43:22 dgil Exp $ Description: stream management - helper stuff for FileSystem manager 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 012603 dgil wrote it from scratch 101903 dgil Add transactioned stream :-) ============================================================================*/#include "precomp.h"/* ============================================================================ __bios_init_stream() ========================================================================= */void __bios_init_stream(BIOS_STREAM idata* stream,jbyte flags,jbyte exflags,jword start,jword size){ stream->m_flags = flags; stream->m_flags2 = exflags; stream->m_start = start; stream->m_pos = start; stream->m_size = size;}/* ============================================================================ __bios_test_stream() Check the stream against the required length parameter. ========================================================================= */jbyte __bios_test_stream(BIOS_STREAM idata* stream,jword length){ /* don't check the length / position if IO */ if ( (stream->m_flags&IO_STREAM)==IO_STREAM) goto check_flag; if ( (length==0) || ((stream->m_pos+length)>(stream->m_start+stream->m_size)) || ((stream->m_pos+length)<stream->m_start) ) { LOG4("STREAM", "__bios_test_stream start=%04Xh offset=%d size=%d requested len=%d", stream->m_start, stream->m_pos-stream->m_start, stream->m_size, length ); /* we will be out of the stream area ! */ BIOS_SETERR(ERR_INVALID_OFFSET); return JSEC_FAIL; }check_flag: if ( ((stream->m_flags&(READ_STREAM|WRITE_STREAM)) == 0) && ((stream->m_flags2&(ERASE_STREAM)) == 0)) { /* invalid flag ! */ BIOS_SETERR(ERR_INVALID_FLAG); return JSEC_FAIL; } return JSEC_OK;}/* ============================================================================ __bios_read_stream() secure: global semaphore on read checking ! notes: - chipher : BIOS_CIPHER_INIT()/BIOS_CRYPTO_CLEANUP() must be called outside this func. ========================================================================= */jbyte __bios_read_stream(jbyte xdata* buf,BIOS_STREAM idata* stream,jbyte length){ LOCAL(jbyte,n); /* stream checking */ if (BIOS_TEST_STREAM(stream,length)==JSEC_FAIL) return JSEC_FAIL; if ((stream->m_flags&READ_STREAM)==0) { BIOS_SETERR(ERR_INVALID_FLAG); HAL_HALT(); return JSEC_FAIL; } gGlobalSem = JSEC_OK; LOG3("STREAM","__bios_read_stream() : stream=0x%lX read addr=0x%.4x length=0x%.2X",stream,stream->m_pos,length); if ( ((stream->m_flags2&INS_IND_STREAM) == INS_IND_STREAM) && ((stream->m_flags&IO_STREAM)==IO_STREAM) ) { /* in T=0, indicate the begin to receive */ BIOS_SEND_INS(); } /* read the stream */ if ((stream->m_flags&IO_STREAM)==IO_STREAM) { for (n=0;n<length;n++) { BIOS_SEND_IINS(); buf[n] = BIOS_RECEIVE(); } } else { if ((stream->m_flags2&XRAM_STREAM) == XRAM_STREAM) { #ifdef XPCORE_SIMU LOG("SIMU","Simulator is not able to simulate that (XPTR conversion) !"); HAL_HALT(); #else HAL_MEMCPY(buf,XPTR(stream->m_pos),length); #endif } else { HAL_EEPROM_READ(buf,stream->m_pos,length); } } /* check the read ? */ if ((stream->m_flags&(SECURE_STREAM|IO_STREAM))==SECURE_STREAM) { HAL_VERIFY_EEPROM(buf,stream->m_pos,length); gGlobalSem-=2; } /* unique stream ? */ if ((stream->m_flags&(UNIQUE_STREAM|IO_STREAM))==UNIQUE_STREAM) { HAL_ERASE_EEPROM(stream->m_pos,length,0x00); gGlobalSem-=2; } /* crc-16 */ if ((stream->m_flags&CRC_STREAM)==CRC_STREAM) { for (n=0;n<length;n++) { HAL_CRC_COMPUTE(buf[n]); } } if ((stream->m_flags&CHKCRC_STREAM)==CHKCRC_STREAM) { if ((HAL_CRC_LO()!=0) || (HAL_CRC_HI()!=0)) { /* bad CRC */ BIOS_SETERR(ERR_INVALID_CRC); return JSEC_FAIL; } } /* decipher ? */ if ((stream->m_flags&CIPHER_STREAM)==CIPHER_STREAM) { BIOS_CIPHER(buf,length,DECIPHER); } /* update the stream */ stream->m_pos += length; if (gGlobalSem!=JSEC_OK) { HAL_HALT(); return JSEC_FAIL; } return JSEC_OK;}/* ============================================================================ __bios_write_stream() secure: global semaphore on write checking ! notes: - chipher : BIOS_CIPHER_INIT()/BIOS_CRYPTO_CLEANUP() must be called outside this func. ========================================================================= */jbyte __bios_write_stream(BIOS_STREAM idata* stream,jbyte xdata* buf,jbyte length){ LOCAL(jbyte,n); /* stream checking */ if (BIOS_TEST_STREAM(stream,length)==JSEC_FAIL) return JSEC_FAIL; if ((stream->m_flags&WRITE_STREAM)==0) { BIOS_SETERR(ERR_INVALID_FLAG); HAL_HALT(); return JSEC_FAIL; } gGlobalSem = JSEC_OK; LOG3("STREAM","__bios_write_stream() : stream=0x%lX write addr=0x%.4x length=0x%.2X",stream,stream->m_pos,length); if ( ((stream->m_flags2&INS_IND_STREAM) == INS_IND_STREAM) && ((stream->m_flags&IO_STREAM)==IO_STREAM) ) { /* in T=0, indicate the begin to send */ BIOS_SEND_INS(); } /* crc-16 */ if ((stream->m_flags&CHKCRC_STREAM)==CHKCRC_STREAM) { for (n=0;n<length-2;n++) { HAL_CRC_COMPUTE(buf[n]); } buf[n++] = HAL_CRC_LO(); buf[n] = HAL_CRC_HI(); } else { if ((stream->m_flags&CRC_STREAM)!=0) { for (n=0;n<length;n++) { HAL_CRC_COMPUTE(buf[n]); } } } /* encipher ? */ if ((stream->m_flags&CIPHER_STREAM)!=0) { length = BIOS_CIPHER(buf,length,ENCIPHER); } /* write the stream */ if ((stream->m_flags&IO_STREAM)==IO_STREAM) { for (n=0;n<length;n++) { BIOS_SEND(buf[n]); } } else { if ((stream->m_flags2&XRAM_STREAM) == XRAM_STREAM) { #ifdef XPCORE_SIMU LOG("SIMU","Simulator is not able to simulate that (XPTR conversion) !"); HAL_HALT(); #else HAL_MEMCPY(buf,XPTR(stream->m_pos),length); #endif } else { #ifdef JAYA_TRANSACTION if ((stream->m_flags2&TRANS_STREAM) == TRANS_STREAM) { if (BIOS_TRANS_ADD(buf,stream->m_pos,length)==JSEC_FAIL) { BIOS_SETERR(ERR_WRITE_ERROR); return JSEC_FAIL; } } else { #endif if (HAL_EEPROM_WRITE(stream->m_pos,buf,length) != EEPROM_HAL_OK) { BIOS_SETERR(ERR_WRITE_ERROR); return JSEC_FAIL; } #ifdef JAYA_TRANSACTION } #endif } } /* check the write ? */ if ((stream->m_flags&(SECURE_STREAM|IO_STREAM))==SECURE_STREAM) { HAL_VERIFY_EEPROM(buf,stream->m_pos,length); gGlobalSem-=2; } /* unique stream ? */ if ((stream->m_flags&(UNIQUE_STREAM|IO_STREAM))==UNIQUE_STREAM) { HAL_ERASE_XRAM(buf,length); gGlobalSem-=2; } /* update the stream */ stream->m_pos += length; if (gGlobalSem!=JSEC_OK) { HAL_HALT(); return JSEC_FAIL; } return JSEC_OK;}/* ============================================================================ __bios_stream2stream() secure: global semaphore on read/write checking ! note: Ciphered Stream is not unciphered nor re-ciphered during the copy ========================================================================= */jbyte __bios_stream2stream(BIOS_STREAM idata* streamDest,BIOS_STREAM idata* streamSrc,jbyte length){ LOCAL(jbyte,n); LOCAL(jbyte,rlen); LOG3("STREAM","__bios_stream2stream() : streamDest=0x%lX streamSrc=0x%lX length=0x%x",streamSrc,streamDest,length); if (BIOS_TEST_STREAM(streamDest,length)==JSEC_FAIL) return JSEC_FAIL; if (BIOS_TEST_STREAM(streamSrc,length)==JSEC_FAIL) return JSEC_FAIL; if ((streamDest->m_flags&WRITE_STREAM)==0) { BIOS_SETERR(ERR_INVALID_FLAG); HAL_HALT(); return JSEC_FAIL; } if ((streamSrc->m_flags&READ_STREAM)==0) { BIOS_SETERR(ERR_INVALID_FLAG); HAL_HALT(); return JSEC_FAIL; } if ( ((streamDest->m_flags2&INS_IND_STREAM) == INS_IND_STREAM) && ((streamDest->m_flags&IO_STREAM)==IO_STREAM) ) { /* in T=0, indicate the begin to send or receive */ BIOS_SEND_INS(); } do { gGlobalSem = JSEC_OK; rlen = (length<CHUNK_OF_STREAM)?length:CHUNK_OF_STREAM; /* read the source stream */ if ((streamSrc->m_flags&IO_STREAM)==IO_STREAM) { for (n=0;n<rlen;n++) { BIOS_SEND_IINS(); u.bBlock[JAYA_BCRYPTO_STREAM0+n] = BIOS_RECEIVE(); } } else { if ((streamSrc->m_flags2&XRAM_STREAM) == XRAM_STREAM) { #ifdef XPCORE_SIMU LOG("SIMU","Simulator is not able to simulate that (XPTR conversion) !"); HAL_HALT(); #else HAL_MEMCPY(&u.bBlock[JAYA_BCRYPTO_STREAM0],XPTR(streamSrc->m_pos),rlen); #endif } else { HAL_EEPROM_READ(&u.bBlock[JAYA_BCRYPTO_STREAM0],streamSrc->m_pos,rlen); } } /* check the read ? */ if ((streamSrc->m_flags&SECURE_STREAM)!=0) { HAL_VERIFY_EEPROM(&u.bBlock[JAYA_BCRYPTO_STREAM0],streamSrc->m_pos,rlen); gGlobalSem-=2; } /* crc-16 */ if ( ((streamDest->m_flags&CRC_STREAM)!=0) || ((streamSrc->m_flags&CRC_STREAM)!=0)) { for (n=0;n<rlen;n++) { HAL_CRC_COMPUTE(u.bBlock[JAYA_BCRYPTO_STREAM0+n]); } } if ((streamSrc->m_flags&CHKCRC_STREAM)==CHKCRC_STREAM) { if ((HAL_CRC_LO()!=0) || (HAL_CRC_HI()!=0)) { /* bad CRC */ BIOS_SETERR(ERR_INVALID_CRC); return JSEC_FAIL; } } /* decipher ? */ if ((streamSrc->m_flags&CIPHER_STREAM)!=0) { BIOS_CIPHER(&u.bBlock[JAYA_BCRYPTO_STREAM0],rlen,DECIPHER); } /* encipher ? */ if ((streamDest->m_flags&CIPHER_STREAM)!=0) { BIOS_CIPHER(&u.bBlock[JAYA_BCRYPTO_STREAM0],rlen,ENCIPHER); } /* write the stream */ if ((streamDest->m_flags&IO_STREAM)==IO_STREAM) { for (n=0;n<rlen;n++) { BIOS_SEND(u.bBlock[JAYA_BCRYPTO_STREAM0+n]); } } else { if ((streamDest->m_flags2&XRAM_STREAM) == XRAM_STREAM) { #ifdef XPCORE_SIMU LOG("SIMU","Simulator is not able to simulate that (XPTR conversion) !"); HAL_HALT(); #else HAL_MEMCPY(XPTR(streamDest->m_pos),&u.bBlock[JAYA_BCRYPTO_STREAM0],rlen); #endif } else { #ifdef JAYA_TRANSACTION if ((streamDest->m_flags2&TRANS_STREAM) == TRANS_STREAM) { if (BIOS_TRANS_ADD(&u.bBlock[JAYA_BCRYPTO_STREAM0],streamDest->m_pos,rlen)==JSEC_FAIL) { BIOS_SETERR(ERR_WRITE_ERROR); return JSEC_FAIL; } } else { #endif if (HAL_EEPROM_WRITE(streamDest->m_pos,&u.bBlock[JAYA_BCRYPTO_STREAM0],rlen) != EEPROM_HAL_OK) { BIOS_SETERR(ERR_WRITE_ERROR); return JSEC_FAIL; } #ifdef JAYA_TRANSACTION } #endif } } /* check the write ? */ if ((streamDest->m_flags&(SECURE_STREAM|IO_STREAM))==SECURE_STREAM) { HAL_VERIFY_EEPROM(&u.bBlock[JAYA_BCRYPTO_STREAM0],streamDest->m_pos,rlen); gGlobalSem-=2; } /* unique source stream ? */ if ((streamSrc->m_flags&(UNIQUE_STREAM|IO_STREAM))==UNIQUE_STREAM) { HAL_ERASE_EEPROM(streamSrc->m_pos,rlen,0x00); gGlobalSem-=2; } /* unique destination stream ? */ if ((streamDest->m_flags&(UNIQUE_STREAM|IO_STREAM))==UNIQUE_STREAM) { HAL_ERASE_XRAM(&u.bBlock[JAYA_BCRYPTO_STREAM0],rlen); gGlobalSem-=2; } /* update the streams */ streamDest->m_pos += rlen; streamSrc->m_pos += rlen; /* next chunk ? */ if (length<CHUNK_OF_STREAM) break; length -= CHUNK_OF_STREAM; if (length==0) break; if (gGlobalSem!=JSEC_OK) { HAL_HALT(); return JSEC_FAIL; } } while (1); if ((streamDest->m_flags&(IO_STREAM|CHKCRC_STREAM))==(IO_STREAM|CHKCRC_STREAM)) { BIOS_SEND(HAL_CRC_LO()); BIOS_SEND(HAL_CRC_HI()); } return JSEC_OK;}/* ============================================================================ __bios_erase_stream() secure: ? notes: - ========================================================================= */jbyte __bios_erase_stream(BIOS_STREAM idata* stream,jbyte length){ /* stream checking */ if (BIOS_TEST_STREAM(stream,length)==JSEC_FAIL) return JSEC_FAIL; if ((stream->m_flags2&ERASE_STREAM)==0) { LOG("STREAM","__bios_erase_stream() invalid flag !"); BIOS_SETERR(ERR_INVALID_FLAG); HAL_HALT(); return JSEC_FAIL; } gGlobalSem = JSEC_OK; LOG3("STREAM","__bios_erase_stream() : stream=0x%lX read addr=0x%.4x length=0x%.2X",stream,stream->m_pos,length); /* erase the stream */ HAL_ERASE_EEPROM(stream->m_pos,length,0x00); /* update the stream */ stream->m_pos += length; gGlobalSem++; if (gGlobalSem!=JSEC_SEM) { LOG1("ATTACK","__bios_erase_stream() #1 - check security failure ! gGlobalSem=%.2X",gGlobalSem); HAL_HALT(); return JSEC_FAIL; } return JSEC_OK;}/* ========================================================================= That's all folks ! ========================================================================= */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -