136 lines
5.5 KiB
Java
136 lines
5.5 KiB
Java
package sega.a7;
|
|
|
|
import javacard.framework.JCSystem;
|
|
import javacard.framework.Util;
|
|
import javacard.security.MessageDigest;
|
|
|
|
public class Command {
|
|
protected short m_ee_cmd;
|
|
protected short m_ee_recvPacketSize;
|
|
protected short m_ee_sendPacketSize;
|
|
protected short[] m_ramD_setSendPacketSize;
|
|
protected short m_ee_tag;
|
|
protected MakePacket m_ee_packet;
|
|
protected AppData m_ee_data;
|
|
protected MessageDigest m_ee_sha1;
|
|
|
|
private static final short ERROR_PACKET_SIZE = 26;
|
|
protected static final short SET_SEND_PACKET_SIZE_ARRAY_SIZE = 1;
|
|
|
|
protected byte[] m_ramD_outData;
|
|
protected short[] m_ramD_outDataInfo;
|
|
|
|
public Command(short cmd, short recvPacketSize, short sendPacketSize, AppData data, MakePacket packet,
|
|
MessageDigest sha1) {
|
|
this.m_ee_cmd = (short) cmd;
|
|
this.m_ee_data = data;
|
|
this.m_ee_packet = packet;
|
|
this.m_ee_recvPacketSize = (short) recvPacketSize;
|
|
this.m_ee_sendPacketSize = (short) sendPacketSize;
|
|
this.m_ee_tag = AppConfig.A7_TAG_RQU_COMMAND;
|
|
this.m_ee_sha1 = sha1;
|
|
this.m_ramD_setSendPacketSize = JCSystem.makeTransientShortArray((short) 1, (byte) 1);
|
|
this.m_ramD_setSendPacketSize[0] = this.m_ee_sendPacketSize;
|
|
this.m_ramD_outData = data.getSendOutBuffer_ramD();
|
|
this.m_ramD_outDataInfo = data.getSendOutInfo_ramD();
|
|
}
|
|
|
|
public boolean select() {
|
|
this.m_ramD_setSendPacketSize[0] = this.m_ee_sendPacketSize;
|
|
return true;
|
|
}
|
|
|
|
public short core(byte[] data, short dataOffset, short dataLength) {
|
|
return AppConfig.A7_SUCCESS;
|
|
}
|
|
|
|
public short execute(byte[] data, short dataOffset, short dataLength, byte[] dst, short dstOffset,
|
|
short dstLength) {
|
|
short ramD_error = checkHeader(data, dataOffset, dataLength);
|
|
if (ramD_error != AppConfig.A7_SUCCESS)
|
|
return makeErrorPacket(ramD_error, dst, dstOffset, dstLength);
|
|
|
|
ramD_error = checkFooter(data, dataOffset, dataLength);
|
|
if (ramD_error != AppConfig.A7_SUCCESS)
|
|
return makeErrorPacket(ramD_error, dst, dstOffset, dstLength);
|
|
|
|
this.m_ramD_outDataInfo[0] = 0;
|
|
this.m_ramD_outDataInfo[1] = 0;
|
|
ramD_error = core(data, dataOffset, dataLength);
|
|
|
|
if (ramD_error != AppConfig.A7_SUCCESS)
|
|
return makeErrorPacket(ramD_error, dst, dstOffset, dstLength);
|
|
|
|
return makeSendPacket(AppConfig.A7_TAG_RSP_COMMAND, this.m_ramD_setSendPacketSize[0], ramD_error,
|
|
this.m_ramD_outData, this.m_ramD_outDataInfo[0], this.m_ramD_outDataInfo[1],
|
|
dst, dstOffset, dstLength);
|
|
}
|
|
|
|
public short getCmd_ee() {
|
|
return this.m_ee_cmd;
|
|
}
|
|
|
|
protected short setSendPacketSize_ramD(short sendSize) {
|
|
this.m_ramD_setSendPacketSize[0] = sendSize;
|
|
return this.m_ramD_setSendPacketSize[0];
|
|
}
|
|
|
|
/**
|
|
* Validate packet header.
|
|
* The header is 6 bytes.
|
|
* 2 bytes: tag
|
|
* 2 bytes: paramsize
|
|
* 2 bytes: command
|
|
*/
|
|
protected short checkHeader(byte[] data, short dataOfset, short dataLength) {
|
|
short ramD_paramsize = Util.getShort(data, (short) (dataOfset + AppConfig.A7_PARAMSIZE_OFFSET));
|
|
if (dataLength != ramD_paramsize)
|
|
return AppConfig.A7_BAD_DATASIZE;
|
|
|
|
short ramD_tag = Util.getShort(data, (short) (dataOfset + AppConfig.A7_TAG_OFFSET));
|
|
|
|
if (ramD_tag != this.m_ee_tag)
|
|
return AppConfig.A7_BAD_TAG;
|
|
if (this.m_ee_recvPacketSize != 0 && dataLength != this.m_ee_recvPacketSize)
|
|
return AppConfig.A7_BAD_DATASIZE;
|
|
return AppConfig.A7_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* Validate an unauthenticated packet footer.
|
|
* The footer is a 20 byte SHA1 sum of the packet.
|
|
*/
|
|
protected short checkFooter(byte[] data, short dataOffset, short dataLength) {
|
|
short ramD_paramsize = (short) (dataOffset + dataLength - AppConfig.A7_CHECKSUM_SIZE);
|
|
byte[] ramD_buffer = this.m_ee_data.getFooterBuffer_ramD();
|
|
this.m_ee_sha1.reset();
|
|
this.m_ee_sha1.doFinal(data, dataOffset, (short) (dataLength - AppConfig.A7_CHECKSUM_SIZE), ramD_buffer,
|
|
(short) 0);
|
|
if (Util.arrayCompare(data, ramD_paramsize, ramD_buffer, (short) 0, (short) AppConfig.A7_CHECKSUM_SIZE) != 0)
|
|
return AppConfig.A7_SUMFAIL;
|
|
return AppConfig.A7_SUCCESS;
|
|
}
|
|
|
|
protected short makeSendPacket(short tag, short paramSize, short result,
|
|
byte[] data, short dataOffset, short dataSize, byte[] sendPacket, short packetOffset,
|
|
short packetLength) {
|
|
if (!this.m_ee_packet.setData(null, (short) 0, (short) 0, tag, paramSize, result, this.m_ee_cmd, data,
|
|
dataOffset,
|
|
dataSize, null, (short) 0, (short) 0, null, (short) 0, (short) 0, sendPacket, packetOffset,
|
|
packetLength,
|
|
this.m_ee_sha1, null)) {
|
|
return makeErrorPacket(AppConfig.A7_FAIL, sendPacket, packetOffset, packetLength);
|
|
}
|
|
return paramSize;
|
|
}
|
|
|
|
protected short makeErrorPacket(short error, byte[] sendPacket, short packetOffset, short packetLength) {
|
|
this.m_ee_data.setLastError_ramD(error);
|
|
this.m_ee_packet.setData(null, (short) 0, (short) 0, AppConfig.A7_TAG_RSP_COMMAND, ERROR_PACKET_SIZE,
|
|
error, this.m_ee_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 ERROR_PACKET_SIZE;
|
|
}
|
|
}
|