2016-04-09 4 views
0

Ich baue ein Projekt auf Java Card mit Java Card 2.1.2 SDK und GPShell als die Art der Kommunikation mit dem Gerät. Ich testete das helloworld Beispiel von GpShell und ich verwaltet Simple APDU senden. Jedoch wenn ich versuche, APDU zu einer größeren .cap Datei zu senden gibt das Gerät mir die folgenden FehlerJava Card Ein Kommunikationsfehler mit der Smartcard wurde festgestellt

send_APDU() returns 0x8010002F (A communications error with the smart card has b 
een detected. Retry the operation. 
) 

Ich legte Teile des Codes aus dem Applet below.It ein Speicherproblem scheint mich, obwohl Java Card verfügt über 80 Kb EEPROM und fast 2 Kb RAM. Im Eclipse-Simulator funktioniert die Anwendung gut.

TwineCipher.java

public class TwineCipher implements IConsts{ 

    /** 
    * The 80 bits of cipher twine 
    */ 

    public static final short MAX_MEMORY_TEMPORARY=32; 
    private static TwineCipher ref_twineCipher_80 = null; 
    private static TwineCipher ref_twineCipher_128 = null; 

    public byte[] temp = JCSystem.makeTransientByteArray(MAX_MEMORY_TEMPORARY,JCSystem.CLEAR_ON_DESELECT); 
    public byte[] rk = JCSystem.makeTransientByteArray((short) ((short)36*8),JCSystem.CLEAR_ON_DESELECT); 

    private static byte [] roundconst = 
     { 
       0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x23, 0x05, 0x0a, 0x14, 0x28, 0x13, 0x26, 
       0x0f, 0x1e, 0x3c, 0x3b, 0x35, 0x29, 0x11, 0x22, 0x07, 0x0e, 0x1c, 0x38, 0x33, 0x25, 0x09, 0x12, 0x24, 0x0b, 
     }; 

    private static short [] shufinv = {1, 2, 11, 6, 3, 0, 9, 4, 7, 10, 13, 14, 5, 8, 15, 12}; 
    private static short [] shuf = { 5, 0, 1, 4, 7, 12, 3, 8, 13, 6, 9, 2, 15, 10, 11, 14}; 
    private static byte [] sbox = {0x0C, 0x00, 0x0F, 0x0A, 0x02, 0x0B, 0x09, 0x05, 0x08, 0x03, 0x0D, 0x07, 0x01, 0x0E, 0x06, 0x04}; 
    private static byte [] data_enc = new byte[16]; 

