a7firm/src/sega/a7/Command.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;
}
}