package sega.a7; import javacard.framework.APDU; import javacard.framework.Applet; import javacard.framework.Util; import javacard.security.MessageDigest; import javacard.security.RandomData; import javacardx.apdu.ExtendedLength; public class A7Firm extends Applet implements ExtendedLength { private CommandServer m_ee_server = new CommandServer(); MessageDigest m_ee_sha1 = MessageDigest.getInstance((byte) 1, false); HmacSha1 m_ee_hmacSha1 = new HmacSha1(); RandomData m_ee_random = RandomData.getInstance((byte) 2); private AppData m_ee_data = new AppData(this.m_ee_random); private MakePacket m_ee_makePacket = new MakePacket(); private Crypt m_ee_crypt = new Crypt(); private AppBuffer m_ee_buffer = new AppBuffer(); public boolean select() { if (!super.select()) return false; this.m_ee_buffer.clear_ramD(); this.m_ee_data.init(); this.m_ee_server.select(); return true; } public A7Firm() { byte[] modulus = this.m_ee_data.getRsaDefaultPriModulus_ee(); byte[] exponent = this.m_ee_data.getRsaDefaultPriExponent_ee(); byte[] tmp = this.m_ee_data.getCryptBuffer_ramD(); Util.arrayFillNonAtomic(tmp, (short) 0, (short) tmp.length, (byte) -1); // Zero all the keys this.m_ee_crypt.init(tmp, (short) 0, (short) tmp.length, tmp, (short) 0, (short) tmp.length, Crypt.AES_MODE_CKEY_DECRYPT); this.m_ee_crypt.init(tmp, (short) 0, (short) tmp.length, tmp, (short) 0, (short) tmp.length, Crypt.AES_MODE_CKEY_ENCRYPT); this.m_ee_crypt.init(tmp, (short) 0, (short) tmp.length, tmp, (short) 0, (short) tmp.length, Crypt.AES_MODE_GKEY_DECRYPT); this.m_ee_crypt.init(tmp, (short) 0, (short) tmp.length, tmp, (short) 0, (short) tmp.length, Crypt.AES_MODE_GKEY_ENCRYPT); this.m_ee_crypt.init(modulus, (short) 0, (short) modulus.length, exponent, (short) 0, (short) exponent.length, Crypt.RSA_MODE_DECRYPT); this.m_ee_server.setNoCommand(new NoCommand((short) -1, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1)); this.m_ee_server.attachCommand( new SessionOpen(AppConfig.A7_ORD_SESSION_OPEN, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1)); this.m_ee_server.attachCommand( new SessionClose(AppConfig.A7_ORD_SESSION_CLOSE, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1)); this.m_ee_server.attachCommand(new AuthStart(AppConfig.A7_ORD_AUTH_START, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand(new HmacChange(AppConfig.A7_ORD_HMAC_CHANGE, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand(new KeyChange(AppConfig.A7_ORD_KEY_CHANGE, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand( new LvGet(AppConfig.A7_ORD_LV_GET, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1)); this.m_ee_server.attachCommand(new KeychipInfoWrite(AppConfig.A7_ORD_KEYCHIP_INFO_WRITE, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand(new KeychipInfoRead(AppConfig.A7_ORD_KEYCHIP_INFO_READ, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand(new GkeyWrite(AppConfig.A7_ORD_GKEY_WRITE, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand(new GkeyEnc(AppConfig.A7_ORD_GKEY_ENC, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand(new GkeyDec(AppConfig.A7_ORD_GKEY_DEC, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand(new SflagWrite(AppConfig.A7_ORD_SFLAG_WRITE, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand( new ErrorGet(AppConfig.A7_ORD_ERROR_GET, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1)); this.m_ee_server.attachCommand( new LvEnable(AppConfig.A7_ORD_LV_ENABLE, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1)); this.m_ee_server.attachCommand(new EepInit(AppConfig.A7_ORD_EEP_INIT, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand( new VerGet(AppConfig.A7_ORD_VER_GET, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1)); this.m_ee_server.attachCommand(new PrivkeyModulusWrite(AppConfig.A7_ORD_GPRIKEY_MODULUS_WRITE, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand(new PrikeyExponentWrite(AppConfig.A7_ORD_GPRIKEY_EXPONENS_WRITE, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand(new UdataWrite(AppConfig.A7_ORD_UDATA_WRITE, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand(new UdataRead(AppConfig.A7_ORD_UDATA_READ, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand(new StorageWrite(AppConfig.A7_ORD_STORAGE_WRITE, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand(new StorageRead(AppConfig.A7_ORD_STORAGE_READ, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand(new RanGet(AppConfig.A7_ORD_RAN_GET, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt, this.m_ee_random)); this.m_ee_server.attachCommand(new PlayCountIncrement(AppConfig.A7_ORD_PLAY_COUNT_INCREMENT, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand(new PlayCountRead(AppConfig.A7_ORD_PLAY_COUNT_READ, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt, this.m_ee_random)); this.m_ee_server.attachCommand(new TraceDataInfoWrite(AppConfig.A7_ORD_TRACE_DATA_INFO_WRITE, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand(new TraceDataInfoRead(AppConfig.A7_ORD_TRACE_DATA_INFO_READ, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt)); this.m_ee_server.attachCommand(new StorageSizeGet(AppConfig.A7_ORD_STORAGE_SIZE_GET, this.m_ee_data, this.m_ee_makePacket, this.m_ee_sha1, this.m_ee_hmacSha1, this.m_ee_crypt, this.m_ee_random)); } private short makeErrorPacket(short error, short cmd, byte[] sendPacket, short packetOffset, short packetLength) { this.m_ee_data.setLastError_ramD((short) error); this.m_ee_makePacket.setData(null, (short) 0, (short) 0, AppConfig.A7_TAG_RSP_COMMAND, (short) 26, (short) error, (short) cmd, null, (short) 0, (short) 0, null, (short) 0, (short) 0, null, (short) 0, (short) 0, sendPacket, packetOffset, packetLength, this.m_ee_sha1, null); return 26; } public void process(APDU apdu) { short ramD_sendSize = (short) 0; if (selectingApplet()) return; byte[] ramD_packetData = apdu.getBuffer(); if (this.m_ee_data.getSflag_ee() && this.m_ee_data.getLevel_ramD() == -1) return; if (this.m_ee_data.getLevel_ramD() == 0) this.m_ee_data.setLevel_ramD((byte) 1); short ramD_length = Util.getShort(ramD_packetData, (short) 5); boolean ramD_bRet = this.m_ee_buffer.setData_ramD(ramD_packetData, (short) 7, ramD_length); if (!ramD_bRet) { this.m_ee_buffer.clear_ramD(); ramD_sendSize = makeErrorPacket(AppConfig.A7_FAIL, (short) 0, ramD_packetData, (short) 0, (short)ramD_packetData.length); apdu.setOutgoingAndSend((short) 0, (short) ramD_sendSize); return; } byte[] ramD_buffer = this.m_ee_buffer.getBuffer_ramD(); short ramD_size = Util.getShort(ramD_buffer, AppConfig.A7_PARAMSIZE_OFFSET); if (ramD_size > this.m_ee_buffer.getBufferSize_ramD()) return; try { ramD_sendSize = this.m_ee_server.execute(ramD_buffer, (short) 0, this.m_ee_buffer.getBufferSize_ramD(), ramD_packetData, (short) 0, (short) ramD_packetData.length); } catch (Exception e) { short ramD_cmd = Util.getShort(ramD_buffer, AppConfig.A7_COMMAND_OFFSET); this.m_ee_data.setLastError_ramD(AppConfig.A7_FAIL); ramD_sendSize = makeErrorPacket(AppConfig.A7_FAIL, ramD_cmd, ramD_packetData, (short) 0, (short) ramD_packetData.length); } this.m_ee_buffer.clear_ramD(); if (ramD_sendSize != 0) apdu.setOutgoingAndSend((short) 0, ramD_sendSize); } public static void install(byte[] bArray, short bOffset, byte bLength) { (new PrivkeyModulusWrite()).register(bArray, (short) ((short) bOffset + 1), bArray[(short) bOffset]); } public void deselect() { super.deselect(); } }