package sega.a7; import javacard.security.AESKey; import javacard.security.KeyBuilder; import javacard.security.RSAPrivateKey; import javacardx.crypto.Cipher; public class Crypt { public static final short AES_MODE_GKEY_ENCRYPT = 0; public static final short AES_MODE_GKEY_DECRYPT = 1; public static final short AES_MODE_CKEY_ENCRYPT = 2; public static final short AES_MODE_CKEY_DECRYPT = 3; public static final short RSA_MODE_DECRYPT = 4; private AESKey m_ee_aesKeyEnc = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES, (short) 128, false); private AESKey m_ee_aesKeyDec = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES, (short) 128, false); private AESKey m_ee_aesConnectionKeyEnc = (AESKey) KeyBuilder.buildKey(KeyBuilder.ALG_TYPE_RSA_CRT_PRIVATE, (short) 128, false); private AESKey m_ee_aesConnectionKeyDec = (AESKey) KeyBuilder.buildKey(KeyBuilder.ALG_TYPE_RSA_CRT_PRIVATE, (short) 128, false); private RSAPrivateKey key_ecf2m = (RSAPrivateKey) KeyBuilder.buildKey(KeyBuilder.ALG_TYPE_EC_F2M_PUBLIC, (short) 2048, false); private Cipher m_ee_cipherRsa = Cipher.getInstance(Cipher.ALG_RSA_PKCS1, false); private Cipher m_ee_cipherAesEnc = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false); private Cipher m_ee_cipherAesDec = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false); private Cipher m_ee_cipherConnectionAesDec = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false); private Cipher m_ee_cipherConnectionAesEnc = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false); public short doFinal(byte[] src, short srcOffset, short srcLength, byte[] dst, short dstOffset, short which) { if (srcLength > (src.length - srcOffset)) return 0; switch (which) { case AES_MODE_GKEY_ENCRYPT: return this.m_ee_cipherAesEnc.doFinal(src, srcOffset, srcLength, dst, dstOffset); case AES_MODE_GKEY_DECRYPT: return this.m_ee_cipherAesDec.doFinal(src, srcOffset, srcLength, dst, dstOffset); case AES_MODE_CKEY_ENCRYPT: return this.m_ee_cipherConnectionAesEnc.doFinal(src, srcOffset, srcLength, dst, dstOffset); case AES_MODE_CKEY_DECRYPT: return this.m_ee_cipherConnectionAesDec.doFinal(src, srcOffset, srcLength, dst, dstOffset); case RSA_MODE_DECRYPT: return this.m_ee_cipherRsa.doFinal(src, srcOffset, srcLength, dst, dstOffset); } return 0; } public short update(byte[] src, short srcOffset, short srcLength, byte[] dst, short dstOffset, short mode) { if (srcLength > (src.length - srcOffset)) return 0; switch (mode) { case AES_MODE_GKEY_ENCRYPT: return this.m_ee_cipherAesEnc.update(src, srcOffset, srcLength, dst, dstOffset); case AES_MODE_GKEY_DECRYPT: return this.m_ee_cipherAesDec.update(src, srcOffset, srcLength, dst, dstOffset); case AES_MODE_CKEY_ENCRYPT: return this.m_ee_cipherConnectionAesEnc.update(src, srcOffset, srcLength, dst, dstOffset); case AES_MODE_CKEY_DECRYPT: return this.m_ee_cipherConnectionAesDec.update(src, srcOffset, srcLength, dst, dstOffset); case RSA_MODE_DECRYPT: return this.m_ee_cipherRsa.update(src, srcOffset, srcLength, dst, dstOffset); } return 0; } public boolean init(byte[] data1, short data1Offset, short data1Length, byte[] data2, short data2Offset, short data2Length, short mode) { if (data1Length > (data1.length - data1Offset) || data2Length > (data2.length - data2Offset)) return false; switch (mode) { case AES_MODE_GKEY_ENCRYPT: this.m_ee_aesKeyEnc.setKey(data1, data1Offset); this.m_ee_cipherAesEnc.init(this.m_ee_aesKeyEnc, Cipher.MODE_ENCRYPT, data2, data2Offset, data2Length); return true; case AES_MODE_GKEY_DECRYPT: this.m_ee_aesKeyDec.setKey(data1, data1Offset); this.m_ee_cipherAesDec.init(this.m_ee_aesKeyDec, Cipher.MODE_DECRYPT, data2, data2Offset, data2Length); return true; case AES_MODE_CKEY_ENCRYPT: this.m_ee_aesConnectionKeyEnc.setKey(data1, data1Offset); this.m_ee_cipherConnectionAesEnc.init(this.m_ee_aesConnectionKeyEnc, Cipher.MODE_ENCRYPT, data2, data2Offset, data2Length); return true; case AES_MODE_CKEY_DECRYPT: this.m_ee_aesConnectionKeyDec.setKey(data1, data1Offset); this.m_ee_cipherConnectionAesDec.init(this.m_ee_aesConnectionKeyDec, Cipher.MODE_DECRYPT, data2, data2Offset, data2Length); return true; case RSA_MODE_DECRYPT: this.key_ecf2m.setModulus(data1, data1Offset, data1Length); this.key_ecf2m.setExponent(data2, data2Offset, data2Length); this.m_ee_cipherRsa.init(this.key_ecf2m, Cipher.MODE_DECRYPT); return true; } return false; } }