package sega.a7; import javacard.framework.JCSystem; import javacard.framework.Util; import javacard.security.RandomData; public class AppData { /** * 9FD0A43A697329C54BAEC33CF07303BB25F4EB0F366B214633D48ABF639C1057 * 55BD87F4071A20E5A139DCF283C86DE5E4D13DA34A023E21AC1B27A452C49044 * 97E625C32F6F9762BB80235D11D592965EA6F5839586C3066F2079E70C96055A * FC5A7FC25789B54DB0833D3625B8DAE173A127A681CCE210103BB72FD0205CD3 * F024C1BB26E261664D638390F8EF7D512DCF2BC72A826EEC413F233788BA1309 * 264018EFDBD8CB748E08917C992A67B7B2C0357E45AB9C9E51CF308EFCC0256F * 28999B079BBB3ADF67D7221A1DE8F3F587A1A49662E0DFE6F5FA557351F04779 * 3FCE52641D2C7DC6B0EABA8AE529D1DFF4DC793BB82994CB49B6E4EFD80F142B */ private static final byte[] m_ee_defaultPriModulus = new byte[] { -97, -48, -92, 58, 105, 115, 41, -59, 75, -82, -61, 60, -16, 115, 3, -69, 37, -12, -21, 15, 54, 107, 33, 70, 51, -44, -118, -65, 99, -100, 16, 87, 85, -67, -121, -12, 7, 26, 32, -27, -95, 57, -36, -14, -125, -56, 109, -27, -28, -47, 61, -93, 74, 2, 62, 33, -84, 27, 39, -92, 82, -60, -112, 68, -105, -26, 37, -61, 47, 111, -105, 98, -69, -128, 35, 93, 17, -43, -110, -106, 94, -90, -11, -125, -107, -122, -61, 6, 111, 32, 121, -25, 12, -106, 5, 90, -4, 90, 127, -62, 87, -119, -75, 77, -80, -125, 61, 54, 37, -72, -38, -31, 115, -95, 39, -90, -127, -52, -30, 16, 16, 59, -73, 47, -48, 32, 92, -45, -16, 36, -63, -69, 38, -30, 97, 102, 77, 99, -125, -112, -8, -17, 125, 81, 45, -49, 43, -57, 42, -126, 110, -20, 65, 63, 35, 55, -120, -70, 19, 9, 38, 64, 24, -17, -37, -40, -53, 116, -114, 8, -111, 124, -103, 42, 103, -73, -78, -64, 53, 126, 69, -85, -100, -98, 81, -49, 48, -114, -4, -64, 37, 111, 40, -103, -101, 7, -101, -69, 58, -33, 103, -41, 34, 26, 29, -24, -13, -11, -121, -95, -92, -106, 98, -32, -33, -26, -11, -6, 85, 115, 81, -16, 71, 121, 63, -50, 82, 100, 29, 44, 125, -58, -80, -22, -70, -118, -27, 41, -47, -33, -12, -36, 121, 59, -72, 41, -108, -53, 73, -74, -28, -17, -40, 15, 20, 43 }; /** * 310A06BADDCCB6CE91B0A8BC3454369AE0C4CCB438509B3F3D7C44AF01D3CBB7 * E0D96DB455D190B2A5CC699E090E219ADFA1CD3623E9984320DA9C4972145AE8 * 916BCFBE9AF9B50C58D8B301460DB1136F2BF03E564DA9DE798F0F98F465BC72 * F4E898377C41075F3580AFF1C3957BA49EA49ED41B145171F8693A86F3685AD3 * 39BEFDA3188141990787977FD8BE7D588886A67E4EEBEB38FBB09FAF44468FF9 * EF74BB7961ED1063714CCA6ECAEC8389CE4A6F315C3069EA4BF2F6CAEF2028A2 * 09B0307200475F775CCAD248E2E93C42C312F954183D233EB1B29409388C03E6 * 2961A8833F5A508305B7D8013AABE6CD1A01034A18E4438DCD46A52825F539F1 */ private static final byte[] m_ee_defaultPriExponent = new byte[] { 49, 10, 6, -70, -35, -52, -74, -50, -111, -80, -88, -68, 52, 84, 54, -102, -32, -60, -52, -76, 56, 80, -101, 63, 61, 124, 68, -81, 1, -45, -53, -73, -32, -39, 109, -76, 85, -47, -112, -78, -91, -52, 105, -98, 9, 14, 33, -102, -33, -95, -51, 54, 35, -23, -104, 67, 32, -38, -100, 73, 114, 20, 90, -24, -111, 107, -49, -66, -102, -7, -75, 12, 88, -40, -77, 1, 70, 13, -79, 19, 111, 43, -16, 62, 86, 77, -87, -34, 121, -113, 15, -104, -12, 101, -68, 114, -12, -24, -104, 55, 124, 65, 7, 95, 53, -128, -81, -15, -61, -107, 123, -92, -98, -92, -98, -44, 27, 20, 81, 113, -8, 105, 58, -122, -13, 104, 90, -45, 57, -66, -3, -93, 24, -127, 65, -103, 7, -121, -105, 127, -40, -66, 125, 88, -120, -122, -90, 126, 78, -21, -21, 56, -5, -80, -97, -81, 68, 70, -113, -7, -17, 116, -69, 121, 97, -19, 16, 99, 113, 76, -54, 110, -54, -20, -125, -119, -50, 74, 111, 49, 92, 48, 105, -22, 75, -14, -10, -54, -17, 32, 40, -94, 9, -80, 48, 114, 0, 71, 95, 119, 92, -54, -46, 72, -30, -23, 60, 66, -61, 18, -7, 84, 24, 61, 35, 62, -79, -78, -108, 9, 56, -116, 3, -26, 41, 97, -88, -125, 63, 90, 80, -125, 5, -73, -40, 1, 58, -85, -26, -51, 26, 1, 3, 74, 24, -28, 67, -115, -51, 70, -91, 40, 37, -11, 57, -15 }; private static final byte VALUE_AUTH_LEVEL = 0; private static final byte VALUE_SESSION = 1; private static final byte VALUE_ERROR_RESULT_H = 2; private static final byte VALUE_ERROR_COUNT = 4; private static final byte VALUE_WRITE_FLAG = 5; private static final byte VALUE_SIZE = 6; private byte[] m_ee_sflag = new byte[1]; private byte[] m_ramD_rsa_update_status; private byte[] m_ramD_value; private byte[] m_ramD_kh; private byte[] m_ramD_cryptBuffer; private byte[] m_ee_gkeyIv; private byte[] m_ramD_cKeyIv; private byte[] m_ramD_newNonceEvent; private byte[] m_ramD_lastNonceEvent; private byte[] m_ramD_generalBuffer; private byte[] m_ramD_sendOutBuffer; private short[] m_ramD_sendOutInfo; private byte[] m_ramD_footerBuffer; private byte[] m_ramD_nonceOddBuffer; private byte[] m_ee_priModulus = new byte[AppConfig.RSA_PRI_MODULUS_SIZE]; private byte[] m_ee_priExponent = new byte[AppConfig.RSA_PRI_EXPONENT_SIZE]; private byte[] m_ee_udata = new byte[AppConfig.UDATA_SIZE]; private byte[] m_ee_storage = new byte[AppConfig.STORAGE_SIZE]; private byte[] m_ee_keychipInfo = new byte[AppConfig.KEYCHIP_INFO_SIZE]; private byte[] m_ee_traceDataInfo = new byte[AppConfig.TRACE_DATA_INFO_SIZE]; private byte[] m_ee_playCount = new byte[AppConfig.PLAY_COUNT_VALUE_SIZE]; private RandomData m_ee_rand; public static final byte SESSION_DISABLE = 0; public static final byte SESSION_ENABLE = 1; public static final byte SHIPMENT_FLAG = 0x04; public static final byte BLOCK_FLAG = 0x20; public static final byte RSA_UPDATE_FLAG = 1; public static final byte RSA_UPDATE_STATUS_SIZE = 1; public static final byte RSA_UPDATE_EXPONENT = 0x08; public static final byte RSA_UPDATE_MODULUS = 0x40; public AppData(RandomData rand) { this.m_ee_rand = rand; this.m_ee_gkeyIv = new byte[16]; Util.arrayCopy(m_ee_defaultPriModulus, (short) 0, this.m_ee_priModulus, (short) 0, (short) this.m_ee_priModulus.length); Util.arrayCopy(m_ee_defaultPriExponent, (short) 0, this.m_ee_priExponent, (short) 0, (short) this.m_ee_priExponent.length); this.m_ee_sflag[0] = 0; Util.arrayFillNonAtomic(this.m_ee_keychipInfo, (short) 0, (short) this.m_ee_keychipInfo.length, (byte) -1); Util.arrayFillNonAtomic(this.m_ee_udata, (short) 0, (short) this.m_ee_udata.length, (byte) -1); Util.arrayFillNonAtomic(this.m_ee_storage, (short) 0, (short) this.m_ee_storage.length, (byte) -1); Util.arrayFillNonAtomic(this.m_ee_traceDataInfo, (short) 0, (short) this.m_ee_traceDataInfo.length, (byte) -1); Util.arrayFillNonAtomic(this.m_ee_playCount, (short) 0, (short) this.m_ee_playCount.length, (byte) 0); Util.arrayFillNonAtomic(this.m_ee_gkeyIv, (short) 0, (short) this.m_ee_gkeyIv.length, (byte) -1); this.m_ramD_value = JCSystem.makeTransientByteArray(VALUE_SIZE, (byte) 1); this.m_ramD_rsa_update_status = JCSystem.makeTransientByteArray(RSA_UPDATE_STATUS_SIZE, (byte) 1); this.m_ramD_kh = JCSystem.makeTransientByteArray((short) 20, (byte) 1); this.m_ramD_newNonceEvent = JCSystem.makeTransientByteArray((short) 20, (byte) 1); this.m_ramD_lastNonceEvent = JCSystem.makeTransientByteArray((short) 20, (byte) 1); this.m_ramD_cKeyIv = JCSystem.makeTransientByteArray(AppConfig.AES_IV_SIZE, (byte) 1); this.m_ramD_generalBuffer = JCSystem.makeTransientByteArray(AppConfig.GENERAL_BUFFER_SIZE, (byte) 1); this.m_ramD_footerBuffer = JCSystem.makeTransientByteArray(AppConfig.FOOTER_BUFFER_SIZE, (byte) 1); this.m_ramD_nonceOddBuffer = JCSystem.makeTransientByteArray(AppConfig.NONCE_ODD_BUFFER_SIZE, (byte) 1); this.m_ramD_sendOutBuffer = JCSystem.makeTransientByteArray(AppConfig.SEND_OUT_BUFFER_SIZE, (byte) 1); this.m_ramD_sendOutInfo = JCSystem.makeTransientShortArray(AppConfig.SEND_BUUFER_INFO_ARRAY_SIZE, (byte) 1); this.m_ramD_cryptBuffer = JCSystem.makeTransientByteArray((short) 16, (byte) 1); } public void init() { if (getBlockFlag_ee()) { this.m_ramD_value[VALUE_AUTH_LEVEL] = -1; } else { this.m_ramD_value[VALUE_AUTH_LEVEL] = 0; } this.m_ramD_value[VALUE_SESSION] = SESSION_DISABLE; this.m_ramD_value[VALUE_ERROR_COUNT] = 0; } public void reset() { this.m_ee_sflag[0] = 0; Util.arrayFillNonAtomic(this.m_ee_keychipInfo, (short) 0, (short) this.m_ee_keychipInfo.length, (byte) -1); Util.arrayFillNonAtomic(this.m_ee_udata, (short) 0, (short) this.m_ee_udata.length, (byte) -1); Util.arrayFillNonAtomic(this.m_ee_storage, (short) 0, (short) this.m_ee_storage.length, (byte) -1); Util.arrayFillNonAtomic(this.m_ee_traceDataInfo, (short) 0, (short) this.m_ee_traceDataInfo.length, (byte) -1); Util.arrayFillNonAtomic(this.m_ee_playCount, (short) 0, (short) this.m_ee_playCount.length, (byte) 0); Util.arrayFillNonAtomic(this.m_ee_gkeyIv, (short) 0, (short) this.m_ee_gkeyIv.length, (byte) -1); } public void setLevel_ramD(byte setLevel) { this.m_ramD_value[VALUE_AUTH_LEVEL] = setLevel; } public byte getLevel_ramD() { return this.m_ramD_value[VALUE_AUTH_LEVEL]; } public void setSession_ramD(byte setSession) { this.m_ramD_value[VALUE_SESSION] = setSession; } public void addValuePlayCounter_ee(byte value) { short ramD_tmp = 0; short ramD_setValue = (short) value; short ramD_ii = 0; while (ramD_ii < this.m_ee_playCount.length) { short ramD_index = (short) ((this.m_ee_playCount.length - ramD_ii) - 1); ramD_tmp = (short) ((ramD_setValue & 0xFF) + (this.m_ee_playCount[ramD_index] & 0xFF)); this.m_ee_playCount[ramD_index] = (byte) (ramD_tmp & 0xFF); if (ramD_tmp > 255) { ramD_setValue = 1; ramD_ii++; continue; } break; } } public boolean getPlayCounter_ee(byte[] playCount, short offset, short length) { if (length < this.m_ee_playCount.length) return false; Util.arrayCopyNonAtomic(this.m_ee_playCount, (short) 0, playCount, offset, (short) this.m_ee_playCount.length); return true; } public byte getSession_ramD() { return this.m_ramD_value[VALUE_SESSION]; } public final byte[] getNewNonceEvent_ramD() { this.m_ee_rand.generateData(this.m_ramD_newNonceEvent, (short) 0, (short) this.m_ramD_newNonceEvent.length); return this.m_ramD_newNonceEvent; } public final byte[] getLastNonceEvent_ramD() { return this.m_ramD_lastNonceEvent; } public boolean setLastNonceEvent_ramD(byte[] lastNonceEvent, short offset, short length) { if (length > this.m_ramD_lastNonceEvent.length) return false; short ramD_writeSize = Util.arrayCopyNonAtomic(lastNonceEvent, offset, this.m_ramD_lastNonceEvent, (short) 0, length); return ramD_writeSize == length; } public final byte[] getKh_ramD() { return this.m_ramD_kh; } public boolean setKh_ramD(byte[] kh, short offset, short length) { if (length > this.m_ramD_kh.length) return false; short ramD_writeSize = Util.arrayCopyNonAtomic(kh, offset, this.m_ramD_kh, (short) 0, length); return ramD_writeSize == length; } public final byte[] getGkeyIv_ee() { return this.m_ee_gkeyIv; } public boolean setGkeyIv_ee(byte[] newGkeyIv, short offset, short length) { if (length > this.m_ee_gkeyIv.length) return false; short ramD_writeSize = Util.arrayCopy(newGkeyIv, offset, this.m_ee_gkeyIv, (short) 0, length); return ramD_writeSize == length; } public final byte[] getCkeyIv_ramD() { return this.m_ramD_cKeyIv; } public boolean setCkeyIv_ramD(byte[] newCkeyIv, short offset, short length) { if (length > this.m_ee_gkeyIv.length) return false; short ramD_writeSize = Util.arrayCopyNonAtomic(newCkeyIv, offset, this.m_ramD_cKeyIv, (short) 0, length); return ramD_writeSize == length; } public final byte[] getRsaDefaultPriModulus_ee() { return m_ee_defaultPriModulus; } public final byte[] getRsaDefaultPriExponent_ee() { return m_ee_defaultPriExponent; } public final byte[] getRsaPriModulus_ee() { return this.m_ee_priModulus; } public final byte[] getRsaPriExponent_ee() { return this.m_ee_priExponent; } public boolean setRsaPriKeyModulus_ee(byte[] exponent, short eOfset, short eLength) { if (eLength > this.m_ee_priModulus.length) return false; short ramD_writeSize = Util.arrayCopy(exponent, eOfset, this.m_ee_priModulus, (short) 0, eLength); return ramD_writeSize == eLength; } public boolean setRsaPriKeyExponent_ee(byte[] modulus, short mOffset, short mLength) { if (mLength > this.m_ee_priExponent.length) return false; short ramD_writeSize = Util.arrayCopy(modulus, mOffset, this.m_ee_priExponent, (short) 0, mLength); return ramD_writeSize == mLength; } public boolean getSflag_ee() { return (this.m_ee_sflag[0] & SHIPMENT_FLAG) != 0; } public void activeSflag() { this.m_ramD_value[VALUE_WRITE_FLAG] = this.m_ee_sflag[0]; this.m_ramD_value[VALUE_WRITE_FLAG] |= SHIPMENT_FLAG; Util.arrayCopy(this.m_ramD_value, VALUE_WRITE_FLAG, this.m_ee_sflag, (short) 0, (short) 1); } public boolean getRsaExponentUpdate_ramD() { return (this.m_ramD_rsa_update_status[0] & RSA_UPDATE_EXPONENT) != 0; } public void activeRssaExponentUpdate_ramD() { this.m_ramD_rsa_update_status[0] = (byte) (this.m_ramD_rsa_update_status[0] | RSA_UPDATE_EXPONENT); } public boolean getRsaModulusUpdate_ramD() { return (this.m_ramD_rsa_update_status[0] & RSA_UPDATE_MODULUS) != 0; } public void activeRssaModulusUpdate_ramD() { this.m_ramD_rsa_update_status[0] = (byte) (this.m_ramD_rsa_update_status[0] | RSA_UPDATE_MODULUS); } public boolean getBlockFlag_ee() { return (this.m_ee_sflag[0] & BLOCK_FLAG) != 0; } public void activeBlockFlag() { this.m_ramD_value[VALUE_WRITE_FLAG] = this.m_ee_sflag[0]; this.m_ramD_value[VALUE_WRITE_FLAG] |= BLOCK_FLAG; Util.arrayCopy(this.m_ramD_value, VALUE_WRITE_FLAG, this.m_ee_sflag, (short) 0, (short) 1); } public final byte[] getKeychipInfo_ee() { return this.m_ee_keychipInfo; } public boolean setKeychipInfo_ee(byte[] newKeychipInfo, short offset, short length) { if (length > this.m_ee_keychipInfo.length) return false; short ramD_writeSize = Util.arrayCopy(newKeychipInfo, offset, this.m_ee_keychipInfo, (short) 0, length); return ramD_writeSize == length; } public final byte[] getTraceDataInfo_ee() { return this.m_ee_traceDataInfo; } public boolean setTraceDataInfo_ee(byte[] newTraceDataInfo, short offset, short length) { if (length > this.m_ee_traceDataInfo.length) return false; short ramD_writeSize = Util.arrayCopy(newTraceDataInfo, offset, this.m_ee_traceDataInfo, (short) 0, length); return ramD_writeSize == length; } public final byte[] getUdata_ee() { return this.m_ee_udata; } public boolean setUdata_ee(byte[] newUdata, short offset, short length) { if (length > newUdata.length) return false; short ramD_writeSize = Util.arrayCopy(newUdata, offset, this.m_ee_udata, (short) 0, length); return ramD_writeSize == length; } public final byte[] getStorageData_ee() { return this.m_ee_storage; } public boolean setStorageData_ee(byte[] newStorage, short offset, short length, short dstOffset) { if (length > (this.m_ee_storage.length - dstOffset)) return false; short ramD_writeSize = Util.arrayCopy(newStorage, offset, this.m_ee_storage, dstOffset, length); return ramD_writeSize == (dstOffset + length); } public byte[] getGeneralBuffer_ramD() { return this.m_ramD_generalBuffer; } public byte[] getSendOutBuffer_ramD() { return this.m_ramD_sendOutBuffer; } public short[] getSendOutInfo_ramD() { return this.m_ramD_sendOutInfo; } public byte[] getCryptBuffer_ramD() { return this.m_ramD_cryptBuffer; } public byte[] getFooterBuffer_ramD() { return this.m_ramD_footerBuffer; } public byte[] getNonceOddBuffer_ramD() { return this.m_ramD_nonceOddBuffer; } public void setLastError_ramD(short error) { Util.setShort(this.m_ramD_value, VALUE_ERROR_RESULT_H, (short) error); } public short getLastError_ramD() { short ramD_result = Util.getShort(this.m_ramD_value, VALUE_ERROR_RESULT_H); return ramD_result; } public void incrementErrorCount() { this.m_ramD_value[VALUE_ERROR_COUNT]++; if (this.m_ramD_value[VALUE_ERROR_COUNT] + 1 == 3) { activeBlockFlag(); this.m_ramD_value[VALUE_AUTH_LEVEL] = -1; } } public void clearErrorCount() { this.m_ramD_value[VALUE_ERROR_COUNT] = 0; } }