    public static TwineCipher getInstance(byte type,byte[] key) 
    { 
     switch(type) 
     { 
      case TWINE_CIPHER_80: 
       if(ref_twineCipher_80 != null) 
        return ref_twineCipher_80; 
       ref_twineCipher_80 = new TwineCipher(key,TWINE_CIPHER_80); 
       return ref_twineCipher_80; 
      case TWINE_CIPHER_128: 
       if(ref_twineCipher_128 != null) 
        return ref_twineCipher_128; 
       ref_twineCipher_128 = new TwineCipher(key,TWINE_CIPHER_128); 
       return ref_twineCipher_128; 
      default: 
       ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED); 
     } 
     ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED); 
     return null; 
    } 

    public static TwineCipher getInstance(byte type) 
    { 
     switch(type) 
     { 
      case TWINE_CIPHER_80: 
       if(ref_twineCipher_80 != null) 
        return ref_twineCipher_80; 
       ref_twineCipher_80 = new TwineCipher(); 
       return ref_twineCipher_80; 
      case TWINE_CIPHER_128: 
       if(ref_twineCipher_128 != null) 
        return ref_twineCipher_128; 
       ref_twineCipher_128 = new TwineCipher(); 
       return ref_twineCipher_128; 
      default: 
       ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED); 
     } 
     ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED); 
     return null; 
    } 
    private TwineCipher(byte[] key,byte keySize) 
    { 
     switch(keySize) 
     { 
      case TWINE_CIPHER_80: 
       expand80Key(key); 
       break; 
      case TWINE_CIPHER_128: 
       expand128Key(key); 
       break; 
      default: 
       ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); 
     } 
    } 
    private TwineCipher() 
    { 

    } 

    private void expand80Key(byte[] key) 
    { 
     short len_x = 20; 
     short key_size = 10; 
     short iterator = 0,iterator2=0;; 
     byte temp_val=-1; 
     byte temp_val2=-1,temp_val3=-1,temp_val4=-1; 
     short sh=0; 
     // reset the array 
     Util.arrayFillNonAtomic(temp, (short)0, (short)20, IConsts.UNTOUCHED_VALUE); 

     unrowl80ExpandKey(key); 

     for (iterator = 0 ; iterator < 35;iterator ++) 
     { 
      rk[(short)(iterator * 8 + 0)] = temp[1]; 
      rk[(short)(iterator * 8 + 1)] = temp[3]; 
      rk[(short)(iterator * 8 + 2)] = temp[4]; 
      rk[(short)(iterator * 8 + 3)] = temp[6]; 
      rk[(short)(iterator * 8 + 4)] = temp[13]; 
      rk[(short)(iterator * 8 + 5)] = temp[14]; 
      rk[(short)(iterator * 8 + 6)] = temp[15]; 
      rk[(short)(iterator * 8 + 7)] = temp[16]; 

      temp[1] ^= sbox[temp[0]]; 
      temp[4] ^= sbox[temp[16]]; 
      temp_val = roundconst[iterator]; 
      temp[7] ^= temp_val >> 3; 
      temp[19] ^= temp_val & 7; 

      temp_val = temp[0]; 
      temp_val2 = temp[1]; 
      temp_val3 = temp[2]; 
      temp_val4 = temp[3]; 

      for (iterator2 = 0 ; iterator2 < 4;iterator2++) 
      { 
       sh     = (short)(iterator2*4); 
       temp[sh]   = temp[(short)(sh+4)]; 
       temp[(short)(sh+1)] = temp[(short)(sh+5)]; 
       temp[(short)(sh+2)] = temp[(short)(sh+6)]; 
       temp[(short)(sh+3)] = temp[(short)(sh+7)]; 
      } 

      temp[16] = temp_val2; 
      temp[17] = temp_val3; 
      temp[18] = temp_val4; 
      temp[19] = temp_val; 

     } 
     rk[(short)(35 * 8 + 0)] = temp[1]; 
     rk[(short)(35 * 8 + 1)] = temp[3]; 
     rk[(short)(35 * 8 + 2)] = temp[4]; 
     rk[(short)(35 * 8 + 3)] = temp[6]; 
     rk[(short)(35 * 8 + 4)] = temp[13]; 
     rk[(short)(35 * 8 + 5)] = temp[14]; 
     rk[(short)(35 * 8 + 6)] = temp[15]; 
     rk[(short)(35 * 8 + 7)] = temp[16]; 

    } 
    private void expand128Key(byte[] key) 
    { 

    } 

    public byte[] encrypt(byte[] src,byte[] dest,short len_src) 
    { 
     Util.arrayFillNonAtomic(temp, (short)0, (short)32, IConsts.UNTOUCHED_VALUE); //reset all values 
                // 16 bytes for first part 
                // 16 bytes for next 
     short iterator=0,iterator2=0,iterator3=0; 
     short START_ITERATOR = 16; 
     for(iterator = 0 ; iterator < len_src ; iterator++) 
     { 
      temp[(short)(2*iterator)] = (byte)((short) (src[iterator] & 0x00FF) >> 4); 
      temp[(short)(2*iterator+1)] = (byte)((short) (src[iterator] & 0x00FF) & 0x0F); 
     } 

     for (iterator = 0 ; iterator < 35 ; iterator ++) 
     { 
      for (iterator2 = 0 ; iterator2 < 8 ; iterator2 ++) 
      { 
       temp[(short)(2*iterator2+1)] ^= sbox[temp[(short)(2*iterator2)]^rk[(short)(iterator*8+iterator2)]]; 

      } 

      for (iterator3 = 0 ; iterator3 < 16;iterator3++) 
      { 
       temp[(short)(shuf[iterator3]+16)] = temp[(short)(iterator3)]; 
      } 
      Util.arrayCopy(temp, (short)16, temp, (short)0, (short)16); 
     } 
     iterator = 35; 
     for (iterator2 = 0; iterator2 < 8 ;iterator2++) 
     { 
      temp[(short)(2*iterator2+1)] ^= sbox[temp[(short)(2*iterator2)]^ rk[(short)(iterator*8+iterator2)]];   
     } 

     for (iterator = 0 ;iterator < 8 ;iterator++) 
     { 
      temp[(short)(24+iterator)] = (byte)(temp[(short)(2*iterator)] << 4 | temp[(short)(2*iterator + 1)]); 
     } 
     Util.arrayCopy(temp, (short)24, dest, (short)(ISO7816.OFFSET_CDATA), (short)8); 
     return temp; // returns bytes from 24 to 32 
    } 
    public byte[] decrypt(byte[] src,byte[] dest,short len_src) 
    { 
     // for this alg len_src is always 8 
     Util.arrayFillNonAtomic(temp, (short)0, (short)32, IConsts.UNTOUCHED_VALUE); //reset all values 
     short iterator=0,iterator2=0,iterator3=0; 
     short START_ITERATOR = 16; 
     for(iterator = 0 ; iterator < len_src ; iterator++) 
     { 
      temp[(short)(2*iterator)] = (byte)((short) (src[iterator] & 0x00FF) >> 4); 
      temp[(short)(2*iterator+1)] = (byte)((short) (src[iterator] & 0x00FF) & 0x0F); 
     } 

     for (iterator = 35 ; iterator > 0 ; iterator --) 
     { 
      for (iterator2 = 0 ; iterator2 < 8 ; iterator2 ++) 
      { 
       temp[(short)(2*iterator2+1)] ^= sbox[temp[(short)(2*iterator2)]^ rk[(short)(iterator*8+iterator2)]]; 
      } 

      for (iterator3 = 0 ; iterator3 < 16;iterator3++) 
      { 
       temp[(short)(shufinv[iterator3]+16)] = temp[(short)(iterator3)]; 
      } 
      Util.arrayCopy(temp, (short)16, temp, (short)0, (short)16); 
     } 
     //FINAL 
     iterator = 0; 
     for (iterator2 = 0; iterator2 < 8 ;iterator2++) 
     { 
      temp[(short)(2*iterator2+1)] ^= sbox[temp[(short)(2*iterator2)]^ rk[(short)(iterator*8+iterator2)]]; 
     } 

     for (iterator = 0 ;iterator < 8 ;iterator++) 
     { 
      temp[(short)(24+iterator)] = (byte)(temp[(short)(2*iterator)] << 4 | temp[(short)(2*iterator + 1)]); 
     } 
     Util.arrayCopy(temp, (short)24, dest, (short)(ISO7816.OFFSET_CDATA), (short)8); 
     return temp; // returns bytes from 24 to 32 indexes 
    } 

    public short process(byte type,byte[] data,short start_offset,short len_data) 
    { 
     Util.arrayCopy(data, start_offset, data_enc, (short) 0, len_data); 
     switch(type) 
     { 
      case OFFSET_P1_ENC: 
       encrypt(data_enc, data, len_data); 
       return (short)8; 
      case OFFSET_P1_DEC: 
       decrypt(data_enc, data, len_data); 
       return (short)8; 
      case OFFSET_P1_GEN: 
       expand80Key(data_enc); 
       return 10; 
      default: 
       return (short)-1; 
     } 

    } 

    private void unrowl80ExpandKey(byte[] key) 
    { 
     temp[(short)(2*0)] = (byte)((short) (key[0] & 0x00FF) >> 4); 
     temp[(short)(2*0 + 1)] = (byte)((short) (key[0] & 0x00FF) & 0x0F); 

     temp[(short)(2*1)] = (byte)((short) (key[1] & 0x00FF) >> 4); 
     temp[(short)(2*1 + 1)] = (byte)((short) (key[1] & 0x00FF) & 0x0F); 

     temp[(short)(2*2)] = (byte)((short) (key[2] & 0x00FF) >> 4); 
     temp[(short)(2*2 + 1)] = (byte)((short) (key[2] & 0x00FF) & 0x0F); 

     temp[(short)(2*3)] = (byte)((short) (key[3] & 0x00FF) >> 4); 
     temp[(short)(2*3 + 1)] = (byte)((short) (key[3] & 0x00FF) & 0x0F); 

     temp[(short)(2*4)] = (byte)((short) (key[4] & 0x00FF) >> 4); 
     temp[(short)(2*4 + 1)] = (byte)((short) (key[4] & 0x00FF) & 0x0F); 

     temp[(short)(2*5)] = (byte)((short) (key[5] & 0x00FF) >> 4); 
     temp[(short)(2*5 + 1)] = (byte)((short) (key[5] & 0x00FF) & 0x0F); 

     temp[(short)(2*6)] = (byte)((short) (key[6] & 0x00FF) >> 4); 
     temp[(short)(2*6 + 1)] = (byte)((short) (key[6] & 0x00FF) & 0x0F); 

     temp[(short)(2*7)] = (byte)((short) (key[7] & 0x00FF) >> 4); 
     temp[(short)(2*7 + 1)] = (byte)((short) (key[7] & 0x00FF) & 0x0F); 

     temp[(short)(2*8)] = (byte)((short) (key[8] & 0x00FF) >> 4); 
     temp[(short)(2*8 + 1)] = (byte)((short) (key[8] & 0x00FF) & 0x0F); 

     temp[(short)(2*9)] = (byte)((short) (key[9] & 0x00FF) >> 4); 
     temp[(short)(2*9 + 1)] = (byte)((short) (key[9] & 0x00FF) & 0x0F); 
    } 
} 

