Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

public class KMOperationImpl implements KMOperation {

private Cipher cipher;
private Signature signature;
private static final short CIPHER_ALG_OFFSET = 0x00;
private static final short PADDING_OFFSET = 0x01;
private static final short OPER_MODE_OFFSET = 0x02;
Expand All @@ -32,12 +34,9 @@ public class KMOperationImpl implements KMOperation {
//Java Card after the GCM update operation.
private static final short AES_GCM_UPDATE_LEN_OFFSET = 0x05;
private short[] parameters;
// Either one of Cipher/Signature instance is stored.
private Object[] operationInst;

public KMOperationImpl() {
parameters = JCSystem.makeTransientShortArray((short) 6, JCSystem.CLEAR_ON_RESET);
operationInst = JCSystem.makeTransientObjectArray((short) 1, JCSystem.CLEAR_ON_RESET);
}

public short getMode() {
Expand Down Expand Up @@ -81,15 +80,19 @@ public void setCipherAlgorithm(short cipherAlg) {
}

public void setCipher(Cipher cipher) {
operationInst[0] = cipher;
JCSystem.beginTransaction();
this.cipher = cipher;
JCSystem.commitTransaction();
}

public void setSignature(Signature signer) {
operationInst[0] = signer;
JCSystem.beginTransaction();
this.signature = signer;
JCSystem.commitTransaction();
}

private void resetCipher() {
operationInst[0] = null;
setCipher(null);
parameters[MAC_LENGTH_OFFSET] = 0;
parameters[AES_GCM_UPDATE_LEN_OFFSET] = 0;
parameters[BLOCK_MODE_OFFSET] = 0;
Expand All @@ -101,7 +104,7 @@ private void resetCipher() {
@Override
public short update(byte[] inputDataBuf, short inputDataStart,
short inputDataLength, byte[] outputDataBuf, short outputDataStart) {
short len = ((Cipher) operationInst[0]).update(inputDataBuf, inputDataStart, inputDataLength,
short len = cipher.update(inputDataBuf, inputDataStart, inputDataLength,
outputDataBuf, outputDataStart);
if (parameters[CIPHER_ALG_OFFSET] == KMType.AES && parameters[BLOCK_MODE_OFFSET] == KMType.GCM) {
// Every time Block size data is stored as intermediate result.
Expand All @@ -113,15 +116,14 @@ public short update(byte[] inputDataBuf, short inputDataStart,
@Override
public short update(byte[] inputDataBuf, short inputDataStart,
short inputDataLength) {
((Signature) operationInst[0]).update(inputDataBuf, inputDataStart, inputDataLength);
signature.update(inputDataBuf, inputDataStart, inputDataLength);
return 0;
}

@Override
public short finish(byte[] inputDataBuf, short inputDataStart,
short inputDataLen, byte[] outputDataBuf, short outputDataStart) {
byte[] tmpArray = KMAndroidSEProvider.getInstance().tmpArray;
Cipher cipher = (Cipher) operationInst[0];
short cipherAlg = parameters[CIPHER_ALG_OFFSET];
short blockMode = parameters[BLOCK_MODE_OFFSET];
short mode = parameters[OPER_MODE_OFFSET];
Expand Down Expand Up @@ -207,11 +209,11 @@ public short sign(byte[] inputDataBuf, short inputDataStart,
short inputDataLength, byte[] signBuf, short signStart) {
short len = 0;
try {
len = ((Signature) operationInst[0]).sign(inputDataBuf, inputDataStart, inputDataLength,
len = signature.sign(inputDataBuf, inputDataStart, inputDataLength,
signBuf, signStart);
} finally {
KMAndroidSEProvider.getInstance().releaseSignatureInstance((Signature) operationInst[0]);
operationInst[0] = null;
KMAndroidSEProvider.getInstance().releaseSignatureInstance(signature);
setSignature(null);
}
return len;
}
Expand All @@ -221,33 +223,31 @@ public boolean verify(byte[] inputDataBuf, short inputDataStart,
short inputDataLength, byte[] signBuf, short signStart, short signLength) {
boolean ret = false;
try {
ret = ((Signature) operationInst[0]).verify(inputDataBuf, inputDataStart, inputDataLength,
ret = signature.verify(inputDataBuf, inputDataStart, inputDataLength,
signBuf, signStart, signLength);
} finally {
KMAndroidSEProvider.getInstance().releaseSignatureInstance((Signature) operationInst[0]);
operationInst[0] = null;
KMAndroidSEProvider.getInstance().releaseSignatureInstance(signature);
setSignature(null);
}
return ret;
}

@Override
public void abort() {
if (operationInst[0] != null) {
if (parameters[OPER_MODE_OFFSET] == KMType.ENCRYPT ||
parameters[OPER_MODE_OFFSET] == KMType.DECRYPT) {
KMAndroidSEProvider.getInstance().releaseCipherInstance((Cipher) operationInst[0]);
resetCipher();
} else {
KMAndroidSEProvider.getInstance().releaseSignatureInstance((Signature) operationInst[0]);
}
operationInst[0] = null;
if (cipher != null) {
KMAndroidSEProvider.getInstance().releaseCipherInstance(cipher);
resetCipher();
}
if (signature != null) {
KMAndroidSEProvider.getInstance().releaseSignatureInstance(signature);
setSignature(null);
}
KMAndroidSEProvider.getInstance().releaseOperationInstance(this);
}

@Override
public void updateAAD(byte[] dataBuf, short dataStart, short dataLength) {
((AEADCipher) operationInst[0]).updateAAD(dataBuf, dataStart, dataLength);
((AEADCipher) cipher).updateAAD(dataBuf, dataStart, dataLength);
}

@Override
Expand Down