2016-04-09 11 views
0

Java Card 2.1.2 SDKとGPShellを使用してデバイスと通信する方法でJava Cardにプロジェクトを構築しました.GPShellのhelloworldの例をテストして管理しましたSimple APDUを送信する。私は大きな.capファイルにAPDUを送信しようとすると、しかし、デバイスは、Javaカードは、80 KBのEEPROMを有しているが、私は私には思えるbelow.Itアプレットからメモリの問題をコードの断片を添付私に次のエラーJava Cardスマートカードとの通信エラーが検出されました

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

を与えますEclipseのシミュレータではアプリケーションがうまく動作します。

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インタフェース

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

カードに送信するコマンドも追加してもらえますか?おそらく、あなたのコマンドにLeの値を送らないからでしょう。 – Abraham

+1

@Abraham私は 'send_apdu -APDU 001123300A0000000000000000000000'とLeとLeを使わないで' send_apdu -APDU 001123300A00000000000000000000'という意味をしましたが、私は同じ答えを得ました。時には私は次のエラー 'システムに接続されたデバイスが機能していません。 – Marga

+0

@Abraham私はクラスを凍結しています。すべてのコードを含めて私の投稿を更新します。 – Marga

答えて

2

APDUバッファのデータフィールドのデータを受信しようとする前に、あなた次のメソッドを呼び出す必要があります。

setIncomingAndReceive()

APDUオブジェクトの場合は、エラーが発生します。

問題と関連してthis Q&Athis Q&Aをご覧ください。

交換:

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 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; 
//..... 

TestApplet.javaにのみ、あなたの質問の下にあなたの最初のコメントで述べたコマンドは、このコマンド(のための問題を解決します、他のコマンドではない)、実際には効率的ではありません:D。だから良い行を見つけ、そこにこのメソッド呼び出しを置きます。

+0

ありがとうございます。私の問題は解決しました – Marga

関連する問題