IConst.java Schnittstelle

public interface IConsts 
{ 
    public static final byte UNTOUCHED_VALUE = 0x50; 
    public static final byte TRUE = 0x01; 
    public static final byte FALSE = 0x00; 

    public static final byte OFFSET_CLA_CIPHERS = (byte) 0x00; 
    public static final byte OFFSET_INS_LIGHT = (byte) 0x11; 


    public static final byte OFFSET_P1_ENC = (byte) 0x21; 
    public static final byte OFFSET_P1_DEC = (byte) 0x22; 
    public static final byte OFFSET_P1_GEN = (byte) 0x23; 

    public static final byte TWINE_CIPHER_80=0x30; 
    public static final byte TWINE_CIPHER_128=0x31; 
    public static final byte LBLOCK_CIPHER=0x32; 
} 

LBlockCipher.java 

    public class LBlockCipher implements IConsts { 


    public static final byte LBLOCK_NBROUNDS = 32; 
    public static final byte LBLOCK_KEY_SIZE = 80; 
    public static final short MEMORY_OUTPUT=32*4; 
    public static final short MEMORY_TEMPORARY=32; 

    static final byte[] S0 = { 14, 9, 15, 0, 13, 4, 10, 11, 1, 2, 8, 3, 7, 6, 12, 5}; 
    static final byte[] S1 = { 4, 11, 14, 9, 15, 13, 0, 10, 7, 12, 5, 6, 2, 8, 1, 3 }; 
    static final byte[] S2 = { 1, 14, 7, 12, 15, 13, 0, 6, 11, 5, 9, 3, 2, 4, 8, 10 }; 
    static final byte[] S3 = { 7, 6, 8, 11, 0, 15, 3, 14, 9, 10, 12, 13, 5, 2, 4, 1 }; 
    static final byte[] S4 = { 14, 5, 15, 0, 7, 2, 12, 13, 1, 8, 4, 9, 11, 10, 6, 3 }; 
    static final byte[] S5 = { 2, 13, 11, 12, 15, 14, 0, 9, 7, 10, 6, 3, 1, 8, 4, 5 }; 
    static final byte[] S6 = { 11, 9, 4, 14, 0, 15, 10, 13, 6, 12, 5, 7, 3, 8, 1, 2 }; 
    static final byte[] S7 = { 13, 10, 15, 0, 14, 4, 9, 11, 2, 1, 8, 3, 7, 5, 12, 6 }; 
    static final byte[] S8 = { 8, 7, 14, 5, 15, 13, 0, 6, 11, 12, 9, 10, 2, 4, 1, 3 }; 
    static final byte[] S9 = { 11, 5, 15, 0, 7, 2, 9, 13, 4, 8, 1, 12, 14, 10, 3, 6 }; 

    public byte[] output = JCSystem.makeTransientByteArray(MEMORY_OUTPUT,JCSystem.CLEAR_ON_DESELECT); 
    public byte[] temp  = JCSystem.makeTransientByteArray(MEMORY_TEMPORARY,JCSystem.CLEAR_ON_DESELECT); 

    private static LBlockCipher m_instance_Cipher = null; 

    public void keySchedule(byte[] key,short start_offset) 
    { 
     // use for keyR offset temp [0 - 3 ] 
     short i = 0 ; 
     output[(short)(0*4+3)] = key[(short)(9 + start_offset)]; 
     output[(short)(0*4+2)] = key[(short)(8 + start_offset)]; 
     output[(short)(0*4+1)] = key[(short)(7 + start_offset)]; 
     output[(short)(0*4+0)] = key[(short)(6 + start_offset)]; 

     for (i = 1;i<32;i++) 
     { 
      temp[3] = key[(short)(9 + start_offset)]; 
      temp[2] = key[(short)(8 + start_offset)]; 
      temp[1] = key[(short)(7 + start_offset)]; 
      temp[0] = key[(short)(6 + start_offset)]; 

      key[(short)(9 + start_offset)] = (byte) ((((key[(short)(6 + start_offset)] & 0x07) << 5) 
              & 0xE0)^(((key[(short)(5 + start_offset)] & 0xF8) >> 3) & 0x1F)); 
      key[(short)(8 + start_offset)] = (byte) ((((key[(short)(5 + start_offset)] 
              & 0x07) << 5) & 0xE0)^(((key[(short)(4 + start_offset)] & 0xF8) >> 3) & 0x1F)); 
      key[(short)(7 + start_offset)] = (byte) ((((key[(short)(4 + start_offset)] 
              & 0x07) << 5) & 0xE0)^(((key[(short)(3 + start_offset)] & 0xF8) >> 3) & 0x1F)); 
      key[(short)(6 + start_offset)] = (byte) ((((key[(short)(3 + start_offset)] 
              & 0x07) << 5) & 0xE0)^(((key[(short)(2 + start_offset)] & 0xF8) >> 3) & 0x1F)); 
      key[(short)(5 + start_offset)] = (byte) ((((key[(short)(2 + start_offset)] & 0x07) << 5) 
              & 0xE0)^(((key[(short)(1 + start_offset)] & 0xF8) >> 3) & 0x1F)); 

      key[(short)(4 + start_offset)] = (byte) ((((key[(short)(1 + start_offset)] & 0x07) << 5) 
              & 0xE0)^(((key[(short)(0 + start_offset)] & 0xF8) >> 3) & 0x1F)); 
      key[(short)(3 + start_offset)] = (byte) ((((key[(short)(0 + start_offset)] & 0x07) << 5) 
              & 0xE0)^(((temp[3] & 0xF8) >> 3) & 0x1F)); 
      key[(short)(2 + start_offset)] = (byte) ((((temp[3] & 0x07) << 5) & 0xE0)^(((temp[2] & 0xF8) >> 3) & 0x1F)); 
      key[(short)(1 + start_offset)] = (byte) ((((temp[2] & 0x07) << 5) & 0xE0)^(((temp[1] & 0xF8) >> 3) & 0x1F)); 
      key[(short)(0 + start_offset)] = (byte) ((((temp[1] & 0x07) << 5) & 0xE0)^(((temp[0] & 0xF8) >> 3) & 0x1F)); 

      key[(short)(9 + start_offset)] = (byte) ((S9[((key[(short)(9 + start_offset)] >> 4) & 0x0F)] << 4) 
              ^S8[(key[(short)(9 + start_offset)] & 0x0F)]); 

      key[(short)(6 + start_offset)] = (byte) (key[(short)(6 + start_offset)]^((i >> 2) & 0x07)); 
      key[(short)(5 + start_offset)] = (byte) (key[(short)(5 + start_offset)]^((i & 0x03) << 6)); 

      output[(short)(i*4 + 3)] = key[(short)(9 + start_offset)]; 
      output[(short)(i*4 + 2)] = key[(short)(8 + start_offset)]; 
      output[(short)(i*4 + 1)] = key[(short)(7 + start_offset)]; 
      output[(short)(i*4 + 0)] = key[(short)(6 + start_offset)];; 
     } 
    } 
    public void OneRound(byte[] x,byte[] k,short offset,short offset_x) 
    { 
     // t - from 5 - 8 tmp from 9 to 12 
     // u8 t[4], tmp[4]; 

     temp[9] = x[(short)(4 + offset_x)]; 
     temp[10] = x[(short)(5 + offset_x)]; 
     temp[11] = x[(short)(6 + offset_x)]; 
     temp[12] = x[(short)(7 + offset_x)]; 

     x[(short)(4 + offset_x)] ^= k[offset]; 
     x[(short)(5 + offset_x)] ^= k[(short)(offset+1)]; 
     x[(short)(6 + offset_x)] ^= k[(short)(offset+2)]; 
     x[(short)(7 + offset_x)] ^= k[(short)(offset+3)]; 

     x[(short)(4 + offset_x)] = (byte) (((S1[((x[(short)(4 + offset_x)]) >> 4) & 0x0F]) << 4) 
           ^S0[(x[(short)(4 + offset_x)] & 0x0F)]); 
     x[(short)(5 + offset_x)] = (byte) (((S3[((x[(short)(5 + offset_x)]) >> 4) & 0x0F]) << 4) 
           ^S2[(x[(short)(5 + offset_x)] & 0x0F)]); 
     x[(short)(6 + offset_x)] = (byte) (((S5[((x[(short)(6 + offset_x)]) >> 4) & 0x0F]) << 4) 
           ^S4[(x[(short)(6 + offset_x)] & 0x0F)]); 
     x[(short)(7 + offset_x)]= (byte) (((S7[((x[(short)(7 + offset_x)]) >> 4) & 0x0F]) << 4) 
           ^S6[(x[(short)(7 + offset_x)] & 0x0F)]); 

     temp[5] = (byte) (((x[(short)(4 + offset_x)] >> 4) & 0x0F)^(x[(short)(5 + offset_x)] & 0xF0)); 
     temp[6] = (byte) ((x[(short)(4 + offset_x)] & 0x0F)^((x[(short)(5 + offset_x)] & 0x0F) << 4)); 
     temp[7] = (byte) (((x[(short)(6 + offset_x)] >> 4) & 0x0F)^(x[(short)(7 + offset_x)] & 0xF0)); 
     temp[8] = (byte) ((x[(short)(6 + offset_x)] & 0x0F)^((x[(short)(7 + offset_x)] & 0x0F) << 4)); 

     x[(short)(4 + offset_x)] = (byte) (x[(short)(3 + offset_x)]^temp[5]); 
     x[(short)(5 + offset_x)] = (byte) (x[(short)(0 + offset_x)]^temp[6]); 
     x[(short)(6 + offset_x)] = (byte) (x[(short)(1 + offset_x)]^temp[7]); 
     x[(short)(7 + offset_x)] = (byte) (x[(short)(2 + offset_x)]^temp[8]); 

     x[(short)(0 + offset_x)] = temp[9]; 
     x[(short)(1 + offset_x)] = temp[10]; 
     x[(short)(2 + offset_x)] = temp[11]; 
     x[(short)(3 + offset_x)] = temp[12]; 


    } 
    public void encrypt(byte[] x,short offset_x) 
    { 
     short i; 
     for (i = 0; i<32; i++) 
     { 
      OneRound(x,output,(short)(4*i),offset_x); 
     } 
    } 
    public void OneRoundInv(byte[] y, byte[] k,short offset,short offset_y) 
    { 
     // t - from 5 - 8 tmp from 9 to 12 
     // u8 t[4], tmp[4]; 

     temp[9] = y[(short)(0 + offset_y)]; 
     temp[10] = y[(short)(1 + offset_y)]; 
     temp[11] = y[(short)(2 + offset_y)]; 
     temp[12] = y[(short)(3 + offset_y)]; 

     y[(short)(0 + offset_y)] = (byte) (y[(short)(0 + offset_y)]^k[offset]); 
     y[(short)(1 + offset_y)] = (byte) (y[(short)(1 + offset_y)]^k[(short)(offset+1)]); 
     y[(short)(2 + offset_y)] = (byte) (y[(short)(2 + offset_y)]^k[(short)(offset+2)]); 
     y[(short)(3 + offset_y)] = (byte) (y[(short)(3 + offset_y)]^k[(short)(offset+3)]); 


     y[(short)(0 + offset_y)] = (byte) (((S1[((y[(short)(0 + offset_y)]) >> 4) & 0x0F]) << 4)^S0[(y[(short)(0 + offset_y)] & 0x0F)]); 
     y[(short)(1 + offset_y)] = (byte) (((S3[((y[(short)(1 + offset_y)]) >> 4) & 0x0F]) << 4)^S2[(y[(short)(1 + offset_y)] & 0x0F)]); 
     y[(short)(2 + offset_y)] = (byte) (((S5[((y[(short)(2 + offset_y)]) >> 4) & 0x0F]) << 4)^S4[(y[(short)(2 + offset_y)] & 0x0F)]); 
     y[(short)(3 + offset_y)] = (byte) (((S7[((y[(short)(3 + offset_y)]) >> 4) & 0x0F]) << 4)^S6[(y[(short)(3 + offset_y)] & 0x0F)]); 


     temp[5] = (byte) (((y[(short)(0 + offset_y)] >> 4) & 0x0F)^(y[(short)(1 + offset_y)] & 0xF0)); 
     temp[6] = (byte) ((y[(short)(0 + offset_y)] & 0x0F)^((y[(short)(1 + offset_y)] & 0x0F) << 4)); 
     temp[7] = (byte) (((y[(short)(2 + offset_y)] >> 4) & 0x0F)^(y[(short)(3 + offset_y)] & 0xF0)); 
     temp[8] = (byte) ((y[(short)(2 + offset_y)] & 0x0F)^((y[(short)(3 + offset_y)] & 0x0F) << 4)); 

     y[(short)(0 + offset_y)] = (byte) (y[(short)(5 + offset_y)]^temp[6]); 
     y[(short)(1 + offset_y)] = (byte) (y[(short)(6 + offset_y)]^temp[7]); 
     y[(short)(2 + offset_y)] = (byte) (y[(short)(7 + offset_y)]^temp[8]); 
     y[(short)(3 + offset_y)] = (byte) (y[(short)(4 + offset_y)]^temp[5]); 

     // PARTIE GAUCHE 
     y[(short)(4 + offset_y)] = temp[9]; 
     y[(short)(5 + offset_y)] = temp[10]; 
     y[(short)(6 + offset_y)] = temp[11]; 
     y[(short)(7 + offset_y)] = temp[12]; 


    } 
    public void decrypt(byte[] x,short offset_x) 
    { 
     short i; 

     for (i = 31; i >= 0; i--) 
     { 
      OneRoundInv(x,output,(short)(i*4),offset_x); 
     } 
    } 

    private LBlockCipher() 
    { 

    } 
    public short process(byte type,byte[] data,short start_offset,short len_data) 
    { 
     Util.arrayCopy(data, start_offset, temp, (short) 16, len_data); 
     switch(type) 
     { 
      case OFFSET_P1_ENC: 
       encrypt(temp,(short)(16)); 
       Util.arrayCopy(temp,(short) 16, data, (short) start_offset, len_data); 
       return (short)8; 
      case OFFSET_P1_DEC: 
       decrypt(temp,(short)(16)); 
       Util.arrayCopy(temp,(short) 16, data, (short) start_offset, len_data); 
       return (short)8; 
      case OFFSET_P1_GEN: 
       keySchedule(temp,(short)(16)); 
       Util.arrayCopy(temp,(short) 16, data, (short) start_offset, len_data); 
       return 10; 
      default: 
       return (short)-1; 
     } 

    } 
    public static LBlockCipher getInstance() 
    { 
     if(m_instance_Cipher == null) 
      m_instance_Cipher = new LBlockCipher(); 
     return m_instance_Cipher; 
    } 

} 

