📄 commands.c
字号:
/* Simple Operating System for Smartcard Education Copyright (C) 2002 Matthias Bruestle <m@mbsks.franken.de> 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; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*//*! @file \brief Commands. The documentation of the commands is on the main page of the doxygen documentation. $Id: commands.c,v 1.27 2003/03/30 12:42:21 m Exp $*/#include <auth.h>#include <hal.h>#include <commands.h>#include <config.h>#include <crypt.h>#include <fs.h>#include <log.h>#include <stddef.h>#include <string.h>#include <sw.h>#include <t0.h>#include <tools.h>#include <types.h>#ifdef __AVR__#include <io.h>#endif /* __AVR__ *//*! \brief Valid data in response array. Invalid if zero. */iu8 resplen;/*! \brief Data returned by Get Response command. The size of this array is the max. of sizeof(S_FINFO) and CRYPT_BLOCK_LEN.*/iu8 response[8];#if CONF_WITH_TESTCMDS==1void cmd_write( void ){ iu8 b, i; if( t0_testP3( 0x00 ) ) { sw_set( SW_WRONG_LEN ); return; } /* TODO: check for eeprom range */ /* Receive */ for( i=0; i<header[4]; i++ ) { /* ~ACK */ t0_sendCAck(); /* Data */ b = hal_io_recByteT0(); if( !hal_eeprom_write( ((iu16)header[2]<<8)+header[3]+i, &b, 1 ) ) return; } sw_set( SW_OK );}#endif /* CONF_WITH_TESTCMDS==1 */#if CONF_WITH_TESTCMDS==1void cmd_read( void ){ iu16 i, max=header[4]; iu8 b; /* TODO: check for eeprom range */ /* ACK */ t0_sendAck(); if( !max ) max=256; for( i=0; i<max; i++ ) { if( !hal_eeprom_read( &b, (header[2]<<8)+header[3]+i, 1 ) ) return; /* Data */ hal_io_sendByteT0( b ); } /* SW */ sw_set( SW_OK );}#endif /* CONF_WITH_TESTCMDS==1 */#if CONF_WITH_FUNNY==1void cmd_led( void ){ iu8 i; iu8 j; switch( header[2] ) { case 1: hal_led( header[3] ); break; case 2: for( i=0; i<header[3]; i++ ) { hal_led( 0x01 ); for( j=0; j<120; j++ ) { hal_io_sendByteT0( 0x60 ); } hal_led( 0x02 ); for( j=0; j<120; j++ ) { hal_io_sendByteT0( 0x60 ); } hal_led( 0x04 ); for( j=0; j<120; j++ ) { hal_io_sendByteT0( 0x60 ); } hal_led( 0x08 ); for( j=0; j<120; j++ ) { hal_io_sendByteT0( 0x60 ); } hal_led( 0x04 ); for( j=0; j<120; j++ ) { hal_io_sendByteT0( 0x60 ); } hal_led( 0x02 ); for( j=0; j<120; j++ ) { hal_io_sendByteT0( 0x60 ); } } hal_led( 0x01 ); for( j=0; j<120; j++ ) { hal_io_sendByteT0( 0x60 ); } hal_led( 0x00 ); break; default: sw_set( SW_WRONG_P1P2 ); return; } /* SW */ sw_set( SW_OK );}#endif /* CONF_WITH_FUNNY==1 */#if CONF_WITH_PINCMDS==1void cmd_changeUnblockPIN( void ){ iu8 pins[max(PIN_LEN+PIN_LEN,PUK_LEN+PIN_LEN)]; iu8 pin1type;/* This makes no difference with the GCC, but it may with some other compiler. */#if ((PIN_LEN)==(PUK_LEN))#define pinssize (PIN_LEN+PIN_LEN)#define pin1len PIN_LEN#else iu8 pinssize, pin1len;#endif switch( header[1] ) { case INS_UNBLOCK_PIN:#if PIN_LEN!=PUK_LEN pinssize=PUK_LEN+PIN_LEN; pin1len=PUK_LEN;#endif pin1type=PIN_TYPE_PUK; break; default:#if PIN_LEN!=PUK_LEN pinssize=PIN_LEN+PIN_LEN; pin1len=PIN_LEN;#endif pin1type=PIN_TYPE_PIN; break; } if( !t0_testP3( pinssize ) ) return; if( !t0_testP1P2( 0x0000 ) ) return; /* ACK */ t0_sendAck(); /* Receive */ t0_recBlock( pins, pinssize ); if( !( auth_verifyPin( pin1type, pins, pin1len ) && auth_setPin( PIN_TYPE_PIN, pins+pin1len, PIN_LEN ) ) ) return; sw_set( SW_OK );}#endif /* CONF_WITH_PINCMDS==1 */#if CONF_WITH_CREATECMD==1void cmd_create( void ){ S_FSTREAM fs; S_FINFO fi; if( !t0_testP3( sizeof(S_FINFO) ) ) return; if( !t0_testP1P2( 0x0000 ) ) return; /* Get DF data */ if( !fs_getData( &selected, &fs, &fi ) ) return; /* Correct DF type? */ if( fi.type!=FS_TYPE_DF ) { sw_set( SW_NOT_ALLOWED ); return; } /* Correct permissions? */ if( !auth_checkAc( (fi.ac[0]>>4)&0x0F ) ) return; /* ACK */ t0_sendAck(); /* Receive */ t0_recBlock( (iu8 *)&fi, sizeof(S_FINFO) ); hton_us( &fi.size, 1 ); hton_us( &fi.fid, 1 ); if( !fs_create( &fi ) ) return; sw_set( SW_OK );}#endif /* CONF_WITH_CREATECMD==1 */#if CONF_WITH_DELETECMD==1void cmd_delete( void ){ S_FSTREAM fs; S_FINFO fi; iu16 fid; iu8 b; if( !t0_testP3( sizeof(iu16) ) ) return; if( !t0_testP1P2( 0x0000 ) ) return; /* Get DF data */ if( !fs_getData( &selected, &fs, &fi ) ) return; /* Correct DF type? */ if( fi.type!=FS_TYPE_DF ) { sw_set( SW_NOT_ALLOWED ); return; } /* Correct permissions? */ if( !auth_checkAc( fi.ac[0]&0x0F ) ) return; /* ACK */ t0_sendAck(); /* Data */ b = hal_io_recByteT0(); fid=b<<8; b = hal_io_recByteT0(); fid+=b; if( !fs_delete( fid ) ) return; sw_set( SW_OK );}#endif /* CONF_WITH_DELETECMD==1 */#if CONF_WITH_KEYCMDS==1void cmd_extAuth( void ){ iu8 cry[8]; if( !t0_testP3( CRYPT_BLOCK_LEN ) ) return; if( !t0_testP1P2( 0x0000 ) ) return; /* ACK */ t0_sendAck(); /* Receive */ t0_recBlock( cry, sizeof(cry) ); if( !auth_createVerifyCryptogram( cry, sizeof(cry), FALSE, 0 ) ) return; sw_set( SW_OK );}#endif /* CONF_WITH_KEYCMDS==1 */#if CONF_WITH_KEYCMDS==1void cmd_getChallenge( void ){ iu8 i, buf[CRYPT_BLOCK_LEN]; if( !t0_testP3( CRYPT_BLOCK_LEN ) ) return; if( !t0_testP1P2( 0x0000 ) ) return; auth_getChallenge( buf, sizeof(buf) ); /* ACK */ t0_sendAck(); for( i=0; i<sizeof(buf); i++ ) { /* Data */ hal_io_sendByteT0( buf[i] ); } /* SW */ sw_set( SW_OK );}#endif /* CONF_WITH_KEYCMDS==1 */void cmd_getResponse( void ){ iu8 i; if( resplen==0 ) { sw_set( SW_WRONG_CONDITION ); return; } if( !t0_testP3( resplen ) ) { if( (header[4]>resplen) || (!header[4]) ) { sw_set( SW_WRONG_LE|resplen ); return; } /* User want's not all data */ resplen=header[4]; } if( !t0_testP1P2( 0x0000 ) ) return; /* ACK */ t0_sendAck(); /* Data */ for( i=0; i<resplen; i++ ) { hal_io_sendByteT0( response[i] ); } sw_set( SW_OK );}#if CONF_WITH_KEYCMDS==1void cmd_intAuth( void ){ bool enc=TRUE; if( !t0_testP3( CRYPT_BLOCK_LEN ) ) return;#if CONF_WITH_DECRYPT==1 if( !t0_testP1P2( 0x0000 ) && !t0_testP1P2( 0x0001 ) ) return; if( header[3]&0x01 ) enc=FALSE;#else /* CONF_WITH_DECRYPT!=1 */ if( !t0_testP1P2( 0x0000 ) ) return;#endif /* CONF_WITH_DECRYPT!=1 */ /* ACK */ t0_sendAck(); /* Receive */ t0_recBlock( response, CRYPT_BLOCK_LEN ); if( !auth_createVerifyCryptogram( response, CRYPT_BLOCK_LEN, TRUE, enc ) ) { resplen=0; return; } resplen=CRYPT_BLOCK_LEN; sw_set( SW_AVAILABLE|CRYPT_BLOCK_LEN );}#endif /* CONF_WITH_KEYCMDS==1 */void cmd_readBinary( void ){ S_FSTREAM fs; S_FINFO fi; iu16 i, max=header[4]; iu8 b; /* Get file data */ if( !fs_getData( &selected, &fs, &fi ) ) return; /* Correct file type? */ if( fi.type!=FS_TYPE_EF ) { sw_set( SW_NOT_ALLOWED ); return; } /* Correct permissions? */ if( !auth_checkAc( fi.ac[0]&0x0F ) ) return; if( !max ) max=256; /* Test file size */ fs.pos=((iu16)header[2]<<8)|header[3]; if(fs.pos>fs.size) { sw_set( SW_WRONG_REFERENCE ); return; } if( !fstream_test( &fs, max ) ) return; /* ACK */ t0_sendAck(); for( i=0; i<max; i++ ) { if( !fstream_read( &fs, &b, 1 ) ) return; /* Data */ hal_io_sendByteT0( b ); } sw_set( SW_OK );}void cmd_select( void ){ S_FPATH fp; S_FINFO *fi=(S_FINFO*)response; iu16 fid; iu8 b; if( !t0_testP3( sizeof(iu16) ) ) return; if( !t0_testP1P2( 0x0000 ) ) return; /* ACK */ t0_sendAck(); /* Data */ b = hal_io_recByteT0(); fid=b<<8; b = hal_io_recByteT0(); fid+=b; if( !fs_getFPath( fid, &fp, NULL, fi ) ) return; memcpy( &selected, &fp, sizeof(S_FPATH) ); resplen=sizeof(S_FINFO); hton_us( &(fi->size), 1 ); hton_us( &(fi->fid), 1 ); sw_set( SW_AVAILABLE|sizeof(S_FINFO) );}void cmd_updateBinary( void ){ S_FSTREAM fs; S_FINFO fi; iu16 i; iu8 b; if( t0_testP3( 0x00 ) ) { sw_set( SW_WRONG_LEN ); return; } /* Get file data */ if( !fs_getData( &selected, &fs, &fi ) ) return; /* Correct file type? */ if( fi.type!=FS_TYPE_EF ) { sw_set( SW_NOT_ALLOWED ); return; } /* Correct permissions? */ if( !auth_checkAc( (fi.ac[0]>>4)&0x0F ) ) return; /* Test file size */ fs.pos=((iu16)header[2]<<8)|header[3]; if(fs.pos>fs.size) { sw_set( SW_WRONG_REFERENCE ); return; } if( !fstream_test( &fs, header[4] ) ) return; /* Receive */ for( i=0; i<header[4]; i++ ) { /* ~ACK */ t0_sendCAck(); /* Data */ b = hal_io_recByteT0(); if( !fstream_write( &fs, &b, 1 ) ) return; } sw_set( SW_OK );}#if 0#if CONF_WITH_KEYCMDS==1void cmd_verifyKey( void ){ iu8 key[ADM_KEY_LEN]; if( !t0_testP3( sizeof(key) ) ) return; if( !t0_testP1P2( 0x0000 ) ) return; /* ACK */ t0_sendAck(); /* Receive */ t0_recBlock( key, sizeof(key) ); if( !auth_verifyPin( PIN_TYPE_EXT, key, sizeof(key) ) ) return; sw_set( SW_OK );}#endif /* CONF_WITH_KEYCMDS==1 */#if CONF_WITH_PINCMDS==1void cmd_verifyPIN( void ){ iu8 pin[PIN_LEN]; if( !t0_testP3( sizeof(pin) ) ) return; if( !t0_testP1P2( 0x0000 ) ) return; /* ACK */ t0_sendAck(); /* Receive */ t0_recBlock( pin, sizeof(pin) ); if( !auth_verifyPin( PIN_TYPE_PIN, pin, sizeof(pin) ) ) return; sw_set( SW_OK );}#endif /* CONF_WITH_PINCMDS==1 */#endif#if (CONF_WITH_KEYCMDS==1) || (CONF_WITH_PINCMDS==1)void cmd_verifyKeyPIN( void ){ iu8 buf[(ADM_KEY_LEN>PIN_LEN)?ADM_KEY_LEN:PIN_LEN]; iu8 len, type; switch( header[1] ) { case INS_VERIFY_KEY: type=PIN_TYPE_EXT; len=16; break; default: type=PIN_TYPE_PIN; len=PIN_LEN; } if( !t0_testP3( len ) ) return; if( !t0_testP1P2( 0x0000 ) ) return; /* ACK */ t0_sendAck(); /* Receive */ t0_recBlock( buf, len ); if( !auth_verifyPin( type, buf, len ) ) return; sw_set( SW_OK );}#endif /* (CONF_WITH_KEYCMDS==1) || (CONF_WITH_PINCMDS==1) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -