Skip to content
Merged
Show file tree
Hide file tree
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 numberDiff line numberDiff line change
Expand Up@@ -40,6 +40,8 @@
import com.android.javacard.keymaster.KMAESKey;
import com.android.javacard.keymaster.KMAttestationKey;
import com.android.javacard.keymaster.KMECPrivateKey;
import com.android.javacard.keymaster.KMError;
import com.android.javacard.keymaster.KMException;
import com.android.javacard.keymaster.KMHmacKey;
import com.android.javacard.keymaster.KMMasterKey;
import com.android.javacard.keymaster.KMPreSharedKey;
Expand DownExpand Up@@ -1018,51 +1020,6 @@ public Signature createRsaSigner(short digest, short padding, byte[] secret,
return rsaSigner;
}

public Signature createRsaVerifier(short digest, short padding,
byte[] modBuffer, short modOff, short modLength) {
try {
byte alg = mapSignature256Alg(KMType.RSA, (byte) padding, (byte) digest);
if (digest == KMType.DIGEST_NONE || padding == KMType.PADDING_NONE)
CryptoException.throwIt(CryptoException.NO_SUCH_ALGORITHM);

Signature rsaVerifier = getSignatureInstanceFromPool(alg);
RSAPublicKey key = (RSAPublicKey) rsaKeyPair.getPublic();
// setExponent
Util.setShort(tmpArray, (short) 0, (short) 0x0001);
Util.setShort(tmpArray, (short) 2, (short) 0x0001);
key.setExponent(tmpArray, (short) 0, (short) 4);
key.setModulus(modBuffer, modOff, modLength);
rsaVerifier.init(key, Signature.MODE_VERIFY);
return rsaVerifier;
} finally {
clean();
}
}

public Cipher createRsaCipher(short padding, short digest, byte[] modBuffer,
short modOff, short modLength) {
try {
byte cipherAlg = mapCipherAlg(KMType.RSA, (byte) padding, (byte) 0, (byte)digest);
// Java Card does not support MGF1-SHA1 and digest as SHA256.
// Both digest should be SHA256 as per Java Card, but as per Keymaster
// MGF should use SHA1 and message digest should be SHA256.
if (cipherAlg == Cipher.ALG_RSA_PKCS1_OAEP) {
KMException.throwIt(KMError.UNIMPLEMENTED);
}
Cipher rsaCipher = getCipherInstanceFromPool(cipherAlg);
RSAPublicKey key = (RSAPublicKey) rsaKeyPair.getPublic();
// setExponent
Util.setShort(tmpArray, (short) 0, (short) 0x0001);
Util.setShort(tmpArray, (short) 2, (short) 0x0001);
key.setExponent(tmpArray, (short) 0, (short) 4);
key.setModulus(modBuffer, modOff, modLength);
rsaCipher.init(key, Cipher.MODE_ENCRYPT);
return rsaCipher;
} finally {
clean();
}
}