TestApplet.java

public class TestApplet extends Applet 
      implements IConsts { 
    private TestApplet() 
    { 

    } 

    public static void install(byte bArray[], short bOffset, byte bLength) throws ISOException { 
     new TestApplet().register(); 
    } 

    public void process(APDU apdu) throws ISOException { 
     if (selectingApplet()) { 
      return; 
     } 
     byte[] buf = apdu.getBuffer(); 
     if(buf[ISO7816.OFFSET_CLA] != IConsts.OFFSET_CLA_CIPHERS) 
      ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED); 
     switch (buf[ISO7816.OFFSET_INS]) 
     { 
      case IConsts.OFFSET_INS_LIGHT: 
       processLight(apdu); 
       return; 
      default: 
       break; 
     } 
    } 

    private void processLight(APDU apdu) 
    { 
     //cla and ins are proccessed 
     byte[] buf = apdu.getBuffer(); 
     byte state = (buf[ISO7816.OFFSET_P1]); 
     byte type = (buf[ISO7816.OFFSET_P2]); 
     byte count_data = buf[ISO7816.OFFSET_LC]; 
     if(count_data == 0x00) 
      ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); 
     short len_data = -1; 
     switch(state) 
     { 
      case OFFSET_P1_ENC: 
       switch(type) 
       { 
        case TWINE_CIPHER_80: 
         TwineCipher m_instance = TwineCipher.getInstance(TwineCipher.TWINE_CIPHER_80); 
         len_data = m_instance.process(OFFSET_P1_ENC, buf, (short)(ISO7816.OFFSET_CDATA), count_data); 
         apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len_data); 
         return; 
        case TWINE_CIPHER_128: 
         TwineCipher.getInstance(TwineCipher.TWINE_CIPHER_80); //TODO change that 
         return; 
        case LBLOCK_CIPHER: 
         LBlockCipher m_instance_lblock= LBlockCipher.getInstance(); 
         len_data = m_instance_lblock.process(OFFSET_P1_ENC, buf, (short)(ISO7816.OFFSET_CDATA), count_data); 
         apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len_data); 
         return; 
        default: 
         ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED); 
       } 
      case OFFSET_P1_DEC: 
       switch(type) 
       { 
        case TwineCipher.TWINE_CIPHER_80: 
         TwineCipher m_instance = TwineCipher.getInstance(TwineCipher.TWINE_CIPHER_80); 
         len_data = m_instance.process(TwineCipher.OFFSET_P1_DEC, buf, (short)(ISO7816.OFFSET_CDATA), count_data); 
         apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len_data); 
         return; 
        case TwineCipher.TWINE_CIPHER_128: 
         TwineCipher.getInstance(TwineCipher.TWINE_CIPHER_80); //TODO change that 
         return; 
        case LBLOCK_CIPHER: 
         LBlockCipher m_instance_lblock= LBlockCipher.getInstance(); 
         len_data = m_instance_lblock.process(OFFSET_P1_DEC, buf, (short)(ISO7816.OFFSET_CDATA), count_data); 
         apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len_data); 
         return; 
        default: 
         ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED); 
       } 
      case OFFSET_P1_GEN: 
       switch(type) 
       { 
        case TwineCipher.TWINE_CIPHER_80: 
         TwineCipher m_instance = TwineCipher.getInstance(TwineCipher.TWINE_CIPHER_80); 
         len_data = m_instance.process(TwineCipher.OFFSET_P1_GEN, buf, (short)(ISO7816.OFFSET_CDATA), count_data); 
         apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len_data); 
         return; 
        case TwineCipher.TWINE_CIPHER_128: 
         TwineCipher.getInstance(TwineCipher.TWINE_CIPHER_80); //TODO change that 
         return; 
        case LBLOCK_CIPHER: 
         LBlockCipher m_instance_lblock= LBlockCipher.getInstance(); 
         len_data = m_instance_lblock.process(OFFSET_P1_GEN, buf, (short)(ISO7816.OFFSET_CDATA), count_data); 
         apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len_data); 
         return; 
        default: 
         ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED); 
       } 
       default: 
        break; 
     } 
    } 

} 
+0

Darf ich Sie bitten, den Befehl, den Sie an die Karte senden, hinzuzufügen? Das liegt wahrscheinlich daran, dass Sie in Ihrem Befehl keinen Le-Wert senden. – Abraham

+1

@Abraham Ich versuchte 'send_apdu -APDU 001123300A0000000000000000000000' und' send_apdu -APDU 001123300A00000000000000000000' Bedeutung mit Le und ohne Le, aber ich habe die gleiche Antwort.Manchmal bekomme ich den folgenden Fehler 'Ein Gerät an das System angeschlossen funktioniert nicht '. – Marga

+0

@Abraham Ist eine Klasse von mir. Ich werde meinen Beitrag mit dem gesamten Code aktualisieren. – Marga

Antwort

2

Bevor Sie versuchen, die Daten in dem Datenfeld des APDU-Puffer zu erhalten, Sie muss die folgende Methode aufrufen:

setIncomingAndReceive()

auf dem APDU-Objekt, sonst erhalten Sie einen Fehler.

Werfen Sie einen Blick auf this Q&A und this Q&A in Bezug auf Ihr Problem.

Ersetzen:

case OFFSET_P1_GEN: 
       switch(type) 
       { 
        case TwineCipher.TWINE_CIPHER_80: 
         TwineCipher m_instance = TwineCipher.getInstance(TwineCipher.TWINE_CIPHER_80); 
         len_data = m_instance.process(TwineCipher.OFFSET_P1_GEN, buf, (short)(ISO7816.OFFSET_CDATA), count_data); 
         apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len_data); 
         return; 
// ...... 

mit

case OFFSET_P1_GEN: 
       switch(type) 
       { 
        case TwineCipher.TWINE_CIPHER_80: 
         TwineCipher m_instance = TwineCipher.getInstance(TwineCipher.TWINE_CIPHER_80); 
         apdu.setIncomingAndReceive(); 
         len_data = m_instance.process(TwineCipher.OFFSET_P1_GEN, buf, (short)(ISO7816.OFFSET_CDATA), count_data); 
         apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len_data); 
         return; 
//..... 

im TestApplet.java wird das Problem für diesen Befehl (nur für den Befehl lösen, die Sie in Ihrem ersten Kommentar unter Ihrer Frage erwähnt , und nicht für andere Befehle), aber es ist tatsächlich nicht effizient: D. Suchen Sie also eine gute Zeile und platzieren Sie diesen Methodenaufruf dort.

+0

Vielen Dank. Mein Problem ist gelöst – Marga