public Cipher createRsaDecipher(short padding, short digest, byte[] secret,
short secretStart, short secretLength, byte[] modBuffer, short modOff,
short modLength) {
Expand All@@ -1086,17 +1043,6 @@ public Signature createEcSigner(short digest, byte[] secret,
return ecSigner;
}

public Signature createEcVerifier(short digest, byte[] pubKey,
short pubKeyStart, short pubKeyLength) {
byte alg = mapSignature256Alg(KMType.EC, (byte) 0, (byte) digest);
Signature ecVerifier = null;
ECPublicKey key = (ECPublicKey) ecKeyPair.getPublic();
key.setW(pubKey, pubKeyStart, pubKeyLength);
ecVerifier = getSignatureInstanceFromPool(alg);
ecVerifier.init(key, Signature.MODE_VERIFY);
return ecVerifier;
}

@Override
public KMOperation initAsymmetricOperation(byte purpose, byte alg,
byte padding, byte digest, byte[] privKeyBuf, short privKeyStart,
Expand All@@ -1116,28 +1062,6 @@ public KMOperation initAsymmetricOperation(byte purpose, byte alg,
opr.setMode(purpose);
JCSystem.commitTransaction();
break;
case KMType.VERIFY:
Signature verifier = createRsaVerifier(digest, padding, pubModBuf,
pubModStart, pubModLength);
opr = getOperationInstanceFromPool();
JCSystem.beginTransaction();
opr.setSignature(verifier);
opr.setCipherAlgorithm(alg);
opr.setPaddingAlgorithm(padding);
opr.setMode(purpose);
JCSystem.commitTransaction();
break;
case KMType.ENCRYPT:
Cipher cipher = createRsaCipher(padding, digest, pubModBuf,
pubModStart, pubModLength);
opr = getOperationInstanceFromPool();
JCSystem.beginTransaction();
opr.setCipher(cipher);
opr.setCipherAlgorithm(alg);
opr.setPaddingAlgorithm(padding);
opr.setMode(purpose);
JCSystem.commitTransaction();
break;
case KMType.DECRYPT:
Cipher decipher = createRsaDecipher(padding, digest, privKeyBuf,
privKeyStart, privKeyLength, pubModBuf, pubModStart, pubModLength);
Expand All@@ -1150,6 +1074,7 @@ public KMOperation initAsymmetricOperation(byte purpose, byte alg,
JCSystem.commitTransaction();
break;
default:
KMException.throwIt(KMError.UNSUPPORTED_PURPOSE);
break;
}
} else if (alg == KMType.EC) {
Expand All@@ -1162,13 +1087,8 @@ public KMOperation initAsymmetricOperation(byte purpose, byte alg,
opr.setSignature(signer);
JCSystem.commitTransaction();
break;
case KMType.VERIFY:
Signature verifier = createEcVerifier(digest, pubModBuf, pubModStart,
pubModLength);
opr = getOperationInstanceFromPool();
JCSystem.beginTransaction();
opr.setSignature(verifier);
JCSystem.commitTransaction();
default:
KMException.throwIt(KMError.UNSUPPORTED_PURPOSE);
break;
}
} else {
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -112,28 +112,14 @@ public short signPreComputedHash(byte[] bytes, short i, short i1,
@Override
public boolean verify(byte[] bytes, short i, short i1, byte[] bytes1,
short i2, short i3) throws CryptoException {
try {
if (i1 > MAX_NO_DIGEST_MSG_LEN)
CryptoException.throwIt(CryptoException.ILLEGAL_USE);
// add zeros to the left
if (i1 < MAX_NO_DIGEST_MSG_LEN) {
Util.arrayFillNonAtomic(KMAndroidSEProvider.getInstance().tmpArray,
(short) 0, (short) MAX_NO_DIGEST_MSG_LEN, (byte) 0);
}
Util.arrayCopyNonAtomic(bytes, i,
KMAndroidSEProvider.getInstance().tmpArray,
(short) (MAX_NO_DIGEST_MSG_LEN - i1), i1);
return inst.verifyPreComputedHash(
KMAndroidSEProvider.getInstance().tmpArray, (short) 0,
(short) MAX_NO_DIGEST_MSG_LEN, bytes1, i2, i3);
} finally {
KMAndroidSEProvider.getInstance().clean();
}
//Verification is handled inside HAL
return false;
}

@Override
public boolean verifyPreComputedHash(byte[] bytes, short i, short i1,
byte[] bytes1, short i2, short i3) throws CryptoException {
return inst.verify(bytes, i, i1, bytes1, i2, i3);
//Verification is handled inside HAL
return false;
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -125,19 +125,6 @@ public short finish(byte[] inputDataBuf, short inputDataStart,
if (mode == KMType.DECRYPT) {
inputDataLen = (short) (inputDataLen - macLength);
}
} else if (cipherAlg == KMType.RSA && padding == KMType.PADDING_NONE &&
mode == KMType.ENCRYPT) {
// Length cannot be greater then key size according to Java Card
if (inputDataLen > 256)
KMException.throwIt(KMError.INVALID_INPUT_LENGTH);
// make input equal to 255 bytes
Util.arrayFillNonAtomic(tmpArray, (short) 0, (short) 256, (byte) 0);
Util.arrayCopyNonAtomic(inputDataBuf, inputDataStart, tmpArray,
(short) (256 - inputDataLen), inputDataLen);
inputDataStart = 0;
inputDataLen = 256;
inputDataBuf = tmpArray;

} else if ((cipherAlg == KMType.DES || cipherAlg == KMType.AES) &&
padding == KMType.PKCS7 && mode == KMType.ENCRYPT) {
byte blkSize = 16;
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -81,21 +81,7 @@ public short doFinal(byte[] buffer, short startOff, short length, byte[] scratch
CryptoException.throwIt(CryptoException.ILLEGAL_VALUE);
}
} else{
if(cipherAlg == KMType.RSA && padding == KMType.PADDING_NONE && mode == KMType.ENCRYPT ){
// Length cannot be greater then key size according to JcardSim
if(length >= 256) KMException.throwIt(KMError.INVALID_INPUT_LENGTH);
// make input equal to 255 bytes
byte[] tmp = new byte[255];
Util.arrayFillNonAtomic(tmp,(short)0,(short)255, (byte)0);
Util.arrayCopyNonAtomic(
buffer,
startOff,
tmp, (short)(255 - length),length);
startOff = 0;
length = 255;
buffer = tmp;

}else if((cipherAlg == KMType.DES || cipherAlg == KMType.AES) && padding ==KMType.PKCS7 && mode == KMType.ENCRYPT){
if((cipherAlg == KMType.DES || cipherAlg == KMType.AES) && padding ==KMType.PKCS7 && mode == KMType.ENCRYPT){
byte blkSize = 16;
byte paddingBytes;
short len = length;
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -173,14 +173,7 @@ public short signPreComputedHash(byte[] bytes, short i, short i1, byte[] bytes1,

@Override
public boolean verify(byte[] bytes, short i, short i1, byte[] bytes1, short i2, short i3) throws CryptoException {
// Cannot support this method as javacard cipher api does not allow 256 byte for public key
// encryption without padding. It only allows 255 bytes data.
try {
update(bytes, i , i1);
return sunSigner.verify(bytes1, i2, i3);
} catch (SignatureException e) {
CryptoException.throwIt(CryptoException.ILLEGAL_VALUE);
}
// Public key operations not handled here.
return false;
}

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -605,27 +605,22 @@ public KMOperation initAsymmetricOperation(byte purpose, byte alg, byte padding,
pubModStart,
pubModLength);
return new KMOperationImpl(signer);
case KMType.VERIFY:
Signature verifier = createRsaVerifier(digest, padding, pubModBuf, pubModStart, pubModLength);
return new KMOperationImpl(verifier);
case KMType.ENCRYPT:
KMCipher cipher = createRsaCipher(padding, digest, pubModBuf, pubModStart, pubModLength);
return new KMOperationImpl(cipher);
case KMType.DECRYPT:
KMCipher decipher =
createRsaDecipher(
padding, digest, privKeyBuf, privKeyStart, privKeyLength, pubModBuf, pubModStart, pubModLength);
return new KMOperationImpl(decipher);
default:
KMException.throwIt(KMError.UNSUPPORTED_PURPOSE);
}
}else if(alg == KMType.EC){
switch(purpose){
case KMType.SIGN:
Signature signer =
createEcSigner(digest,privKeyBuf,privKeyStart,privKeyLength);
return new KMOperationImpl(signer);
case KMType.VERIFY:
Signature verifier = createEcVerifier(digest,pubModBuf,pubModStart,pubModLength);
return new KMOperationImpl(verifier);
default:
KMException.throwIt(KMError.UNSUPPORTED_PURPOSE);
}
}
CryptoException.throwIt(CryptoException.NO_SUCH_ALGORITHM);
Expand DownExpand Up@@ -1110,52 +1105,6 @@ public void addRngEntropy(byte[] num, short offset, short length) {
}
}


public KMCipher createRsaCipher(short padding, short digest, byte[] modBuffer, short modOff, short modLength) {
byte cipherAlg = mapCipherAlg(KMType.RSA, (byte)padding, (byte)0);
if (cipherAlg == Cipher.ALG_RSA_PKCS1_OAEP) {
return createRsaOAEP256Cipher(KMType.ENCRYPT, (byte)digest, null,(short)0,(short)0,modBuffer,modOff,modLength);
}
Cipher rsaCipher = Cipher.getInstance(cipherAlg,false);
RSAPublicKey key = (RSAPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC, KeyBuilder.LENGTH_RSA_2048, false);
byte[] exponent = new byte[]{0x01,0x00,0x01};
key.setExponent(exponent,(short)0,(short)3);
key.setModulus(modBuffer, modOff, modLength);
rsaCipher.init(key,Cipher.MODE_ENCRYPT);
KMCipherImpl inst = new KMCipherImpl(rsaCipher);
inst.setCipherAlgorithm(KMType.RSA);
inst.setMode(KMType.ENCRYPT);
inst.setPaddingAlgorithm(padding);
return inst;
}

public Signature createRsaVerifier(short digest, short padding, byte[] modBuffer, short modOff, short modLength) {
short alg = mapSignature256Alg(KMType.RSA,(byte)padding);
if(digest == KMType.DIGEST_NONE || padding == KMType.PADDING_NONE) CryptoException.throwIt(CryptoException.NO_SUCH_ALGORITHM);
Signature rsaVerifier = Signature.getInstance((byte)alg, false);
RSAPublicKey key = (RSAPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC, KeyBuilder.LENGTH_RSA_2048, false);
byte[] exponent = new byte[]{0x01,0x00,0x01};
key.setExponent(exponent,(short)0,(short)3);
key.setModulus(modBuffer, modOff, modLength);
rsaVerifier.init(key,Signature.MODE_VERIFY);
return rsaVerifier;
}

public Signature createEcVerifier(short digest, byte[] pubKey, short pubKeyStart, short pubKeyLength) {
short alg = mapSignature256Alg(KMType.EC, (byte)0);
Signature ecVerifier;
//if(msgDigestAlg == MessageDigest.ALG_NULL) CryptoException.throwIt(CryptoException.NO_SUCH_ALGORITHM);
if(digest == KMType.DIGEST_NONE) {
ecVerifier = new KMEcdsa256NoDigestSignature(Signature.MODE_VERIFY, pubKey, pubKeyStart, pubKeyLength);
} else {
ECPublicKey key = (ECPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC, KeyBuilder.LENGTH_EC_FP_256, false);
key.setW(pubKey,pubKeyStart,pubKeyLength);
ecVerifier = Signature.getInstance((byte)alg,false);
ecVerifier.init(key,Signature.MODE_VERIFY);
}
return ecVerifier;
}

@Override
public KMAttestationCert getAttestationCert(boolean rsaCert) {
return KMAttestationCertImpl.instance(rsaCert);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,8 +89,7 @@ public short signPreComputedHash(byte[] bytes, short i, short i1, byte[] bytes1,

@Override
public boolean verify(byte[] bytes, short i, short i1, byte[] bytes1, short i2, short i3) throws CryptoException {
// Cannot support this method as javacard cipher api does not allow 256 byte for public key
// encryption without padding. It only allows 255 bytes data.
// Public key operations not handled here.
return false;
}

Expand Down
Loading